diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index 7df60847..a62b0dac 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -169,6 +169,7 @@ #define HEARTBEAT_NONE 0 // Never send heartbeat #define HEARTBEAT_ONCE 1 // Send it only once upon MQTT connection #define HEARTBEAT_REPEAT 2 // Send it upon MQTT connection and every HEARTBEAT_INTERVAL +#define HEARTBEAT_REPEAT_STATUS 3 // Send it upon MQTT connection and every HEARTBEAT_INTERVAL only STATUS report // Backwards compatibility check #if defined(HEARTBEAT_ENABLED) && (HEARTBEAT_ENABLED == 0) @@ -180,7 +181,7 @@ #endif #ifndef HEARTBEAT_INTERVAL -#define HEARTBEAT_INTERVAL 300000 // Interval between heartbeat messages (in ms) +#define HEARTBEAT_INTERVAL 300 // Interval between heartbeat messages (in sec) #endif #define UPTIME_OVERFLOW 4294967295 // Uptime overflow value diff --git a/code/espurna/system.ino b/code/espurna/system.ino index 6afd96b2..27b2d4dd 100644 --- a/code/espurna/system.ino +++ b/code/espurna/system.ino @@ -12,6 +12,8 @@ Copyright (C) 2018 by Xose PĂ©rez unsigned long _loop_delay = 0; bool _system_send_heartbeat = false; +unsigned char _heartbeat_mode = HEARTBEAT_MODE; +unsigned long _heartbeat_interval = HEARTBEAT_INTERVAL; // Calculated load average 0 to 100; unsigned short int _load_average = 100; @@ -66,6 +68,10 @@ void systemSendHeartbeat() { _system_send_heartbeat = true; } +bool systemGetHeartbeat() { + return _system_send_heartbeat; +} + unsigned long systemLoopDelay() { return _loop_delay; } @@ -75,6 +81,11 @@ unsigned long systemLoadAverage() { return _load_average; } +void _systemSetupHeartbeat() { + _heartbeat_mode = getSetting("hbMode", HEARTBEAT_MODE).toInt(); + _heartbeat_interval = getSetting("hbInterval", HEARTBEAT_INTERVAL).toInt(); +} + void systemLoop() { // ------------------------------------------------------------------------- @@ -97,19 +108,21 @@ void systemLoop() { // Heartbeat // ------------------------------------------------------------------------- - #if HEARTBEAT_MODE == HEARTBEAT_ONCE - if (_system_send_heartbeat) { - _system_send_heartbeat = false; - heartbeat(); - } - #elif HEARTBEAT_MODE == HEARTBEAT_REPEAT + if (_system_send_heartbeat && _heartbeat_mode == HEARTBEAT_ONCE) { + heartbeat(); + _system_send_heartbeat = false; + } else if (_heartbeat_mode == HEARTBEAT_REPEAT || _heartbeat_mode == HEARTBEAT_REPEAT_STATUS) { static unsigned long last_hbeat = 0; - if (_system_send_heartbeat || (last_hbeat == 0) || (millis() - last_hbeat > HEARTBEAT_INTERVAL)) { - _system_send_heartbeat = false; + #if NTP_SUPPORT + if ((_system_send_heartbeat && ntpSynced()) || (millis() - last_hbeat > _heartbeat_interval * 1000)) { + #else + if (_system_send_heartbeat || (millis() - last_hbeat > _heartbeat_interval * 1000)) { + #endif last_hbeat = millis(); heartbeat(); + _system_send_heartbeat = false; } - #endif // HEARTBEAT_MODE == HEARTBEAT_REPEAT + } // ------------------------------------------------------------------------- // Load Average calculation @@ -179,4 +192,7 @@ void systemSetup() { // Register Loop espurnaRegisterLoop(systemLoop); + // Cache Heartbeat values + _systemSetupHeartbeat(); + } diff --git a/code/espurna/utils.ino b/code/espurna/utils.ino index 4903082f..9d9768bf 100644 --- a/code/espurna/utils.ino +++ b/code/espurna/utils.ino @@ -58,6 +58,14 @@ String getCoreRevision() { #endif } +unsigned char getHeartbeatMode() { + return getSetting("hbMode", HEARTBEAT_MODE).toInt(); +} + +unsigned char getHeartbeatInterval() { + return getSetting("hbInterval", HEARTBEAT_INTERVAL).toInt(); +} + // WTF // Calling ESP.getFreeHeap() is making the system crash on a specific // AiLight bulb, but anywhere else... @@ -135,8 +143,6 @@ unsigned long getUptime() { } -#if HEARTBEAT_MODE != HEARTBEAT_NONE - // ----------------------------------------------------------------------------- // Heartbeat helper // ----------------------------------------------------------------------------- @@ -196,6 +202,7 @@ void heartbeat() { unsigned int free_heap = getFreeHeap(); #if MQTT_SUPPORT + unsigned char _heartbeat_mode = getHeartbeatMode(); bool serial = !mqttConnected(); #else bool serial = true; @@ -224,9 +231,9 @@ void heartbeat() { // ------------------------------------------------------------------------- #if MQTT_SUPPORT - if (!serial) { + if (!serial && (_heartbeat_mode == HEARTBEAT_REPEAT || systemGetHeartbeat())) { if (hb_cfg & Heartbeat::Interval) - mqttSend(MQTT_TOPIC_INTERVAL, String(HEARTBEAT_INTERVAL / 1000).c_str()); + mqttSend(MQTT_TOPIC_INTERVAL, String(getHeartbeatInterval() / 1000).c_str()); if (hb_cfg & Heartbeat::App) mqttSend(MQTT_TOPIC_APP, APP_NAME); @@ -280,7 +287,10 @@ void heartbeat() { if (hb_cfg & Heartbeat::Loadavg) mqttSend(MQTT_TOPIC_LOADAVG, String(systemLoadAverage()).c_str()); + } else if (!serial && _heartbeat_mode == HEARTBEAT_REPEAT_STATUS) { + mqttSend(MQTT_TOPIC_STATUS, MQTT_STATUS_ONLINE, true); } + #endif // ------------------------------------------------------------------------- @@ -300,8 +310,6 @@ void heartbeat() { } -#endif /// HEARTBEAT_MODE != HEARTBEAT_NONE - // ----------------------------------------------------------------------------- // INFO // ----------------------------------------------------------------------------- diff --git a/code/espurna/ws.ino b/code/espurna/ws.ino index 995624f0..aa329e38 100644 --- a/code/espurna/ws.ino +++ b/code/espurna/ws.ino @@ -350,6 +350,8 @@ void _wsOnStart(JsonObject& root) { #if TERMINAL_SUPPORT root["cmdVisible"] = 1; #endif + root["hbMode"] = getSetting("hbMode", HEARTBEAT_MODE).toInt(); + root["hbInterval"] = getSetting("hbInterval", HEARTBEAT_INTERVAL).toInt(); } diff --git a/code/html/index.html b/code/html/index.html index 69b65202..349ebfcb 100644 --- a/code/html/index.html +++ b/code/html/index.html @@ -620,6 +620,31 @@
Request password when starting telnet session
+
+ + +
+
+
+ Define when heartbeat message will be sent. +
+
+ +
+ + +
+
+
+ This is the interval in seconds how often to send the heartbeat message. +
+
+
@@ -629,7 +654,7 @@
The device has bytes available for OTA updates. If your image is larger than this consider doing a two-step update.
- +