From 8237c2a0b3cb0edbf8e1caeecafa5c4dd39f80da Mon Sep 17 00:00:00 2001 From: Matthias Prinke <83612361+matthias-bs@users.noreply.github.com> Date: Fri, 11 Oct 2024 22:54:31 +0200 Subject: [PATCH 1/8] Implemented secure MQTT --- src/common.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/common.h b/src/common.h index a43334c..d281a8d 100644 --- a/src/common.h +++ b/src/common.h @@ -21,7 +21,7 @@ bool DecodeWeather(WiFiClient& json, String Type) { log_d("Creating JSON object"); // allocate the JsonDocument JsonDocument doc; - + // Deserialize the JSON document DeserializationError error = deserializeJson(doc, json); // Test if parsing succeeds. @@ -108,10 +108,9 @@ String ConvertUnixTime(int unix_time) { return output; } //######################################################################################### -//extern WiFiClient client; // wifi client object +bool obtain_wx_data(const String& RequestType) { + WiFiClient client; -//bool obtain_wx_data(WiFiClient& client, const String& RequestType) { -bool obtain_wx_data(WiFiClient& client, const String& RequestType) { const String units = (Units == "M" ? "metric" : "imperial"); client.stop(); // close connection before sending a new request HTTPClient http; From e44f71f715cf6ba900e93ec14b0c9b9580b46208 Mon Sep 17 00:00:00 2001 From: Matthias Prinke Date: Fri, 11 Oct 2024 22:23:44 +0200 Subject: [PATCH 2/8] Fixed sensor status flags, added secure MQTT --- .../MqttInterface.cpp | 56 +++++++++++++------ .../Waveshare_7_5_T7_Sensors/MqttInterface.h | 37 ++++++------ 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/examples/Waveshare_7_5_T7_Sensors/MqttInterface.cpp b/examples/Waveshare_7_5_T7_Sensors/MqttInterface.cpp index 8dbe36a..2c5e708 100644 --- a/examples/Waveshare_7_5_T7_Sensors/MqttInterface.cpp +++ b/examples/Waveshare_7_5_T7_Sensors/MqttInterface.cpp @@ -33,6 +33,7 @@ // History: // // 20241010 Extracted from Waveshare_7_5_T7_Sensors.ino +// 20241011 Fixed sensor status flags, added secure MQTT // // ToDo: // - @@ -49,28 +50,45 @@ extern RTC_DATA_ATTR time_t LocalHistTStamp; static bool mqttMessageReceived = false; //!< Flag: MQTT message has been received +static const char digicert[] PROGMEM = DIGICERT; #ifdef SIMULATE_MQTT - static const char *MqttBuf = "{\"end_device_ids\":{\"device_id\":\"eui-9876b6000011c87b\",\"application_ids\":{\"application_id\":\"flora-lora\"},\"dev_eui\":\"9876B6000011C87B\",\"join_eui\":\"0000000000000000\",\"dev_addr\":\"260BFFCA\"},\"correlation_ids\":[\"as:up:01GH0PHSCTGKZ51EB8XCBBGHQD\",\"gs:conn:01GFQX269DVXYK9W6XF8NNZWDD\",\"gs:up:host:01GFQX26AXQM4QHEAPW48E8EWH\",\"gs:uplink:01GH0PHS6A65GBAPZB92XNGYAP\",\"ns:uplink:01GH0PHS6BEPXS9Y7DMDRNK84Y\",\"rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01GH0PHS6BY76SY2VPRSHNDDRH\",\"rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01GH0PHSCS7D3V8ERSKF0DTJ8H\"],\"received_at\":\"2022-11-04T06:51:44.409936969Z\",\"uplink_message\":{\"session_key_id\":\"AYRBaM/qASfqUi+BQK75Gg==\",\"f_port\":1,\"frm_payload\":\"PwOOWAgACAAIBwAAYEKAC28LAw0D4U0DwAoAAAAAwMxMP8DMTD/AzEw/AAAAAAAAAAAA\",\"decoded_payload\":{\"bytes\":{\"air_temp_c\":\"9.1\",\"battery_v\":2927,\"humidity\":88,\"indoor_humidity\":77,\"indoor_temp_c\":\"9.9\",\"rain_day\":\"0.8\",\"rain_hr\":\"0.0\",\"rain_mm\":\"56.0\",\"rain_mon\":\"0.8\",\"rain_week\":\"0.8\",\"soil_moisture\":10,\"soil_temp_c\":\"9.6\",\"status\":{\"ble_ok\":true,\"res\":false,\"rtc_sync_req\":false,\"runtime_expired\":true,\"s1_batt_ok\":true,\"s1_dec_ok\":true,\"ws_batt_ok\":true,\"ws_dec_ok\":true},\"supply_v\":2944,\"water_temp_c\":\"7.8\",\"wind_avg_meter_sec\":\"0.8\",\"wind_direction_deg\":\"180.0\",\"wind_gust_meter_sec\":\"0.8\"}},\"rx_metadata\":[{\"gateway_ids\":{\"gateway_id\":\"lora-db0fc\",\"eui\":\"3135323538002400\"},\"time\":\"2022-11-04T06:51:44.027496Z\",\"timestamp\":1403655780,\"rssi\":-104,\"channel_rssi\":-104,\"snr\":8.25,\"location\":{\"latitude\":52.27640735,\"longitude\":10.54058183,\"altitude\":65,\"source\":\"SOURCE_REGISTRY\"},\"uplink_token\":\"ChgKFgoKbG9yYS1kYjBmYxIIMTUyNTgAJAAQ5KyonQUaCwiA7ZKbBhCw6tpgIKDtnYPt67cC\",\"channel_index\":4,\"received_at\":\"2022-11-04T06:51:44.182146570Z\"}],\"settings\":{\"data_rate\":{\"lora\":{\"bandwidth\":125000,\"spreading_factor\":8,\"coding_rate\":\"4/5\"}},\"frequency\":\"867300000\",\"timestamp\":1403655780,\"time\":\"2022-11-04T06:51:44.027496Z\"},\"received_at\":\"2022-11-04T06:51:44.203702153Z\",\"confirmed\":true,\"consumed_airtime\":\"0.215552s\",\"locations\":{\"user\":{\"latitude\":52.24619,\"longitude\":10.50106,\"source\":\"SOURCE_REGISTRY\"}},\"network_ids\":{\"net_id\":\"000013\",\"tenant_id\":\"ttn\",\"cluster_id\":\"eu1\",\"cluster_address\":\"eu1.cloud.thethings.network\"}}}"; +static const char *MqttBuf = "{\"end_device_ids\":{\"device_id\":\"eui-9876b6000011c87b\",\"application_ids\":{\"application_id\":\"flora-lora\"},\"dev_eui\":\"9876B6000011C87B\",\"join_eui\":\"0000000000000000\",\"dev_addr\":\"260BFFCA\"},\"correlation_ids\":[\"as:up:01GH0PHSCTGKZ51EB8XCBBGHQD\",\"gs:conn:01GFQX269DVXYK9W6XF8NNZWDD\",\"gs:up:host:01GFQX26AXQM4QHEAPW48E8EWH\",\"gs:uplink:01GH0PHS6A65GBAPZB92XNGYAP\",\"ns:uplink:01GH0PHS6BEPXS9Y7DMDRNK84Y\",\"rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01GH0PHS6BY76SY2VPRSHNDDRH\",\"rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01GH0PHSCS7D3V8ERSKF0DTJ8H\"],\"received_at\":\"2022-11-04T06:51:44.409936969Z\",\"uplink_message\":{\"session_key_id\":\"AYRBaM/qASfqUi+BQK75Gg==\",\"f_port\":1,\"frm_payload\":\"PwOOWAgACAAIBwAAYEKAC28LAw0D4U0DwAoAAAAAwMxMP8DMTD/AzEw/AAAAAAAAAAAA\",\"decoded_payload\":{\"bytes\":{\"air_temp_c\":\"9.1\",\"battery_v\":2927,\"humidity\":88,\"indoor_humidity\":77,\"indoor_temp_c\":\"9.9\",\"rain_day\":\"0.8\",\"rain_hr\":\"0.0\",\"rain_mm\":\"56.0\",\"rain_mon\":\"0.8\",\"rain_week\":\"0.8\",\"soil_moisture\":10,\"soil_temp_c\":\"9.6\",\"status\":{\"ble_ok\":true,\"res\":false,\"rtc_sync_req\":false,\"runtime_expired\":true,\"s1_batt_ok\":true,\"s1_dec_ok\":true,\"ws_batt_ok\":true,\"ws_dec_ok\":true},\"supply_v\":2944,\"water_temp_c\":\"7.8\",\"wind_avg_meter_sec\":\"0.8\",\"wind_direction_deg\":\"180.0\",\"wind_gust_meter_sec\":\"0.8\"}},\"rx_metadata\":[{\"gateway_ids\":{\"gateway_id\":\"lora-db0fc\",\"eui\":\"3135323538002400\"},\"time\":\"2022-11-04T06:51:44.027496Z\",\"timestamp\":1403655780,\"rssi\":-104,\"channel_rssi\":-104,\"snr\":8.25,\"location\":{\"latitude\":52.27640735,\"longitude\":10.54058183,\"altitude\":65,\"source\":\"SOURCE_REGISTRY\"},\"uplink_token\":\"ChgKFgoKbG9yYS1kYjBmYxIIMTUyNTgAJAAQ5KyonQUaCwiA7ZKbBhCw6tpgIKDtnYPt67cC\",\"channel_index\":4,\"received_at\":\"2022-11-04T06:51:44.182146570Z\"}],\"settings\":{\"data_rate\":{\"lora\":{\"bandwidth\":125000,\"spreading_factor\":8,\"coding_rate\":\"4/5\"}},\"frequency\":\"867300000\",\"timestamp\":1403655780,\"time\":\"2022-11-04T06:51:44.027496Z\"},\"received_at\":\"2022-11-04T06:51:44.203702153Z\",\"confirmed\":true,\"consumed_airtime\":\"0.215552s\",\"locations\":{\"user\":{\"latitude\":52.24619,\"longitude\":10.50106,\"source\":\"SOURCE_REGISTRY\"}},\"network_ids\":{\"net_id\":\"000013\",\"tenant_id\":\"ttn\",\"cluster_id\":\"eu1\",\"cluster_address\":\"eu1.cloud.thethings.network\"}}}"; #else - static char MqttBuf[MQTT_PAYLOAD_SIZE + 1]; //!< MQTT Payload Buffer +static char MqttBuf[MQTT_PAYLOAD_SIZE + 1]; //!< MQTT Payload Buffer #endif -/** - * \brief MQTT message reception callback function - * - * Sets the flag mqttMessageReceived and copies the received message to - * MqttBuf. - */ +// MQTT message reception callback function static void mqttMessageCb(String &topic, String &payload) { - mqttMessageReceived = true; - log_d("Payload size: %d", payload.length()); + mqttMessageReceived = true; + log_d("Payload size: %d", payload.length()); #ifndef SIMULATE_MQTT - strncpy(MqttBuf, payload.c_str(), payload.length()); + strncpy(MqttBuf, payload.c_str(), payload.length()); #endif } +// Constructor +MqttInterface::MqttInterface(MQTTClient &_MqttClient) +{ +#if defined(USE_SECUREWIFI) +#ifdef CHECK_CA_ROOT + net.setCACert(digicert); +#endif +#ifdef CHECK_PUB_KEY + error "CHECK_PUB_KEY: not implemented" +#endif +#ifdef CHECK_FINGERPRINT + net.setFingerprint(fp); +#endif +#if (!defined(CHECK_PUB_KEY) and !defined(CHECK_CA_ROOT) and !defined(CHECK_FINGERPRINT)) + // do not verify tls certificate + net.setInsecure(); +#endif +#endif + MqttClient = _MqttClient; +} + // Connect to MQTT broker bool MqttInterface::mqttConnect() { @@ -212,19 +230,19 @@ void MqttInterface::getMqttData(mqtt_sensors_t &MqttSensors) MqttSensors.soil_moisture = payload[SOIL1_MOISTURE].isNull() ? INV_UINT8 : payload[SOIL1_MOISTURE]; MqttSensors.soil_temp_c = payload[SOIL1_TEMP_C].isNull() ? INV_TEMP : payload[SOIL1_TEMP_C]; MqttSensors.water_temp_c = payload[OW0_TEMP_C].isNull() ? INV_TEMP : payload[OW0_TEMP_C]; - MqttSensors.wind_avg_meter_sec = payload[WS_WIND_AVG_MS].isNull() ? INV_FLOAT : payload[WS_WIND_AVG_MS]; + MqttSensors.wind_avg_meter_sec = payload[WS_WIND_AVG_MS].isNull() ? INV_UINT16 : payload[WS_WIND_AVG_MS]; MqttSensors.wind_direction_deg = payload[WS_WIND_DIR_DEG].isNull() ? INV_UINT16 : payload[WS_WIND_DIR_DEG]; - MqttSensors.wind_gust_meter_sec = payload[WS_WIND_GUST_MS].isNull() ? INV_FLOAT : payload[WS_WIND_GUST_MS]; + MqttSensors.wind_gust_meter_sec = payload[WS_WIND_GUST_MS].isNull() ? INV_UINT16 : payload[WS_WIND_GUST_MS]; - // FIXME: This is a workaround for the time being JsonObject status = payload["status"]; bool ble_ok = MqttSensors.indoor_temp_c != INV_TEMP && MqttSensors.indoor_humidity != INV_UINT8; // MqttSensors.status.ble_ok = status["ble_ok"] | ble_ok; MqttSensors.status.ble_ok = ble_ok; + MqttSensors.status.ble_batt_ok = 1; // No MQTT signal available bool s1_dec_ok = MqttSensors.soil_temp_c != INV_TEMP && MqttSensors.soil_moisture != INV_UINT8; // MqttSensors.status.s1_dec_ok = status["s1_dec_ok"] | s1_dec_ok; MqttSensors.status.s1_dec_ok = s1_dec_ok; - bool ws_dec_ok = MqttSensors.air_temp_c != INV_TEMP && MqttSensors.rain_mm != INV_FLOAT; + bool ws_dec_ok = MqttSensors.air_temp_c != INV_TEMP && MqttSensors.humidity != INV_UINT8 && MqttSensors.rain_mm != INV_FLOAT; // MqttSensors.status.ws_dec_ok = status["ws_dec_ok"] | ws_dec_ok; MqttSensors.status.ws_dec_ok = ws_dec_ok; @@ -249,11 +267,15 @@ void MqttInterface::getMqttData(mqtt_sensors_t &MqttSensors) MqttSensors.rain_day = 0; } + log_d("ws_dec_ok: %d", MqttSensors.status.ws_dec_ok); + log_d("s1_dec_ok: %d", MqttSensors.status.s1_dec_ok); + log_d("ble_ok: %d", MqttSensors.status.ble_ok); + log_d("ws_batt_ok: %d", MqttSensors.status.ws_batt_ok); + log_d("s1_batt_ok: %d", MqttSensors.status.s1_batt_ok); log_i("MQTT data updated: %d", MqttSensors.valid ? 1 : 0); } - -bool MqttInterface::mqttUplink(WiFiClient &net, MQTTClient &MqttClient, local_sensors_t &data) +bool MqttInterface::mqttUplink(MQTTClient &MqttClient, local_sensors_t &data) { char payload[21]; char topic[41]; diff --git a/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h b/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h index 82849ce..7b7cf10 100644 --- a/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h +++ b/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h @@ -33,6 +33,7 @@ // History: // // 20241010 Extracted from Waveshare_7_5_T7_Sensors.ino +// 20241011 Fixed sensor status flags, added secure MQTT // // ToDo: // - @@ -43,10 +44,16 @@ #define _MQTT_INTERFACE #include #include +#include "config.h" + #include +#if defined(USE_SECUREWIFI) +#include +#endif + #include // https://github.com/256dpi/arduino-mqtt #include // https://github.com/bblanchon/ArduinoJson needs version v6 or above -#include "config.h" + #include "secrets.h" #include "LocalInterface.h" @@ -57,11 +64,12 @@ struct MqttS char received_at[32]; //!< MQTT message received date/time struct { - unsigned int ws_batt_ok : 1; //!< weather sensor battery o.k. - unsigned int ws_dec_ok : 1; //!< weather sensor decoding o.k. - unsigned int s1_batt_ok : 1; //!< soil moisture sensor battery o.k. - unsigned int s1_dec_ok : 1; //!< soil moisture sensor dencoding o.k. - unsigned int ble_ok : 1; //!< BLE T-/H-sensor data o.k. + unsigned int ws_batt_ok : 1; //!< weather sensor battery o.k. + unsigned int ws_dec_ok : 1; //!< weather sensor decoding o.k. + unsigned int s1_batt_ok : 1; //!< soil moisture sensor battery o.k. + unsigned int s1_dec_ok : 1; //!< soil moisture sensor dencoding o.k. + unsigned int ble_batt_ok : 1; //!< BLE sensor battery o.k. + unsigned int ble_ok : 1; //!< BLE T-/H-sensor data o.k. } status; float air_temp_c; //!< temperature in degC @@ -89,9 +97,9 @@ struct MqttS typedef struct MqttS mqtt_sensors_t; //!< Shortcut for struct Sensor struct MqttHistQData { - float temperature; //!< temperature in degC - uint8_t humidity; //!< humidity in % - bool valid; //!< data valid + float temperature; //!< temperature in degC + uint8_t humidity; //!< humidity in % + bool valid; //!< data valid }; typedef struct MqttHistQData mqtt_hist_t; //!< Shortcut for struct MqttHistQData @@ -147,18 +155,14 @@ typedef struct MqttHistQData mqtt_hist_t; //!< Shortcut for struct MqttHistQData class MqttInterface { private: - WiFiClient net; + NetworkClientSecure net; MQTTClient MqttClient; public: /*! * \brief Constructor */ - MqttInterface(WiFiClient &_net, MQTTClient &_MqttClient) - { - net = _net; - MqttClient = _MqttClient; - }; + MqttInterface(MQTTClient &_MqttClient); /** * \brief Connect to MQTT broker @@ -170,11 +174,10 @@ class MqttInterface /** * \brief Get MQTT data from broker * - * \param net network connection * \param MqttClient MQTT client object */ void getMqttData(mqtt_sensors_t &MqttSensors); - bool mqttUplink(WiFiClient &net, MQTTClient &MqttClient, local_sensors_t &data); + bool mqttUplink(MQTTClient &MqttClient, local_sensors_t &data); }; #endif \ No newline at end of file From 32d4201bddf7e9f280271568deae11a3c116b9bd Mon Sep 17 00:00:00 2001 From: Matthias Prinke Date: Fri, 11 Oct 2024 22:40:42 +0200 Subject: [PATCH 3/8] Minor Changes --- examples/Waveshare_7_5_T7_Sensors/utils.cpp | 6 +++--- examples/Waveshare_7_5_T7_Sensors/utils.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/Waveshare_7_5_T7_Sensors/utils.cpp b/examples/Waveshare_7_5_T7_Sensors/utils.cpp index a86b364..a667728 100644 --- a/examples/Waveshare_7_5_T7_Sensors/utils.cpp +++ b/examples/Waveshare_7_5_T7_Sensors/utils.cpp @@ -152,8 +152,8 @@ boolean UpdateLocalTime() CurrentDay = timeinfo.tm_mday; printTime(timeinfo, time_output, date_output, 32, TXT_UPDATED); - Date_str = date_output; - Time_str = time_output; + Date_str = String(date_output); + Time_str = String(time_output); return true; } @@ -182,5 +182,5 @@ void printTime(struct tm &timeinfo, char *date_output, char *time_output, int ma strftime(update_time, sizeof(update_time), "%r", &timeinfo); // Creates: '02:05:49pm' } - sprintf(time_output, "%s %s", label, update_time); + sprintf(time_output, "%s %s", label.c_str(), update_time); } \ No newline at end of file diff --git a/examples/Waveshare_7_5_T7_Sensors/utils.h b/examples/Waveshare_7_5_T7_Sensors/utils.h index 46b42d5..ace7cb9 100644 --- a/examples/Waveshare_7_5_T7_Sensors/utils.h +++ b/examples/Waveshare_7_5_T7_Sensors/utils.h @@ -43,9 +43,9 @@ #define _UTILS_H #include #include +#include "config.h" #include #include -#include "config.h" #include "secrets.h" /** From 8c6fa47db8195a97372e383422070b0e4b5141da Mon Sep 17 00:00:00 2001 From: Matthias Prinke Date: Fri, 11 Oct 2024 22:46:57 +0200 Subject: [PATCH 4/8] Added secure MQTT --- .../Waveshare_7_5_T7_Sensors.ino | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/examples/Waveshare_7_5_T7_Sensors/Waveshare_7_5_T7_Sensors.ino b/examples/Waveshare_7_5_T7_Sensors/Waveshare_7_5_T7_Sensors.ino index d746a47..21fd565 100644 --- a/examples/Waveshare_7_5_T7_Sensors/Waveshare_7_5_T7_Sensors.ino +++ b/examples/Waveshare_7_5_T7_Sensors/Waveshare_7_5_T7_Sensors.ino @@ -56,16 +56,16 @@ * * 20241008 Fixed B/W display (small artefacts remaining) * 20241009 Fixed B/W display of main screens + * 20241011 Added secure MQTT * */ +#include "config.h" #include "owm_credentials.h" // See 'owm_credentials' tab and enter your OWM API key and set the Wifi SSID and PASSWORD #include // https://github.com/bblanchon/ArduinoJson needs version v6 or above -#include // Built-in -// #include -#include // Built-in -#include // Built-in -//#include // Built-in + +#include // Built-in +#include // Built-in #include // Built-in #include // https://github.com/256dpi/arduino-mqtt #include // https://github.com/SMFSW/cQueue @@ -167,7 +167,6 @@ RTC_DATA_ATTR bool touchPrevTrig = false; //!< Flag: Left touch sensor has bee RTC_DATA_ATTR bool touchNextTrig = false; //!< Flag: Right touch sensor has been triggered RTC_DATA_ATTR bool touchMidTrig = false; //!< Flag: Middle touch sensor has been triggered - // ################ PROGRAM VARIABLES and OBJECTS ################ #define autoscale_on true @@ -181,11 +180,11 @@ const String Locations[] = LOCATIONS_TXT; //!< /Screen Titles #define max_readings 24 RTC_DATA_ATTR Forecast_record_type WxConditions[1]; //!< OWM Weather Conditions Forecast_record_type WxForecast[max_readings]; //!< OWM Weather Forecast -float pressure_readings[max_readings] = {0}; //!< OWM pressure readings -float temperature_readings[max_readings] = {0}; //!< OWM temperature readings -float humidity_readings[max_readings] = {0}; //!< OWM humidity readings -float rain_readings[max_readings] = {0}; //!< OWM rain readings -float snow_readings[max_readings] = {0}; //!< OWM snow readings +float pressure_readings[max_readings] = {0}; //!< OWM pressure readings +float temperature_readings[max_readings] = {0}; //!< OWM temperature readings +float humidity_readings[max_readings] = {0}; //!< OWM humidity readings +float rain_readings[max_readings] = {0}; //!< OWM rain readings +float snow_readings[max_readings] = {0}; //!< OWM snow readings #include "common.h" @@ -238,8 +237,6 @@ void ARDUINO_ISR_ATTR touch_mid_isr() */ void setup() { - WiFiClient net; //!< network object - StartTime = millis(); Serial.begin(115200); Serial.setDebugOutput(true); @@ -362,11 +359,13 @@ void setup() bool RxWeather = false, RxForecast = false; while ((RxWeather == false || RxForecast == false) && Attempts <= 2) - { // Try up-to 2 time for Weather and Forecast data - if (RxWeather == false) - RxWeather = obtain_wx_data(net, "weather"); - if (RxForecast == false) - RxForecast = obtain_wx_data(net, "forecast"); + { // Try up-to 2 times for Weather and Forecast data + if (RxWeather == false) { + RxWeather = obtain_wx_data("weather"); + } + if (RxForecast == false) { + RxForecast = obtain_wx_data("forecast"); + } Attempts++; } if (RxWeather && RxForecast) @@ -472,7 +471,9 @@ void setup() // Fetch MQTT data MQTTClient MqttClient(MQTT_PAYLOAD_SIZE); - MqttInterface mqttInterface(net, MqttClient); + //NetworkClientSecure net; + //MqttInterface mqttInterface(net, MqttClient); + MqttInterface mqttInterface(MqttClient); if (mqttInterface.mqttConnect()) { // Show download icon @@ -510,12 +511,23 @@ void setup() if (display.epd2.hasFastPartialUpdate) { - display.setPartialWindow(x, y, 48, 48); - display.firstPage(); - do - { - display.fillRect(x, y, 48, 48, GxEPD_WHITE); - } while (display.nextPage()); + log_d("hasFastPartialUpdate"); + if (ScreenNo == ScreenMQTT) { + log_d("DisplayMQTTWeather(NULL)"); + display.setFullWindow(); + DisplayMQTTWeather(NULL); + } else { + display.setPartialWindow(x, y, 48, 48); + #if defined(DISPLAY_3C) + display.firstPage(); + do + { + #endif + display.fillRect(x, y, 48, 48, GxEPD_WHITE); + #if defined(DISPLAY_3C) + } while (display.nextPage()); + #endif + } } else { @@ -551,7 +563,7 @@ void setup() } SaveRainDayData(); - mqttInterface.mqttUplink(net, MqttClient, LocalSensors); + mqttInterface.mqttUplink(MqttClient, LocalSensors); StopWiFi(); BeginSleep(); } @@ -622,7 +634,6 @@ inline bool TouchTriggered(void) return (touchPrevTrig || touchMidTrig || touchNextTrig); } - /** * \brief Display Open Weather Map (OWM) data * @@ -851,9 +862,9 @@ void DisplayMQTTWeather(const unsigned char *status_bitmap) drawString(524, 130, String(MqttSensors.indoor_humidity) + "%", CENTER); #ifdef FORCE_LOW_BATTERY - MqttSensors.status.ws_batt_ok = false; + MqttSensors.status.ble_batt_ok = false; #endif - if (!MqttSensors.status.ws_batt_ok) + if (!MqttSensors.status.ble_batt_ok) { display.drawBitmap(577, 115, epd_bitmap_battery_alert, 24, 24, GxEPD_BLACK); } From 09132511ca2b99b49acde6263c28cfab30ef059d Mon Sep 17 00:00:00 2001 From: Matthias Prinke <83612361+matthias-bs@users.noreply.github.com> Date: Fri, 11 Oct 2024 23:14:00 +0200 Subject: [PATCH 5/8] Refactoring, added secure WiFi --- examples/Waveshare_7_5_T7_Sensors/config.h | 39 +++++----------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/examples/Waveshare_7_5_T7_Sensors/config.h b/examples/Waveshare_7_5_T7_Sensors/config.h index 9050ed4..619457b 100644 --- a/examples/Waveshare_7_5_T7_Sensors/config.h +++ b/examples/Waveshare_7_5_T7_Sensors/config.h @@ -34,6 +34,7 @@ // History: // // 20241010 Extracted from owm_credentials.h +// 20241011 Added secure WiFi // // ToDo: // - @@ -71,6 +72,14 @@ #define I2C_SDA 21 //!< I2C Serial Data Pin #define I2C_SCL 22 //!< I2C Serial Clock Pin +//#define USE_SECUREWIFI + +// enable only one of these below, disabling both is fine too. +//#define CHECK_CA_ROOT +//#define CHECK_PUB_KEY +// Arduino 1.8.19 ESP32 WiFiClientSecure.h: "SHA1 fingerprint is broken now!" +//#define CHECK_FINGERPRINT + // Domain Name Server - separate bytes by comma! #define MY_DNS 192,168,0,1 @@ -130,34 +139,4 @@ #define HIST_UPDATE_RATE 30 #define HIST_UPDATE_TOL 5 -// TODO: Move to LocalSensors class -// Local Sensor Data -struct LocalS -{ - struct - { - bool valid; //!< data valid - float temperature; //!< temperature in degC - float humidity; //!< humidity in % - uint8_t batt_level; //!< battery level in % - int rssi; //!< RSSI in dBm - } ble_thsensor[1]; - struct - { - bool valid; //!< data valid - float temperature; //!< temperature in degC - float humidity; //!< humidity in % - float pressure; //!< pressure in hPa - } i2c_thpsensor[1]; - struct - { - bool valid; //!< data valid - float temperature; //!< temperature in degC - float humidity; //!< humidity in % - uint16_t co2; //!< CO2 in ppm - } i2c_co2sensor; -}; - -typedef struct LocalS local_sensors_t; //!< Shortcut for struct LocalS - #endif From d06e2d3aed1d81de66f96c00a4c4727cda40f48c Mon Sep 17 00:00:00 2001 From: Matthias Prinke Date: Fri, 11 Oct 2024 23:31:55 +0200 Subject: [PATCH 6/8] Fixed non-secure MQTT --- examples/Waveshare_7_5_T7_Sensors/MqttInterface.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h b/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h index 7b7cf10..04ba9a0 100644 --- a/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h +++ b/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h @@ -155,7 +155,11 @@ typedef struct MqttHistQData mqtt_hist_t; //!< Shortcut for struct MqttHistQData class MqttInterface { private: +#if defined(USE_SECUREWIFI) NetworkClientSecure net; + #else + WiFiClient net; +#endif MQTTClient MqttClient; public: From ea99cd24437f4a30ea30ad6bfa05d9beadf3b5e8 Mon Sep 17 00:00:00 2001 From: Matthias Prinke <83612361+matthias-bs@users.noreply.github.com> Date: Fri, 11 Oct 2024 23:45:21 +0200 Subject: [PATCH 7/8] Update secrets.h --- examples/Waveshare_7_5_T7_Sensors/secrets.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/Waveshare_7_5_T7_Sensors/secrets.h b/examples/Waveshare_7_5_T7_Sensors/secrets.h index 971a0b4..b20e50d 100644 --- a/examples/Waveshare_7_5_T7_Sensors/secrets.h +++ b/examples/Waveshare_7_5_T7_Sensors/secrets.h @@ -13,4 +13,12 @@ // MQTT broker for publishing #define MQTT_USER_P "your_user_pub" -#define MQTT_PASS_P "your passwd_pub" \ No newline at end of file +#define MQTT_PASS_P "your passwd_pub" + +#define DIGICERT "\ +-----BEGIN CERTIFICATE-----\n\ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ +BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\ +\n\ +-----END CERTIFICATE-----\ +" From 12499bb32db08c0da48a9f15b7987d16809832f3 Mon Sep 17 00:00:00 2001 From: Matthias Prinke Date: Fri, 11 Oct 2024 23:51:37 +0200 Subject: [PATCH 8/8] Fixed non-secure MQTT --- examples/Waveshare_7_5_T7_Sensors/MqttInterface.cpp | 2 ++ examples/Waveshare_7_5_T7_Sensors/MqttInterface.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/Waveshare_7_5_T7_Sensors/MqttInterface.cpp b/examples/Waveshare_7_5_T7_Sensors/MqttInterface.cpp index 2c5e708..43db7f2 100644 --- a/examples/Waveshare_7_5_T7_Sensors/MqttInterface.cpp +++ b/examples/Waveshare_7_5_T7_Sensors/MqttInterface.cpp @@ -50,7 +50,9 @@ extern RTC_DATA_ATTR time_t LocalHistTStamp; static bool mqttMessageReceived = false; //!< Flag: MQTT message has been received +#if defined(USE_SECUREWIFI) && defined(CHECK_CA_ROOT) static const char digicert[] PROGMEM = DIGICERT; +#endif #ifdef SIMULATE_MQTT static const char *MqttBuf = "{\"end_device_ids\":{\"device_id\":\"eui-9876b6000011c87b\",\"application_ids\":{\"application_id\":\"flora-lora\"},\"dev_eui\":\"9876B6000011C87B\",\"join_eui\":\"0000000000000000\",\"dev_addr\":\"260BFFCA\"},\"correlation_ids\":[\"as:up:01GH0PHSCTGKZ51EB8XCBBGHQD\",\"gs:conn:01GFQX269DVXYK9W6XF8NNZWDD\",\"gs:up:host:01GFQX26AXQM4QHEAPW48E8EWH\",\"gs:uplink:01GH0PHS6A65GBAPZB92XNGYAP\",\"ns:uplink:01GH0PHS6BEPXS9Y7DMDRNK84Y\",\"rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01GH0PHS6BY76SY2VPRSHNDDRH\",\"rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01GH0PHSCS7D3V8ERSKF0DTJ8H\"],\"received_at\":\"2022-11-04T06:51:44.409936969Z\",\"uplink_message\":{\"session_key_id\":\"AYRBaM/qASfqUi+BQK75Gg==\",\"f_port\":1,\"frm_payload\":\"PwOOWAgACAAIBwAAYEKAC28LAw0D4U0DwAoAAAAAwMxMP8DMTD/AzEw/AAAAAAAAAAAA\",\"decoded_payload\":{\"bytes\":{\"air_temp_c\":\"9.1\",\"battery_v\":2927,\"humidity\":88,\"indoor_humidity\":77,\"indoor_temp_c\":\"9.9\",\"rain_day\":\"0.8\",\"rain_hr\":\"0.0\",\"rain_mm\":\"56.0\",\"rain_mon\":\"0.8\",\"rain_week\":\"0.8\",\"soil_moisture\":10,\"soil_temp_c\":\"9.6\",\"status\":{\"ble_ok\":true,\"res\":false,\"rtc_sync_req\":false,\"runtime_expired\":true,\"s1_batt_ok\":true,\"s1_dec_ok\":true,\"ws_batt_ok\":true,\"ws_dec_ok\":true},\"supply_v\":2944,\"water_temp_c\":\"7.8\",\"wind_avg_meter_sec\":\"0.8\",\"wind_direction_deg\":\"180.0\",\"wind_gust_meter_sec\":\"0.8\"}},\"rx_metadata\":[{\"gateway_ids\":{\"gateway_id\":\"lora-db0fc\",\"eui\":\"3135323538002400\"},\"time\":\"2022-11-04T06:51:44.027496Z\",\"timestamp\":1403655780,\"rssi\":-104,\"channel_rssi\":-104,\"snr\":8.25,\"location\":{\"latitude\":52.27640735,\"longitude\":10.54058183,\"altitude\":65,\"source\":\"SOURCE_REGISTRY\"},\"uplink_token\":\"ChgKFgoKbG9yYS1kYjBmYxIIMTUyNTgAJAAQ5KyonQUaCwiA7ZKbBhCw6tpgIKDtnYPt67cC\",\"channel_index\":4,\"received_at\":\"2022-11-04T06:51:44.182146570Z\"}],\"settings\":{\"data_rate\":{\"lora\":{\"bandwidth\":125000,\"spreading_factor\":8,\"coding_rate\":\"4/5\"}},\"frequency\":\"867300000\",\"timestamp\":1403655780,\"time\":\"2022-11-04T06:51:44.027496Z\"},\"received_at\":\"2022-11-04T06:51:44.203702153Z\",\"confirmed\":true,\"consumed_airtime\":\"0.215552s\",\"locations\":{\"user\":{\"latitude\":52.24619,\"longitude\":10.50106,\"source\":\"SOURCE_REGISTRY\"}},\"network_ids\":{\"net_id\":\"000013\",\"tenant_id\":\"ttn\",\"cluster_id\":\"eu1\",\"cluster_address\":\"eu1.cloud.thethings.network\"}}}"; diff --git a/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h b/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h index 04ba9a0..0c15438 100644 --- a/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h +++ b/examples/Waveshare_7_5_T7_Sensors/MqttInterface.h @@ -157,7 +157,7 @@ class MqttInterface private: #if defined(USE_SECUREWIFI) NetworkClientSecure net; - #else +#else WiFiClient net; #endif MQTTClient MqttClient;