Browse Source

Configure Heartbeat & option HEARTBEAT_REPEAT_STATUS:

- Heartbeat mode and interval configuration added to WebUI ADMIN page
- New option HEARTBEAT_REPEAT_STATUS: on device startup full heartbeat information and after HEARTBEAT_INTERVAL only STATUS report.
- Enhanced first heartbeat message - on device startup it will send heartbeat after ntpSynced will be true to get device time.

P.S. Code is tested. Web part is not compiled, and not tested. I hope it will work :)
sensors
Martins Ierags 5 years ago
parent
commit
465b5230ff
5 changed files with 73 additions and 16 deletions
  1. +1
    -0
      code/espurna/config/general.h
  2. +27
    -9
      code/espurna/system.ino
  3. +14
    -6
      code/espurna/utils.ino
  4. +2
    -0
      code/espurna/ws.ino
  5. +29
    -1
      code/html/index.html

+ 1
- 0
code/espurna/config/general.h View File

@ -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)


+ 27
- 9
code/espurna/system.ino View File

@ -12,6 +12,8 @@ Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
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,13 @@ unsigned long systemLoadAverage() {
return _load_average;
}
void _systemSetupHeartbeat() {
if (getSetting("hbMode").length() == 0) setSetting("hbMode", HEARTBEAT_MODE);
if (getSetting("hbInterval").length() == 0) setSetting("hbInterval", HEARTBEAT_INTERVAL);
_heartbeat_mode = getSetting("hbMode", HEARTBEAT_MODE).toInt();
_heartbeat_interval = getSetting("hbInterval", HEARTBEAT_INTERVAL).toInt();
}
void systemLoop() {
// -------------------------------------------------------------------------
@ -97,19 +110,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)) {
#else
if (_system_send_heartbeat || (millis() - last_hbeat > _heartbeat_interval)) {
#endif
last_hbeat = millis();
heartbeat();
_system_send_heartbeat = false;
}
#endif // HEARTBEAT_MODE == HEARTBEAT_REPEAT
}
// -------------------------------------------------------------------------
// Load Average calculation
@ -179,4 +194,7 @@ void systemSetup() {
// Register Loop
espurnaRegisterLoop(systemLoop);
// Cache Heartbeat values
_systemSetupHeartbeat();
}

+ 14
- 6
code/espurna/utils.ino View File

@ -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
// -----------------------------------------------------------------------------


+ 2
- 0
code/espurna/ws.ino View File

@ -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();
}


+ 29
- 1
code/html/index.html View File

@ -620,6 +620,34 @@
<div class="pure-u-1 pure-u-lg-3-4 hint">Request password when starting telnet session</div>
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Heartbeat mode</label>
<select class="pure-u-1 pure-u-lg-1-4" name="hbMode" tabindex="15" >
<option value="0">HEARTBEAT_NONE</option>
<option value="1">HEARTBEAT_ONCE</option>
<option value="2">HEARTBEAT_REPEAT</option>
<option value="3">HEARTBEAT_REPEAT_STATUS</option>
</select>
<div class="pure-u-0 pure-u-lg-1-2"></div>
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint">
<strong>HEARTBEAT_NONE:</strong> no heartbeat at all, never.<br />
<strong>HEARTBEAT_ONCE:</strong> only on device startup.<br />
<strong>HEARTBEAT_REPEAT:</strong> on device startup and after HEARTBEAT_INTERVAL.<br />
<strong>HEARTBEAT_REPEAT_STATUS:</strong> on device startup full heartbeat information and after HEARTBEAT_INTERVAL only STATUS report.
</div>
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Heartbeat interval</label>
<input name="hbInterval" class="pure-u-1 pure-u-lg-1-4" type="text" tabindex="16" />
<div class="pure-u-0 pure-u-lg-1-2"></div>
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint">
This is the interval in <strong>ms</strong> how often to send the heartbeat message.
</div>
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Upgrade</label>
<input class="pure-u-1-2 pure-u-lg-1-2" name="filename" type="text" readonly />
@ -629,7 +657,7 @@
<div class="pure-u-1 pure-u-lg-3-4 hint">The device has <span name="free_size"></span> bytes available for OTA updates. If your image is larger than this consider doing a <a href="https://github.com/xoseperez/espurna/wiki/TwoStepUpdates" target="_blank"><strong>two-step update</strong></a>.</div>
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4"><progress id="upgrade-progress"></progress></div>
<input name="upgrade" type="file" tabindex="16" />
<input name="upgrade" type="file" tabindex="17" />
</div>
</fieldset>


Loading…
Cancel
Save