Merge pull request #15352 from SRGDamia1/development

Development
This commit is contained in:
Theo Arends 2022-04-12 16:20:00 +02:00 committed by GitHub
commit 727b207ccc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 12 deletions

View File

@ -22,6 +22,10 @@ Add ``#define USE_TASMESH`` to your file ``user_config_override.h`` before compi
## Commands
**WARNING: The MAC address used for ESP-NOW on the broker is the *Soft AP MAC*, not the WiFi MAC.**
*NOTE: The colons in the mac addresses of the commands are optional.*
``MeshBroker`` - starts the broker on the ESP32, printing out the MAC and used WiFi-channel to the log. Must be called after WiFi is initialized!! Example 'Rule1 on system#boot do meshbroker endon'
``MeshChannel 1..13`` - changes the WiFi-channel (on the node) to n (1-13) according to the channel of the (ESP32-)broker.
@ -36,16 +40,24 @@ Add ``#define USE_TASMESH`` to your file ``user_config_override.h`` before compi
Rules examples:
- The broker must be started after wifi is up!!</br>``rule1 on system#boot do meshbroker endon``
- The node may be started as soon as possible. Once started wifi and webserver are disabled by design</br>``rule1 on system#init do meshnode 98:F4:AB:6D:2D:B5 endon``
- Add a known peer (another node in the mesh) after the node has initialized</br>``rule3 on mesh#node=1 do meshpeer 2cf4323cdb33 endon``
- The broker must be started after wifi is up!!
- To start as ESP32 as broker after wifi and mqtt connection, use</br>``rule1 on system#boot do meshbroker endon``
- The node may be started as soon as possible. Once started wifi and webserver are disabled by design.
- To start the node immediately use</br>``rule1 on system#init do meshnode FA:KE:AD:DR:ES:S1 endon``
- To use mesh in combination with deep sleep, you must set a rule to re-initialize the mesh on wake-up.
The mesh status and parameters are **NOT** (yet) saved to flash and the mesh is not restarted automatically.
- **WARNING**: In case of a system-wide power outage, nodes will be unable to reconnect until after the broker is ready!
If all devices power up at the same time, a broker starting after `system#boot` will likely not be ready until *after* a node attempting to join at `system#init`.
This will cause the node to fail to mesh and *no retrying is implemented at this time*.
To account for this, instead of (or in addition to) using a rule on the nodes, assign all nodes to a common group topic (`GroupTopic2 tasnodes`) and have the broker send a command on that topic after it is ready:</br>`rule2 on mesh#broker=1 do publish cmnd/tasnodes/meshnode FA:KE:AD:DR:ES:S1`
- Add a known peer (another node in the mesh) after the node has initialized</br>``rule3 on mesh#node=1 do meshpeer FA:KE:AD:DR:ES:S1 endon``
## Limitations
The following limitations apply:
- An ESP32 is only supported as a broker
- An ESP8266 is only supported as a node
- No command persistence is implemented so use rules to start a broker or a node
- No command persistence is implemented so use rules to start a broker or a node after start up or deep sleep
- Although node send queues are implemented there is no node receive queue so MQTT commands send to the node need to be as small as possible limited to a maximum of around 160 characters including the topic
- Although broker receive queues are implemented there is no broker send queue so MQTT commands send to the node need to be as small as possible limited to a maximum of around 160 characters including the topic
- As there is no direct connection from the node to the MQTT broker it will signal the node as LWT Offline

View File

