diff --git a/platformio.ini b/platformio.ini index 2fc5abd..656090f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -4,4 +4,8 @@ board = esp12e framework = arduino lib_deps = https://github.com/thorsten-gehrig/arduino-tpuart-knx-user-forum https://github.com/knolleary/pubsubclient - https://github.com/me-no-dev/ESPAsyncWebServer \ No newline at end of file + https://github.com/me-no-dev/ESPAsyncWebServer +upload_port = /dev/ttyUSB0 +upload_speed = 460800 +monitor_port = /dev/ttyUSB0 +monitor_speed = 115200 diff --git a/src/main.cpp b/src/main.cpp index dc69a71..f478fb6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,22 +4,23 @@ #include "wifi.h" #include "time_.h" #include "mqtt.h" -#include "http.h" +#include "ota.h" void setup() { delay(500); - Serial.begin(112500); + Serial.begin(115200); Serial.print("\n\n\nStartup\n"); knxSetup(); wifiSetup(); - timeSetup(); - mqttSetup(); - httpSetup(); + otaSetup(); } void loop() { - knxLoop(); wifiLoop(); - timeLoop(); - mqttLoop(); + otaLoop(); + if (isOtaDelayComplete()) { + knxLoop(); + timeLoop(); + mqttLoop(); + } } diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 4753e87..7bcb341 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -1,17 +1,23 @@ #include "mqtt.h" #include "wifi.h" +#include #include #include PubSubClient mqtt; +bool mqttHalted = false; + void mqttSetup() { mqtt.setServer("10.0.0.50", 1883); mqtt.setBufferSize(512); } void mqttLoop() { + if (mqttHalted) { + return; + } if (!isWiFiConnected()) { mqtt.disconnect(); } else if (!mqtt.loop()) { @@ -27,8 +33,10 @@ void mqttPublish(const char *topic, const char *payload) { String getLogPrefix(const char *level) { tm info{}; - getLocalTime(&info); - char buffer[20]; + time_t now = 0; + time(&now); + localtime_r(&now, &info); + char buffer[27]; snprintf(buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d %5s ", info.tm_year, info.tm_mon, info.tm_mday, info.tm_hour, info.tm_min, info.tm_sec, level); return {buffer}; } @@ -54,3 +62,12 @@ void mqttLogError(const char *message, ...) { mqttLog("og/error", message, vl); va_end(vl); } + +void mqttHalt() { + if (mqtt.loop()) { + Serial.print("Disconnecting MQTT..."); + mqttHalted = true; + mqtt.disconnect(); + Serial.print(" DONE"); + } +} \ No newline at end of file diff --git a/src/mqtt.h b/src/mqtt.h index f73853c..6d0d0ba 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -11,4 +11,6 @@ void mqttLogInfo(const char *message, ...); void mqttLogError(const char *message, ...); +void mqttHalt(); + #endif diff --git a/src/ota.cpp b/src/ota.cpp new file mode 100644 index 0000000..4d1bf19 --- /dev/null +++ b/src/ota.cpp @@ -0,0 +1,87 @@ +#include "ota.h" +#include "wifi.h" +#include "mqtt.h" +#include "time_.h" +#include "http.h" + +#include + +#define OTA_DELAY_SEC 10 + +bool otaDelayComplete = false; + +unsigned long otaDelaySince = 0; + +const char *otaError(ota_error_t error); + +void onOtaDelayComplete(); + +void otaDelayLog(); + +void otaSetup() { + ArduinoOTA.onStart([] { + Serial.print("\nOTA begin...\n"); + }); + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + Serial.printf("\rOTA: %3d%%", 100 * progress / total); + }); + ArduinoOTA.onError([](ota_error_t error) { + Serial.printf("\nOTA error: #%d = %s\n", error, otaError(error)); + }); + ArduinoOTA.onEnd([] { + Serial.print("\nOTA complete.\n"); + mqttHalt(); + wifiHalt(); + }); + ArduinoOTA.begin(); +} + +void otaLoop() { + ArduinoOTA.handle(); + if (otaDelayComplete) { + return; + } + if (!isWiFiConnected()) { + otaDelaySince = millis(); + return; + } + if (millis() - otaDelaySince <= OTA_DELAY_SEC * 1000) { + otaDelayLog(); + return; + } + Serial.print("OTA delay complete!\n"); + otaDelayComplete = true; + timeSetup(); + mqttSetup(); + httpSetup(); +} + +void otaDelayLog() { + static unsigned long lastSec = 0; + unsigned long pastSec = (millis() - otaDelaySince) / 1000; + if (pastSec != lastSec) { + lastSec = pastSec; + Serial.printf("OTA delay %2lus\n", OTA_DELAY_SEC - pastSec); + } +} + +bool isOtaDelayComplete() { + return otaDelayComplete; +} + +const char *otaError(ota_error_t error) { + switch (error) { + case OTA_AUTH_ERROR: + return "AUTH"; + case OTA_BEGIN_ERROR: + return "BEGIN"; + case OTA_CONNECT_ERROR: + return "CONNECT"; + case OTA_RECEIVE_ERROR: + return "RECEIVE"; + case OTA_END_ERROR: + return "END"; + default: + return "???"; + } +} diff --git a/src/ota.h b/src/ota.h new file mode 100644 index 0000000..d6cbf08 --- /dev/null +++ b/src/ota.h @@ -0,0 +1,10 @@ +#ifndef KNXESP_OTA_H +#define KNXESP_OTA_H + +void otaSetup(); + +void otaLoop(); + +bool isOtaDelayComplete(); + +#endif diff --git a/src/wifi.cpp b/src/wifi.cpp index 399b1fa..d85fbbc 100644 --- a/src/wifi.cpp +++ b/src/wifi.cpp @@ -8,6 +8,8 @@ unsigned long wifiConnectBegin = 0; bool wifiConnected = false; +bool wifiHalted = false; + bool isWiFiConnected() { return wifiConnected; } @@ -24,6 +26,9 @@ void wifiSetup() { } void wifiLoop() { + if (wifiHalted) { + return; + } if (!wifiConnected) { if (WiFi.localIP() == 0UL) { if (millis() - wifiConnectBegin > WIFI_TIMEOUT_MILLIS) { @@ -33,7 +38,7 @@ void wifiLoop() { wifiSetup(); } } else { - Serial.print("wifi connected\n"); + Serial.printf("wifi connected as: %s\n", WiFi.localIP().toString().c_str()); wifiConnected = true; } } else { @@ -43,3 +48,15 @@ void wifiLoop() { } } } + +void wifiHalt() { + if (WiFi.localIP() != 0UL) { + Serial.print("Stopping WiFi..."); + wifiHalted = true; + WiFi.disconnect(); + while (WiFi.localIP() != 0UL) { + delay(100); + } + Serial.print(" DONE\n"); + } +} \ No newline at end of file diff --git a/src/wifi.h b/src/wifi.h index 4985adc..0114d3f 100644 --- a/src/wifi.h +++ b/src/wifi.h @@ -7,7 +7,7 @@ void wifiSetup(); void wifiLoop(); -void timeLoop(); +void wifiHalt(); bool isTimeSet();