From b02c731e95b8560758daa2551f88be8ddc79c390 Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Sat, 1 Jun 2024 13:10:50 +0200 Subject: [PATCH 1/8] use blue led to indicate status of MQTT connectivity --- include/devices.h | 5 ++--- src/esp_clock.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/devices.h b/include/devices.h index 60b0bb1..376fb21 100644 --- a/include/devices.h +++ b/include/devices.h @@ -28,10 +28,9 @@ namespace Devices { .addSecondary(Builder::instance(SENSOR_ID).withValueTemplate("{{ value_json.pressure }}").build()) .build(); - Switch* ledMqtt = Builder::instance(new Switch{ "Led", "led", + auto ledMqtt = Builder::instance(new Switch{ "Led", "led", [](const char* msg) { - strcmp("ON", msg) == 0 ? digitalWrite(LED_BUILTIN, LOW) : digitalWrite(LED_BUILTIN, HIGH); - ledMqtt->updateState(!digitalRead(LED_BUILTIN)); + turnLed(strcmp("ON", msg) == 0); } }).withStateTopic().restoreFromState().build(); diff --git a/src/esp_clock.cpp b/src/esp_clock.cpp index b6e0678..6c286e1 100644 --- a/src/esp_clock.cpp +++ b/src/esp_clock.cpp @@ -14,6 +14,10 @@ Scheduler ts; Task tCheckWifi(5 * TASK_MINUTE, TASK_ONCE, checkWifiCallback, &ts); Task tWifiConnected(TASK_IMMEDIATE, TASK_ONCE, onWifiConnected, &ts); +void turnLed(bool on = true) { + on ? digitalWrite(LED_BUILTIN, LOW) : digitalWrite(LED_BUILTIN, HIGH); +} + #include "bme.h" #include "ntp_time.h" #include "wifi.h" @@ -56,7 +60,10 @@ void setup() { Ota::setup(); Ntp::setup(); Bme::setup(); - Mqtt::setup(&ts); + Mqtt::setup(&ts, + [] {turnLed(false);}, + [] {turnLed();} + ); Devices::setup(); Wifi::setup(); From 8f706fe32fe4188860d5fc3268bee7e4775e5434 Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Sat, 1 Jun 2024 15:10:33 +0200 Subject: [PATCH 2/8] update time daily at 4 AM --- include/display.h | 3 +++ include/ntp_time.h | 6 ++---- src/esp_clock.cpp | 4 +--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/display.h b/include/display.h index 9653f80..a3c01c1 100644 --- a/include/display.h +++ b/include/display.h @@ -82,6 +82,9 @@ namespace Display { static int currentHour = -1; if (currentHour != hour()) { currentHour = hour(); + if (currentHour == 4) { + Ntp::updateTime(); + } if (currentHour == 8) { Brightness::set(BRIGHTNESS_DAY); Wifi::reconnect(); diff --git a/include/ntp_time.h b/include/ntp_time.h index e047434..b9fcbe0 100644 --- a/include/ntp_time.h +++ b/include/ntp_time.h @@ -14,13 +14,11 @@ namespace Ntp { TimeChangeRule CET = { "CET ", Last, Sun, Oct, 3, 60 }; // Central European Standard Time Timezone CE(CEST, CET); - time_t updateTime() { + void updateTime() { if (timeClient.forceUpdate()) { time_t newTime = CE.toLocal(timeClient.getEpochTime()); setTime(newTime); - return newTime; - } else { - return 0; + Serial.println(asctime(localtime(&newTime))); } } diff --git a/src/esp_clock.cpp b/src/esp_clock.cpp index 6c286e1..d422d77 100644 --- a/src/esp_clock.cpp +++ b/src/esp_clock.cpp @@ -84,9 +84,7 @@ void onWifiConnected() { Wifi::printStatus(); Ota::tLoop.enable(); Mqtt::tReConnect.enable(); - if (time_t newTime = Ntp::updateTime()) { - Serial.println(asctime(localtime(&newTime))); - } + Ntp::updateTime(); } void checkWifiCallback() { From 8a955fa43a0976776c96b9ca51848acfb7674a45 Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Sat, 1 Jun 2024 21:58:57 +0200 Subject: [PATCH 3/8] update time daily at 4 AM using task --- include/display.h | 2 +- include/ntp_time.h | 6 +++--- src/esp_clock.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/display.h b/include/display.h index a3c01c1..049d34a 100644 --- a/include/display.h +++ b/include/display.h @@ -83,7 +83,7 @@ namespace Display { if (currentHour != hour()) { currentHour = hour(); if (currentHour == 4) { - Ntp::updateTime(); + Ntp::tUpdateTime.restart(); } if (currentHour == 8) { Brightness::set(BRIGHTNESS_DAY); diff --git a/include/ntp_time.h b/include/ntp_time.h index b9fcbe0..fca16af 100644 --- a/include/ntp_time.h +++ b/include/ntp_time.h @@ -14,16 +14,16 @@ namespace Ntp { TimeChangeRule CET = { "CET ", Last, Sun, Oct, 3, 60 }; // Central European Standard Time Timezone CE(CEST, CET); - void updateTime() { + Task tUpdateTime(TASK_IMMEDIATE, TASK_ONCE, []{ if (timeClient.forceUpdate()) { time_t newTime = CE.toLocal(timeClient.getEpochTime()); setTime(newTime); Serial.println(asctime(localtime(&newTime))); } - } + }, &ts); void setup() { - timeClient.begin(); Serial.println("NTP setup"); + timeClient.begin(); } } \ No newline at end of file diff --git a/src/esp_clock.cpp b/src/esp_clock.cpp index d422d77..7b0ad8c 100644 --- a/src/esp_clock.cpp +++ b/src/esp_clock.cpp @@ -84,7 +84,7 @@ void onWifiConnected() { Wifi::printStatus(); Ota::tLoop.enable(); Mqtt::tReConnect.enable(); - Ntp::updateTime(); + Ntp::tUpdateTime.enable(); } void checkWifiCallback() { From 16647d1f885ca7e4643ab765a6020d082e2a3300 Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Sat, 1 Jun 2024 22:03:54 +0200 Subject: [PATCH 4/8] display sensor values only once on startup --- include/devices.h | 1 + include/display.h | 2 +- src/esp_clock.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/devices.h b/include/devices.h index 376fb21..8d37578 100644 --- a/include/devices.h +++ b/include/devices.h @@ -58,6 +58,7 @@ namespace Devices { [](const char* msg) { if (strcmp("PRESS", msg) == 0 && !Display::tDisplaySensor.isEnabled()) { Bme::data.readAll(); + Display::tDisplaySensor.setIterations(DISPLAY_SENSOR_ITERATIONS); Display::tDisplaySensor.restart(); }; } diff --git a/include/display.h b/include/display.h index 049d34a..036d4c1 100644 --- a/include/display.h +++ b/include/display.h @@ -33,7 +33,7 @@ namespace Display { tDisplayTime.disable(); return true; }, []() { - tDisplaySensor.setIterations(DISPLAY_SENSOR_ITERATIONS); + tDisplaySensor.setIterations(DISPLAY_SENSOR_ITERATIONS*2); tDisplayTime.enableDelayed(tDisplaySensor.getInterval()); }); diff --git a/src/esp_clock.cpp b/src/esp_clock.cpp index 7b0ad8c..1927bb9 100644 --- a/src/esp_clock.cpp +++ b/src/esp_clock.cpp @@ -30,6 +30,7 @@ void turnLed(bool on = true) { Task tButton(TASK_IMMEDIATE, TASK_ONCE, []() { if (Display::tDisplaySensor.isEnabled()) return; Bme::data.readAll(); + Display::tDisplaySensor.setIterations(DISPLAY_SENSOR_ITERATIONS); Display::tDisplaySensor.restart(); }, &ts); Task tLed(TASK_IMMEDIATE, TASK_ONCE, []() { @@ -44,7 +45,6 @@ Task tReadBme(TASK_MINUTE, TASK_FOREVER, []() { Devices::publishBme280(); if (abs(lastTemp - Bme::data.temp) > 0.2) { lastTemp = Bme::data.temp; - Display::tDisplaySensor.setIterations(DISPLAY_SENSOR_ITERATIONS*2); Display::tDisplaySensor.restart(); } }, &ts); From 858d13c9a7d9e1abebd231e616d54cafbd709e98 Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Sat, 1 Jun 2024 22:14:34 +0200 Subject: [PATCH 5/8] simplify wifi and make it more generic --- include/devices.h | 1 - include/display.h | 6 +++--- include/wifi.h | 38 +++++++++++++++++++++----------------- src/esp_clock.cpp | 18 +++++++----------- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/include/devices.h b/include/devices.h index 8d37578..8a28872 100644 --- a/include/devices.h +++ b/include/devices.h @@ -1,6 +1,5 @@ #pragma once -#define MAIN_DEVICE_ID "esp_clock" #define SENSOR_ID "bme280" #include "ha.h" diff --git a/include/display.h b/include/display.h index 036d4c1..ae2edf4 100644 --- a/include/display.h +++ b/include/display.h @@ -50,7 +50,7 @@ namespace Display { void set(uint8_t value) { current = value % (BRIGHTNESS_MAX + 1); clockDisplay.setBrightness(current); - brightnessChangedCallback(); + if (brightnessChangedCallback) brightnessChangedCallback(); } void change(bool increase) { @@ -87,7 +87,7 @@ namespace Display { } if (currentHour == 8) { Brightness::set(BRIGHTNESS_DAY); - Wifi::reconnect(); + Wifi::tReconnect.enable(); } if (currentHour == 17) { Brightness::set(BRIGHTNESS_NIGHT); @@ -142,7 +142,7 @@ namespace Display { void changeHourFormat24(bool format24) { hourFormat24 = format24; drawTime(); - hourFormatChangedCallback(); + if (hourFormatChangedCallback) hourFormatChangedCallback(); } void setup() { diff --git a/include/wifi.h b/include/wifi.h index c00d88d..f3f6361 100644 --- a/include/wifi.h +++ b/include/wifi.h @@ -7,23 +7,33 @@ namespace Wifi { WiFiEventHandler stationConnectedHandler; WiFiEventHandler stationDisconnectedHandler; - void reconnect(); - - Task tWifiReconnect(1 * TASK_MINUTE, TASK_FOREVER, reconnect, &ts); String currentSSID; String currentPsk; - void setup() { - stationConnectedHandler = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP& e) { - Serial.println("Reconnected to network."); - tWifiConnected.restart(); - tWifiReconnect.cancel(); + void printStatus(); + + Task tReconnect(1 * TASK_MINUTE, TASK_FOREVER, []{ + if (WiFi.status() != WL_CONNECTED) { + Serial.println("Reconnecting to WiFi netowrk..."); + WiFi.forceSleepWake(); + WiFi.begin(currentSSID.c_str(), currentPsk.c_str()); + } + }); + + void setup(Scheduler& ts, void(*onConnected)() = nullptr) { + ts.addTask(tReconnect); + + stationConnectedHandler = WiFi.onStationModeGotIP([onConnected](const WiFiEventStationModeGotIP& e) { + Serial.println("Connected to network."); + printStatus(); + tReconnect.cancel(); + if (onConnected) onConnected(); }); stationDisconnectedHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected& e) { Serial.println("Disconnected from network."); - tWifiReconnect.restartDelayed(); + tReconnect.restartDelayed(); }); @@ -36,17 +46,11 @@ namespace Wifi { while (wifiMulti.run() != WL_CONNECTED) { delay(500); } - WiFi.setHostname("esp-clock"); + WiFi.setHostname(MAIN_DEVICE_ID); currentSSID = WiFi.SSID(); currentPsk = WiFi.psk(); - } - void reconnect() { - if (WiFi.status() != WL_CONNECTED) { - WiFi.forceSleepWake(); - WiFi.begin(currentSSID.c_str(), currentPsk.c_str()); - Serial.println("Reconnecting to WiFi netowrk..."); - } + tReconnect.enable(); } void disconnect() { diff --git a/src/esp_clock.cpp b/src/esp_clock.cpp index 1927bb9..f83af4e 100644 --- a/src/esp_clock.cpp +++ b/src/esp_clock.cpp @@ -1,18 +1,17 @@ #include void checkWifiCallback(); -void onWifiConnected(); void onButtonPressed(); void onLed(); void onButtonCallback(); #define MQTT_HOST IPAddress(192, 168, 5, 11) #define MQTT_PORT 1883 +#define MAIN_DEVICE_ID "esp-clock" #include Scheduler ts; Task tCheckWifi(5 * TASK_MINUTE, TASK_ONCE, checkWifiCallback, &ts); -Task tWifiConnected(TASK_IMMEDIATE, TASK_ONCE, onWifiConnected, &ts); void turnLed(bool on = true) { on ? digitalWrite(LED_BUILTIN, LOW) : digitalWrite(LED_BUILTIN, HIGH); @@ -52,6 +51,7 @@ Task tReadBme(TASK_MINUTE, TASK_FOREVER, []() { void setup() { Serial.begin(9600); + Serial.println(); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); @@ -66,7 +66,11 @@ void setup() { ); Devices::setup(); - Wifi::setup(); + Wifi::setup(ts, []{ + Ota::tLoop.enable(); + Mqtt::tReConnect.enable(); + Ntp::tUpdateTime.enable(); + }); pinMode(BUTTON, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(BUTTON), onButtonPressed, FALLING); @@ -79,14 +83,6 @@ void loop() { ts.execute(); } -void onWifiConnected() { - Serial.println("Wifi connected event"); - Wifi::printStatus(); - Ota::tLoop.enable(); - Mqtt::tReConnect.enable(); - Ntp::tUpdateTime.enable(); -} - void checkWifiCallback() { #if !WIFI_ALWAYS_ON Serial.println("Wifi connection timed out"); From 15f5ab3ef7d32f5d29842a44fbdab18c2c342b19 Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Sat, 1 Jun 2024 22:27:45 +0200 Subject: [PATCH 6/8] use task for WifiMulti: everything should be exectued inside loop --- include/wifi.h | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/include/wifi.h b/include/wifi.h index f3f6361..e47dc8e 100644 --- a/include/wifi.h +++ b/include/wifi.h @@ -5,6 +5,7 @@ namespace Wifi { + ESP8266WiFiMulti wifiMulti; WiFiEventHandler stationConnectedHandler; WiFiEventHandler stationDisconnectedHandler; @@ -21,9 +22,16 @@ namespace Wifi { } }); - void setup(Scheduler& ts, void(*onConnected)() = nullptr) { - ts.addTask(tReconnect); + Task tInitialConnect(500 * TASK_MILLISECOND, 120, []{ + Serial.println("Finding WiFi netowrk..."); + if (wifiMulti.run() == WL_CONNECTED) tInitialConnect.disable(); + }, nullptr, false, nullptr, []{ + currentSSID = WiFi.SSID(); + currentPsk = WiFi.psk(); + tReconnect.enable(); + }); + void setup(Scheduler& ts, void(*onConnected)() = nullptr) { stationConnectedHandler = WiFi.onStationModeGotIP([onConnected](const WiFiEventStationModeGotIP& e) { Serial.println("Connected to network."); printStatus(); @@ -37,20 +45,14 @@ namespace Wifi { }); - ESP8266WiFiMulti wifiMulti; + WiFi.setHostname(MAIN_DEVICE_ID); for (uint32_t i = 0; i < sizeof(credentials) / sizeof(WifiCredentials); i++) { wifiMulti.addAP(credentials[i].ssid, credentials[i].password); } - Serial.println("Connecting to WiFi netowrk."); - while (wifiMulti.run() != WL_CONNECTED) { - delay(500); - } - WiFi.setHostname(MAIN_DEVICE_ID); - currentSSID = WiFi.SSID(); - currentPsk = WiFi.psk(); - - tReconnect.enable(); + ts.addTask(tInitialConnect); + ts.addTask(tReconnect); + tInitialConnect.enable(); } void disconnect() { From 5014fd7f98324dd4db5b003679aa341f25c1a453 Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Tue, 4 Jun 2024 10:26:05 +0200 Subject: [PATCH 7/8] move wifi&ota inside a library --- include/credentials.h.tpl | 4 -- include/ota.h | 35 ----------------- include/wifi.h | 80 --------------------------------------- platformio.ini | 3 +- 4 files changed, 2 insertions(+), 120 deletions(-) delete mode 100644 include/credentials.h.tpl delete mode 100644 include/ota.h delete mode 100644 include/wifi.h diff --git a/include/credentials.h.tpl b/include/credentials.h.tpl deleted file mode 100644 index c5637e4..0000000 --- a/include/credentials.h.tpl +++ /dev/null @@ -1,4 +0,0 @@ -struct WifiCredentials { - const char* ssid; - const char* password; -} credentials[] = {"foo", "bar"}; diff --git a/include/ota.h b/include/ota.h deleted file mode 100644 index 43b4c05..0000000 --- a/include/ota.h +++ /dev/null @@ -1,35 +0,0 @@ -#include - -namespace Ota { - - void loop(); - Task tLoop(TASK_IMMEDIATE, TASK_FOREVER, loop, &ts, true); - - void setup() { - ArduinoOTA.onStart([]() { - Serial.println("Starting OTA"); - Mqtt::publishCleanupConfig(); - delay(2000); - Mqtt::disconnect(); - }); - ArduinoOTA.onEnd([]() { - Serial.println("\nOTA Finished"); - }); - ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { - Serial.printf("Progress: %u%%\r", (progress / (total / 100))); - }); - ArduinoOTA.onError([](ota_error_t error) { - Serial.printf("Error[%u]: ", error); - if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); - else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); - else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); - else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); - else if (error == OTA_END_ERROR) Serial.println("End Failed"); - }); - ArduinoOTA.begin(); - } - - void loop() { - ArduinoOTA.handle(); - } -} diff --git a/include/wifi.h b/include/wifi.h deleted file mode 100644 index e47dc8e..0000000 --- a/include/wifi.h +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include "credentials.h" - -namespace Wifi { - - ESP8266WiFiMulti wifiMulti; - WiFiEventHandler stationConnectedHandler; - WiFiEventHandler stationDisconnectedHandler; - - String currentSSID; - String currentPsk; - - void printStatus(); - - Task tReconnect(1 * TASK_MINUTE, TASK_FOREVER, []{ - if (WiFi.status() != WL_CONNECTED) { - Serial.println("Reconnecting to WiFi netowrk..."); - WiFi.forceSleepWake(); - WiFi.begin(currentSSID.c_str(), currentPsk.c_str()); - } - }); - - Task tInitialConnect(500 * TASK_MILLISECOND, 120, []{ - Serial.println("Finding WiFi netowrk..."); - if (wifiMulti.run() == WL_CONNECTED) tInitialConnect.disable(); - }, nullptr, false, nullptr, []{ - currentSSID = WiFi.SSID(); - currentPsk = WiFi.psk(); - tReconnect.enable(); - }); - - void setup(Scheduler& ts, void(*onConnected)() = nullptr) { - stationConnectedHandler = WiFi.onStationModeGotIP([onConnected](const WiFiEventStationModeGotIP& e) { - Serial.println("Connected to network."); - printStatus(); - tReconnect.cancel(); - if (onConnected) onConnected(); - }); - - stationDisconnectedHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected& e) { - Serial.println("Disconnected from network."); - tReconnect.restartDelayed(); - }); - - - WiFi.setHostname(MAIN_DEVICE_ID); - for (uint32_t i = 0; i < sizeof(credentials) / sizeof(WifiCredentials); i++) { - wifiMulti.addAP(credentials[i].ssid, credentials[i].password); - } - - ts.addTask(tInitialConnect); - ts.addTask(tReconnect); - tInitialConnect.enable(); - } - - void disconnect() { - Serial.println("Disconnecting WiFi"); - WiFi.disconnect(); - WiFi.forceSleepBegin(); - } - - void printStatus() { - // print the SSID of the network you're attached to: - Serial.print("SSID: "); - Serial.println(WiFi.SSID()); - - // print your WiFi shield's IP address: - IPAddress ip = WiFi.localIP(); - Serial.print("IP Address: "); - Serial.println(ip); - - // print the received signal strength: - long rssi = WiFi.RSSI(); - Serial.print("signal strength (RSSI):"); - Serial.print(rssi); - Serial.println(" dBm"); - } -} diff --git a/platformio.ini b/platformio.ini index 25ec799..93fdda3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,7 +20,8 @@ lib_deps = jchristensen/Timezone@^1.2.4 adafruit/Adafruit Unified Sensor @ ^1.1.4 adafruit/Adafruit BME280 Library@^2.2.4 - https://git.hodos.ro/arduino/ha-mqtt.git@^1.0.0 + https://git.hodos.ro/libraries/wifi.git@^1.0.0 + https://git.hodos.ro/libraries/ha-mqtt.git@^1.0.0 build_flags = -D WIFI_ALWAYS_ON=1 [env:laptop_home] From 8b451fbbcf23b74533256c8752e3ba27e96cc58f Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Tue, 4 Jun 2024 21:35:36 +0200 Subject: [PATCH 8/8] update wifi library --- platformio.ini | 2 +- src/esp_clock.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 93fdda3..f5443ef 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,7 +20,7 @@ lib_deps = jchristensen/Timezone@^1.2.4 adafruit/Adafruit Unified Sensor @ ^1.1.4 adafruit/Adafruit BME280 Library@^2.2.4 - https://git.hodos.ro/libraries/wifi.git@^1.0.0 + https://git.hodos.ro/libraries/wifi.git@^1.0.1 https://git.hodos.ro/libraries/ha-mqtt.git@^1.0.0 build_flags = -D WIFI_ALWAYS_ON=1 diff --git a/src/esp_clock.cpp b/src/esp_clock.cpp index f83af4e..0e65126 100644 --- a/src/esp_clock.cpp +++ b/src/esp_clock.cpp @@ -57,7 +57,13 @@ void setup() { digitalWrite(LED_BUILTIN, HIGH); Display::setup(); - Ota::setup(); + Ota::setup( + [] { + Display::displayText("load"); + Mqtt::publishCleanupConfig(); + delay(2000); + Mqtt::disconnect(); + }); Ntp::setup(); Bme::setup(); Mqtt::setup(&ts,