@ -649,6 +649,9 @@ void CmndStatus(void)
(uint32_t)WiFi.localIP(), Settings->ipv4_address[1], Settings->ipv4_address[2],
Settings->ipv4_address[3], Settings->ipv4_address[4],
WiFi.macAddress().c_str());
#if defined USE_TASMESH
ResponseAppend_P(PSTR(",\"Soft AP Mac\":\"%s\""), WiFi.softAPmacAddress().c_str());
#endif // USE_TASMESH
#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32 && defined(USE_ETHERNET)
ResponseAppend_P(PSTR(",\"Ethernet\":{\"" D_CMND_HOSTNAME "\":\"%s\",\""
D_CMND_IPADDRESS "\":\"%_I\",\"" D_JSON_GATEWAY "\":\"%_I\",\"" D_JSON_SUBNETMASK "\":\"%_I\",\""

View File

@ -41,10 +41,13 @@
#define MESH_MAX_PACKETS 3 // (3) Max number of packets
#define MESH_REFRESH 50 // Number of ms
// The format of the vendor-specific action frame is as follows:
// ------------------------------------------------------------------------------------------------------------
// | MAC Header | Category Code | Organization Identifier | Random Values | Vendor Specific Content | FCS |
// ------------------------------------------------------------------------------------------------------------
// 24 bytes 1 byte 3 bytes 4 bytes 7~255 bytes 4 bytes
//
// The Vendor Specific Content contains vendor-specific fields as follows:
// -------------------------------------------------------------------------------
// | Element ID | Length | Organization Identifier | Type | Version | Body |
// -------------------------------------------------------------------------------

View File

@ -288,7 +288,7 @@ bool MESHroleNode(void) {
}
/**
* @brief Redirects the mqtt message on the node just before it would have been sended to
* @brief Redirects the outgoing mqtt message on the node just before it would have been sent to
* the broker via ESP-NOW
*
* @param _topic
@ -385,8 +385,10 @@ void MESHstartNode(int32_t _channel, uint8_t _role){ //we need a running broker
wifi_promiscuous_enable(0);
WiFi.disconnect();
MESHsetWifi(0);
if (esp_now_init() != 0) {
AddLog(LOG_LEVEL_INFO, PSTR("MSH: Node init failed"));
esp_now_deinit(); // in case it was already initialized but disconnected
int init_result = esp_now_init();
if (init_result != 0) {
AddLog(LOG_LEVEL_INFO, PSTR("MSH: Node init failed with error: %d"), init_result);
// try to re-launch wifi
MESH.role = ROLE_NONE;
MESHsetWifi(1);
@ -421,8 +423,10 @@ void MESHstartBroker(void) { // Must be called after WiFi is initialized!!
WiFi.softAPmacAddress(MESH.broker); //set MESH.broker to the needed MAC
uint32_t _channel = WiFi.channel();
if (esp_now_init() != 0) {
AddLog(LOG_LEVEL_INFO, PSTR("MSH: Broker init failed"));
esp_now_deinit(); // in case it was already initialized by disconnected
esp_err_t init_result = esp_now_init();
if (esp_err_t() != ESP_OK) {
AddLog(LOG_LEVEL_INFO, PSTR("MSH: Broker init failed with error: %s"), init_result);
return;
}
@ -646,6 +650,7 @@ void MESHEverySecond(void) {
if (millis() - MESH.lastMessageFromBroker > 70000) {
AddLog(LOG_LEVEL_DEBUG, PSTR("MSH: Broker not seen for 70 secs, try to re-launch wifi"));
MESH.role = ROLE_NONE;
MESHdeInit(); // if we don't deinit after losing connection, we will get an error trying to reinit later
MESHsetWifi(1);
WifiBegin(3, MESH.channel);
}
@ -733,12 +738,15 @@ void (* const MeshCommand[])(void) PROGMEM = {
&CmndMeshBroker, &CmndMeshNode, &CmndMeshPeer, &CmndMeshChannel, &CmndMeshInterval };
void CmndMeshBroker(void) {
#ifdef ESP32 // only ESP32 currently supported as broker
MESH.channel = WiFi.channel(); // The Broker gets the channel from the router, no need to declare it with MESHCHANNEL (will be mandatory set it when ETH will be implemented)
MESHstartBroker();
ResponseCmndNumber(MESH.channel);
#endif // ESP32
}
void CmndMeshNode(void) {
#ifndef ESP32 // only ESP8266 current supported as node
if (XdrvMailbox.data_len > 0) {
MESHHexStringToBytes(XdrvMailbox.data, MESH.broker);
if (XdrvMailbox.index != 0) { XdrvMailbox.index = 1; } // Everything not 0 is a full node
@ -764,6 +772,7 @@ void CmndMeshNode(void) {
AddLog(LOG_LEVEL_INFO, PSTR("MSH: No Mesh Broker found using MAC %s"), XdrvMailbox.data);
}
}
#endif // ESP32
}
void CmndMeshPeer(void) {
@ -773,9 +782,16 @@ void CmndMeshPeer(void) {
char _peerMAC[18];
ToHex_P(_MAC, 6, _peerMAC, 18, ':');
AddLog(LOG_LEVEL_DEBUG,PSTR("MSH: MAC-string %s (%s)"), XdrvMailbox.data, _peerMAC);
MESHaddPeer(_MAC);
MESHcountPeers();
ResponseCmndChar(_peerMAC);
if (MESHcheckPeerList((const uint8_t *)_MAC) == false) {
MESHaddPeer(_MAC);
MESHcountPeers();
ResponseCmndChar(_peerMAC);
} else if (WiFi.macAddress() == String(_peerMAC) || WiFi.softAPmacAddress() == String(_peerMAC)){
// a device can be added as its own peer, but every send will result in a ESP_NOW_SEND_FAIL
AddLog(LOG_LEVEL_DEBUG,PSTR("MSH: device %s cannot be a peer of itself"), XdrvMailbox.data, _peerMAC);
} else {
AddLog(LOG_LEVEL_DEBUG,PSTR("MSH: %s is already on peer list, will not add"), XdrvMailbox.data, _peerMAC);
}
}
}