Support LWT messages when using TASMESH (#20392)

* Send LWTs when nodes come online and offline

* Use string macro

* Add a TASMESH_HEARTBEAT config

* Add flags to config file

* Fix missing break in case

* Rename heartbeat feature define

* Comment out tasmesh settings

* Detect online peers on all packets, not just heartbeats
This commit is contained in:
Felipe Martínez 2024-02-18 15:28:00 +01:00 committed by GitHub
parent d8d1b1d131
commit d77cf7d2f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 50 additions and 1 deletions

View File

@ -396,6 +396,8 @@
// -- ESP-NOW -------------------------------------
//#define USE_TASMESH // Enable Tasmota Mesh using ESP-NOW (+11k code)
//#define USE_TASMESH_HEARTBEAT // If enabled, the broker will detect when nodes come online and offline and send Birth and LWT messages over MQTT correspondingly
//#define TASMESH_OFFLINE_DELAY 3 // Maximum number of seconds since the last heartbeat before the broker considers a node to be offline
// -- OTA -----------------------------------------
//#define USE_ARDUINO_OTA // Add optional support for Arduino OTA with ESP8266 (+13k code)

View File

@ -91,6 +91,10 @@ struct mesh_peer_t {
uint32_t lastMessageFromPeer; // Time of last message from peer
#ifdef ESP32
char topic[MESH_TOPICSZ];
#ifdef USE_TASMESH_HEARTBEAT
bool isAlive; // True if we have gotten a heartbeat recently
uint32_t lastHeartbeatFromPeer; // Time of last heartbeat from peer
#endif // USE_TASMESH_HEARTBEAT
#endif //ESP32
};
@ -164,7 +168,10 @@ enum MESH_Packet_Type { // Type of packet
PACKET_TYPE_REGISTER_NODE, // register a node with encrypted broker-MAC, announce mqtt topic to ESP32-proxy - broker will send time ASAP
PACKET_TYPE_REFRESH_NODE, // refresh node infos with encrypted broker-MAC, announce mqtt topic to ESP32-proxy - broker will send time slightly delayed
PACKET_TYPE_MQTT, // send regular mqtt messages, single or multipackets
PACKET_TYPE_WANTTOPIC // the broker has no topic for this peer/node
PACKET_TYPE_WANTTOPIC, // the broker has no topic for this peer/node
#ifdef USE_TASMESH_HEARTBEAT
PACKET_TYPE_HEARTBEAT // sent periodically from nodes to the broker to signal aliveness
#endif // USE_TASMESH_HEARTBEAT
};
/*********************************************************************************************\

View File

@ -472,6 +472,22 @@ void MESHevery50MSecond(void) {
// do something on the node
// AddLog(LOG_LEVEL_DEBUG, PSTR("MSH: %30_H), (uint8_t *)&MESH.packetToConsume.front());
#ifdef USE_TASMESH_HEARTBEAT
for (auto &_peer : MESH.peers){
if (memcmp(_peer.MAC, MESH.packetToConsume.front().sender, 6) == 0) {
_peer.lastHeartbeatFromPeer = millis();
if (!_peer.isAlive) {
_peer.isAlive = true;
char stopic[TOPSZ];
GetTopic_P(stopic, TELE, _peer.topic, S_LWT);
MqttPublishPayload(stopic, PSTR(MQTT_LWT_ONLINE));
}
break;
}
}
#endif // USE_TASMESH_HEARTBEAT
MESHencryptPayload(&MESH.packetToConsume.front(), 0);
switch (MESH.packetToConsume.front().type) {
// case PACKET_TYPE_REGISTER_NODE:
@ -546,6 +562,9 @@ void MESHevery50MSecond(void) {
// AddLog(LOG_LEVEL_INFO, PSTR("MSH: %*_H), MESH.packetToConsume.front().chunkSize, (uint8_t *)&MESH.packetToConsume.front().payload);
}
break;
case PACKET_TYPE_HEARTBEAT:
break;
default:
AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)&MESH.packetToConsume.front(), MESH.packetToConsume.front().chunkSize +5);
break;
@ -582,6 +601,17 @@ void MESHEverySecond(void) {
AddLog(LOG_LEVEL_INFO, PSTR("MSH: Multi packets in buffer %u"), MESH.multiPackets.size());
MESH.multiPackets.erase(MESH.multiPackets.begin());
}
#ifdef USE_TASMESH_HEARTBEAT
for (auto &_peer : MESH.peers){
if (_peer.isAlive && TimePassedSince(_peer.lastHeartbeatFromPeer) > TASMESH_OFFLINE_DELAY * 1000) {
_peer.isAlive = false;
char stopic[TOPSZ];
GetTopic_P(stopic, TELE, _peer.topic, S_LWT);
MqttPublishPayload(stopic, PSTR(MQTT_LWT_OFFLINE));
}
}
#endif // USE_TASMESH_HEARTBEAT
}
#else // ESP8266
@ -649,6 +679,16 @@ void MESHEverySecond(void) {
MESHsetWifi(1);
WifiBegin(3, MESH.channel);
}
#ifdef USE_TASMESH_HEARTBEAT
MESH.sendPacket.counter++;
MESH.sendPacket.TTL = 2;
MESH.sendPacket.chunks = 0;
MESH.sendPacket.chunk = 0;
MESH.sendPacket.chunkSize = 0;
MESH.sendPacket.type = PACKET_TYPE_HEARTBEAT;
MESHsendPacket(&MESH.sendPacket);
#endif // USE_TASMESH_HEARTBEAT
}
}