17 Commits
v1.21 ... main

Author SHA1 Message Date
90133a7d67 Version 1.42
Fixed some bugs.
2023-03-15 16:37:19 +03:00
dd3cbb9633 Fixed one bug 2023-03-12 12:49:50 +03:00
0b64933ee7 Minor changes 2023-03-07 11:58:03 +03:00
1d8d8e3f7d Fixed one bug 2023-03-06 00:43:29 +03:00
ceb80d8bd7 Minor changes 2023-03-04 13:28:32 +03:00
53464acb22 Minor changes 2023-03-04 12:41:59 +03:00
af8cc16675 Minor changes 2023-03-04 12:36:37 +03:00
c248a08efe Version 1.41
Changed config data storage location to EEPROM.
2023-03-04 11:16:55 +03:00
651ade7334 Fixed one bug 2023-02-26 14:21:47 +03:00
98a082dd67 Version 1.4
Minimized of config message size.
Changed SDK version for 3.0.5
2023-02-26 11:13:18 +03:00
1aa5465687 Fixed one small bug 2023-02-19 12:30:38 +03:00
71ec165aca Version 1.32
Minor changes.
2023-02-19 12:23:25 +03:00
d1ddd9ecbb Minor changes 2023-02-19 11:03:13 +03:00
5d023b13c1 Minor changes 2023-02-19 09:59:58 +03:00
551866b040 Version 1.31
Fixed one minor bug.
2023-02-18 10:07:15 +03:00
b940f325f2 Minor changes 2023-02-17 17:01:52 +03:00
0b603489fd Version 1.3
Added relay work modes.
2023-02-17 09:28:23 +03:00
6 changed files with 221 additions and 147 deletions

View File

@ -11,6 +11,7 @@ ESP-NOW based switch for ESP8266. Alternate firmware for Tuya/SmartLife/eWeLink
5. Possibility firmware update over OTA (if is allows the size of the flash memory).
6. Web interface for settings.
7. Optionally support one external one wire digital climate sensor (DS18B20, DHT11 or DHT22) with automatically added sensor configuration to Home Assistan via MQTT discovery as a sensor. Periodically transmission sensor status (every 300 seconds) to the gateway.
8. Normal or reverse relay mode (normal by default).
## Notes

View File

@ -10,7 +10,7 @@ function createXmlHttpObject() {
function load() {
if (xmlHttp.readyState == 0 || xmlHttp.readyState == 4) {
xmlHttp.open('PUT', '/config.json', true);
xmlHttp.open('GET', '/config', true);
xmlHttp.send(null);
xmlHttp.onload = function () {
jsonResponse = JSON.parse(xmlHttp.responseText);
@ -29,6 +29,7 @@ function loadBlock() {
}
document.getElementsByTagName('body')[0].innerHTML = newString;
setFirmvareValue('version', 'firmware');
setGpioValue('workModeSelect', 'workMode');
setGpioValue('relayPinSelect', 'relayPin');
setGpioValue('relayPinTypeSelect', 'relayPinType');
setGpioValue('ledPinSelect', 'ledPin');
@ -71,7 +72,8 @@ function saveSetting(submit) {
+ "&extButtonPin=" + getSelectValue('extButtonPinSelect')
+ "&extButtonPinType=" + getSelectValue('extButtonPinTypeSelect')
+ "&sensorPin=" + getSelectValue('sensorPinSelect')
+ "&sensorType=" + getSelectValue('sensorTypeSelect');
+ "&sensorType=" + getSelectValue('sensorTypeSelect')
+ "&workMode=" + getSelectValue('workModeSelect');
sendRequest(submit, server);
alert("Please restart device for changes apply.");
}

View File

@ -29,6 +29,15 @@
title="ESP-NOW network name (1 to 20 characters)" />
</div>
<div class="wrapper">
<p class="text-select">Work mode:</p>
<input id="workMode" value="{{workMode}}" hidden />
<p><select id="workModeSelect">
<option value="0">NORMAL</option>
<option value="1">REVERSE</option>
</select></p>
</div>
<div class="wrapper">
<p class="text-select">Relay GPIO:</p>
<input id="relayPin" value="{{relayPin}}" hidden />

View File

@ -21,7 +21,6 @@
```text
Relay GPIO GPIO12 HIGH
Led GPIO GPIO13 LOW
Button GPIO GPIO04 RISING
Ext sensor GPIO GPIO14 DS18B20
```

View File

@ -2,8 +2,9 @@
platform = espressif8266
board = esp12e
framework = arduino
build_flags = -D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK305
board_build.filesystem = littlefs
board_build.ldscript = eagle.flash.4m2m.ld
board_build.ldscript = eagle.flash.4m1m.ld
lib_deps =
https://github.com/aZholtikov/ZHNetwork
https://github.com/aZholtikov/ZHConfig
@ -16,8 +17,9 @@ lib_deps =
platform = espressif8266
board = esp12e
framework = arduino
build_flags = -D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK305
board_build.filesystem = littlefs
board_build.ldscript = eagle.flash.4m2m.ld
board_build.ldscript = eagle.flash.4m1m.ld
upload_port = 192.168.4.1
upload_protocol = espota
lib_deps =
@ -32,8 +34,9 @@ lib_deps =
platform = espressif8266
board = esp8285
framework = arduino
build_flags = -D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK305
board_build.filesystem = littlefs
board_build.ldscript = eagle.flash.2m256.ld
board_build.ldscript = eagle.flash.2m64.ld
lib_deps =
https://github.com/aZholtikov/ZHNetwork
https://github.com/aZholtikov/ZHConfig
@ -46,8 +49,9 @@ lib_deps =
platform = espressif8266
board = esp8285
framework = arduino
build_flags = -D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK305
board_build.filesystem = littlefs
board_build.ldscript = eagle.flash.2m256.ld
board_build.ldscript = eagle.flash.2m64.ld
upload_port = 192.168.4.1
upload_protocol = espota
lib_deps =
@ -62,6 +66,7 @@ lib_deps =
platform = espressif8266
board = esp8285
framework = arduino
build_flags = -D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK305
board_build.filesystem = littlefs
board_build.ldscript = eagle.flash.1m64.ld
lib_deps =

View File

@ -2,6 +2,7 @@
#include "ArduinoOTA.h"
#include "ESPAsyncWebServer.h" // https://github.com/aZholtikov/Async-Web-Server
#include "LittleFS.h"
#include "EEPROM.h"
#include "Ticker.h"
#include "DallasTemperature.h"
#include "DHTesp.h"
@ -14,6 +15,8 @@ void onConfirmReceiving(const uint8_t *target, const uint16_t id, const bool sta
void loadConfig(void);
void saveConfig(void);
void loadStatus(void);
void saveStatus(void);
void setupWebServer(void);
void buttonInterrupt(void);
@ -30,15 +33,11 @@ typedef struct
char message[200]{0};
} espnow_message_t;
std::vector<espnow_message_t> espnowMessage;
const String firmware{"1.21"};
struct deviceConfig
{
String espnowNetName{"DEFAULT"};
uint8_t workMode{0};
String deviceName = "ESP-NOW switch " + String(ESP.getChipId(), HEX);
bool relayStatus{false};
uint8_t relayPin{0};
uint8_t relayPinType{1};
uint8_t buttonPin{0};
@ -47,17 +46,20 @@ uint8_t extButtonPin{0};
uint8_t extButtonPinType{0};
uint8_t ledPin{0};
uint8_t ledPinType{0};
uint8_t sensorPin{0};
uint8_t sensorType{0};
} config;
std::vector<espnow_message_t> espnowMessage;
const String firmware{"1.42"};
bool relayStatus{false};
bool wasMqttAvailable{false};
uint8_t gatewayMAC[6]{0};
const String payloadOn{"ON"};
const String payloadOff{"OFF"};
ZHNetwork myNet;
AsyncWebServer webServer(80);
@ -92,32 +94,35 @@ void setup()
LittleFS.begin();
loadConfig();
loadStatus();
if (sensorPin)
if (config.sensorPin)
{
if (sensorType == ENST_DS18B20)
oneWire.begin(sensorPin);
if (sensorType == ENST_DHT11 || sensorType == ENST_DHT22)
dht.setup(sensorPin, DHTesp::AUTO_DETECT);
if (config.sensorType == ENST_DS18B20)
oneWire.begin(config.sensorPin);
if (config.sensorType == ENST_DHT11 || config.sensorType == ENST_DHT22)
dht.setup(config.sensorPin, DHTesp::AUTO_DETECT);
}
if (relayPin)
if (config.relayPin)
{
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, relayPinType ? relayStatus : !relayStatus);
pinMode(config.relayPin, OUTPUT);
if (config.workMode)
digitalWrite(config.relayPin, config.relayPinType ? !relayStatus : relayStatus);
else
digitalWrite(config.relayPin, config.relayPinType ? relayStatus : !relayStatus);
}
if (ledPin)
if (config.ledPin)
{
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, ledPinType ? relayStatus : !relayStatus);
pinMode(config.ledPin, OUTPUT);
digitalWrite(config.ledPin, config.ledPinType ? relayStatus : !relayStatus);
}
if (buttonPin)
attachInterrupt(buttonPin, buttonInterrupt, buttonPinType ? RISING : FALLING);
if (extButtonPin)
attachInterrupt(extButtonPin, buttonInterrupt, extButtonPinType ? RISING : FALLING);
if (config.buttonPin)
attachInterrupt(config.buttonPin, buttonInterrupt, config.buttonPinType ? RISING : FALLING);
if (config.extButtonPin)
attachInterrupt(config.extButtonPin, buttonInterrupt, config.extButtonPinType ? RISING : FALLING);
WiFi.setSleepMode(WIFI_NONE_SLEEP);
myNet.begin(espnowNetName.c_str());
myNet.begin(config.espnowNetName.c_str());
// myNet.setCryptKey("VERY_LONG_CRYPT_KEY"); // If encryption is used, the key must be set same of all another ESP-NOW devices in network.
myNet.setOnBroadcastReceivingCallback(onBroadcastReceiving);
@ -142,16 +147,16 @@ void loop()
if (attributesMessageTimerSemaphore)
{
sendAttributesMessage();
if (sensorPin)
sendAttributesMessage(sensorType);
if (config.sensorPin)
sendAttributesMessage(config.sensorType);
}
if (keepAliveMessageTimerSemaphore)
sendKeepAliveMessage();
if (statusMessageTimerSemaphore)
{
sendStatusMessage();
if (sensorPin)
sendStatusMessage(sensorType);
if (config.sensorPin)
sendStatusMessage(config.sensorType);
}
myNet.maintenance();
ArduinoOTA.handle();
@ -168,7 +173,7 @@ void onBroadcastReceiving(const char *data, const uint8_t *sender)
if (myNet.macToString(gatewayMAC) == myNet.macToString(sender) && incomingData.payloadsType == ENPT_KEEP_ALIVE)
{
isGatewayAvailable = true;
StaticJsonDocument<sizeof(esp_now_payload_data_t::message)> json;
DynamicJsonDocument json(sizeof(esp_now_payload_data_t::message));
deserializeJson(json, incomingData.message);
bool temp = json["MQTT"] == "online" ? true : false;
if (wasMqttAvailable != temp)
@ -177,14 +182,14 @@ void onBroadcastReceiving(const char *data, const uint8_t *sender)
if (temp)
{
sendConfigMessage();
if (sensorPin)
sendConfigMessage(sensorType);
if (config.sensorPin)
sendConfigMessage(config.sensorType);
sendAttributesMessage();
if (sensorPin)
sendAttributesMessage(sensorType);
if (config.sensorPin)
sendAttributesMessage(config.sensorType);
sendStatusMessage();
if (sensorPin)
sendStatusMessage(sensorType);
if (config.sensorPin)
sendStatusMessage(config.sensorType);
}
}
gatewayAvailabilityCheckTimer.once(15, gatewayAvailabilityCheckTimerCallback);
@ -197,16 +202,26 @@ void onUnicastReceiving(const char *data, const uint8_t *sender)
memcpy(&incomingData, data, sizeof(esp_now_payload_data_t));
if (incomingData.deviceType != ENDT_GATEWAY || myNet.macToString(gatewayMAC) != myNet.macToString(sender))
return;
StaticJsonDocument<sizeof(esp_now_payload_data_t::message)> json;
DynamicJsonDocument json(sizeof(esp_now_payload_data_t::message));
if (incomingData.payloadsType == ENPT_SET)
{
deserializeJson(json, incomingData.message);
relayStatus = json["set"] == payloadOn ? true : false;
if (relayPin)
digitalWrite(relayPin, relayPinType ? relayStatus : !relayStatus);
if (ledPin)
digitalWrite(ledPin, ledPinType ? relayStatus : !relayStatus);
saveConfig();
relayStatus = json["set"] == "ON" ? true : false;
if (config.relayPin)
{
if (config.workMode)
digitalWrite(config.relayPin, config.relayPinType ? !relayStatus : relayStatus);
else
digitalWrite(config.relayPin, config.relayPinType ? relayStatus : !relayStatus);
}
if (config.ledPin)
{
if (config.workMode)
digitalWrite(config.ledPin, config.ledPinType ? !relayStatus : relayStatus);
else
digitalWrite(config.ledPin, config.ledPinType ? relayStatus : !relayStatus);
}
saveStatus();
sendStatusMessage();
}
if (incomingData.payloadsType == ENPT_UPDATE)
@ -239,49 +254,59 @@ void onConfirmReceiving(const uint8_t *target, const uint16_t id, const bool sta
void loadConfig()
{
if (!LittleFS.exists("/config.json"))
ETS_GPIO_INTR_DISABLE();
EEPROM.begin(4096);
if (EEPROM.read(4095) == 254)
{
EEPROM.get(0, config);
EEPROM.end();
}
else
{
EEPROM.end();
saveConfig();
File file = LittleFS.open("/config.json", "r");
String jsonFile = file.readString();
StaticJsonDocument<512> json;
deserializeJson(json, jsonFile);
espnowNetName = json["espnowNetName"].as<String>();
deviceName = json["deviceName"].as<String>();
relayStatus = json["relayStatus"];
relayPin = json["relayPin"];
relayPinType = json["relayPinType"];
buttonPin = json["buttonPin"];
buttonPinType = json["buttonPinType"];
extButtonPin = json["extButtonPin"];
extButtonPinType = json["extButtonPinType"];
ledPin = json["ledPin"];
ledPinType = json["ledPinType"];
sensorPin = json["sensorPin"];
sensorType = json["sensorType"];
file.close();
}
delay(50);
ETS_GPIO_INTR_ENABLE();
}
void saveConfig()
{
StaticJsonDocument<512> json;
json["firmware"] = firmware;
json["espnowNetName"] = espnowNetName;
json["deviceName"] = deviceName;
json["relayStatus"] = relayStatus;
json["relayPin"] = relayPin;
json["relayPinType"] = relayPinType;
json["buttonPin"] = buttonPin;
json["buttonPinType"] = buttonPinType;
json["extButtonPin"] = extButtonPin;
json["extButtonPinType"] = extButtonPinType;
json["ledPin"] = ledPin;
json["ledPinType"] = ledPinType;
json["sensorPin"] = sensorPin;
json["sensorType"] = sensorType;
ETS_GPIO_INTR_DISABLE();
EEPROM.begin(4096);
EEPROM.write(4095, 254);
EEPROM.put(0, config);
EEPROM.end();
delay(50);
ETS_GPIO_INTR_ENABLE();
}
void loadStatus(void)
{
ETS_GPIO_INTR_DISABLE();
if (!LittleFS.exists("/status.json"))
saveStatus();
File file = LittleFS.open("/status.json", "r");
String jsonFile = file.readString();
DynamicJsonDocument json(64); // To calculate the buffer size uses https://arduinojson.org/v6/assistant.
deserializeJson(json, jsonFile);
relayStatus = json["status"];
file.close();
delay(50);
ETS_GPIO_INTR_ENABLE();
}
void saveStatus(void)
{
ETS_GPIO_INTR_DISABLE();
DynamicJsonDocument json(48); // To calculate the buffer size uses https://arduinojson.org/v6/assistant.
json["status"] = relayStatus;
json["system"] = "empty";
File file = LittleFS.open("/config.json", "w");
File file = LittleFS.open("/status.json", "w");
serializeJsonPretty(json, file);
file.close();
delay(50);
ETS_GPIO_INTR_ENABLE();
}
void setupWebServer()
@ -289,36 +314,57 @@ void setupWebServer()
webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send(LittleFS, "/index.htm"); });
webServer.on("/function.js", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send(LittleFS, "/function.js"); });
webServer.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send(LittleFS, "/style.css"); });
webServer.on("/setting", HTTP_GET, [](AsyncWebServerRequest *request)
{
relayPin = request->getParam("relayPin")->value().toInt();
relayPinType = request->getParam("relayPinType")->value().toInt();
buttonPin = request->getParam("buttonPin")->value().toInt();
buttonPinType = request->getParam("buttonPinType")->value().toInt();
extButtonPin = request->getParam("extButtonPin")->value().toInt();
extButtonPinType = request->getParam("extButtonPinType")->value().toInt();
ledPin = request->getParam("ledPin")->value().toInt();
ledPinType = request->getParam("ledPinType")->value().toInt();
sensorPin = request->getParam("sensorPin")->value().toInt();
sensorType = request->getParam("sensorType")->value().toInt();
deviceName = request->getParam("deviceName")->value();
espnowNetName = request->getParam("espnowNetName")->value();
config.relayPin = request->getParam("relayPin")->value().toInt();
config.relayPinType = request->getParam("relayPinType")->value().toInt();
config.buttonPin = request->getParam("buttonPin")->value().toInt();
config.buttonPinType = request->getParam("buttonPinType")->value().toInt();
config.extButtonPin = request->getParam("extButtonPin")->value().toInt();
config.extButtonPinType = request->getParam("extButtonPinType")->value().toInt();
config.ledPin = request->getParam("ledPin")->value().toInt();
config.ledPinType = request->getParam("ledPinType")->value().toInt();
config.sensorPin = request->getParam("sensorPin")->value().toInt();
config.sensorType = request->getParam("sensorType")->value().toInt();
config.workMode = request->getParam("workMode")->value().toInt();
config.deviceName = request->getParam("deviceName")->value();
config.espnowNetName = request->getParam("espnowNetName")->value();
request->send(200);
saveConfig(); });
webServer.on("/restart", HTTP_GET, [](AsyncWebServerRequest *request)
webServer.on("/config", HTTP_GET, [](AsyncWebServerRequest *request)
{
request->send(200);
String configJson;
DynamicJsonDocument json(384); // To calculate the buffer size uses https://arduinojson.org/v6/assistant.
json["firmware"] = firmware;
json["espnowNetName"] = config.espnowNetName;
json["deviceName"] = config.deviceName;
json["relayPin"] = config.relayPin;
json["relayPinType"] = config.relayPinType;
json["buttonPin"] = config.buttonPin;
json["buttonPinType"] = config.buttonPinType;
json["extButtonPin"] = config.extButtonPin;
json["extButtonPinType"] = config.extButtonPinType;
json["ledPin"] = config.ledPin;
json["ledPinType"] = config.ledPinType;
json["sensorPin"] = config.sensorPin;
json["sensorType"] = config.sensorType;
json["workMode"] = config.workMode;
serializeJsonPretty(json, configJson);
request->send(200, "application/json", configJson); });
webServer.on("/restart", HTTP_GET, [](AsyncWebServerRequest *request)
{request->send(200);
ESP.restart(); });
webServer.onNotFound([](AsyncWebServerRequest *request)
{
if (LittleFS.exists(request->url()))
request->send(LittleFS, request->url());
else
{
request->send(404, "text/plain", "File Not Found");
} });
{ request->send(404, "text/plain", "File Not Found"); });
webServer.begin();
}
@ -326,19 +372,29 @@ void setupWebServer()
void IRAM_ATTR buttonInterrupt()
{
ETS_GPIO_INTR_DISABLE();
buttonInterruptTimer.once_ms(100, switchingRelay); // For prevent contact chatter.
buttonInterruptTimer.once_ms(500, switchingRelay); // For prevent contact chatter.
}
void switchingRelay()
{
relayStatus = !relayStatus;
if (relayPin)
digitalWrite(relayPin, relayPinType ? relayStatus : !relayStatus);
if (ledPin)
digitalWrite(ledPin, ledPinType ? relayStatus : !relayStatus);
saveConfig();
sendStatusMessage();
ETS_GPIO_INTR_ENABLE();
relayStatus = !relayStatus;
if (config.relayPin)
{
if (config.workMode)
digitalWrite(config.relayPin, config.relayPinType ? !relayStatus : relayStatus);
else
digitalWrite(config.relayPin, config.relayPinType ? relayStatus : !relayStatus);
}
if (config.ledPin)
{
if (config.workMode)
digitalWrite(config.ledPin, config.ledPinType ? !relayStatus : relayStatus);
else
digitalWrite(config.ledPin, config.ledPinType ? relayStatus : !relayStatus);
}
saveStatus();
sendStatusMessage();
}
void sendAttributesMessage(const uint8_t type)
@ -352,7 +408,7 @@ void sendAttributesMessage(const uint8_t type)
uint32_t days = hours / 24;
esp_now_payload_data_t outgoingData{ENDT_SWITCH, ENPT_ATTRIBUTES};
espnow_message_t message;
StaticJsonDocument<sizeof(esp_now_payload_data_t::message)> json;
DynamicJsonDocument json(sizeof(esp_now_payload_data_t::message));
if (type == ENST_NONE)
json["Type"] = "ESP-NOW switch";
else
@ -391,25 +447,25 @@ void sendConfigMessage(const uint8_t type)
return;
esp_now_payload_data_t outgoingData{ENDT_SWITCH, ENPT_CONFIG};
espnow_message_t message;
StaticJsonDocument<sizeof(esp_now_payload_data_t::message)> json;
DynamicJsonDocument json(sizeof(esp_now_payload_data_t::message));
if (type == ENST_NONE)
{
json["name"] = deviceName;
json["unit"] = 1;
json["type"] = HACT_SWITCH;
json["class"] = HASWDC_SWITCH;
json["template"] = "state";
json["payload_on"] = payloadOn;
json["payload_off"] = payloadOff;
json[MCMT_DEVICE_NAME] = config.deviceName;
json[MCMT_DEVICE_UNIT] = 1;
json[MCMT_COMPONENT_TYPE] = HACT_SWITCH;
json[MCMT_DEVICE_CLASS] = HASWDC_SWITCH;
json[MCMT_VALUE_TEMPLATE] = "state";
}
if (type == ENST_DS18B20 || type == ENST_DHT11 || type == ENST_DHT22)
{
outgoingData.deviceType = ENDT_SENSOR;
json["name"] = deviceName + " temperature";
json["unit"] = 2;
json["type"] = HACT_SENSOR;
json["class"] = HASDC_TEMPERATURE;
json["template"] = "temperature";
json[MCMT_DEVICE_NAME] = config.deviceName + " temperature";
json[MCMT_DEVICE_UNIT] = 2;
json[MCMT_COMPONENT_TYPE] = HACT_SENSOR;
json[MCMT_DEVICE_CLASS] = HASDC_TEMPERATURE;
json[MCMT_VALUE_TEMPLATE] = "temperature";
json[MCMT_UNIT_OF_MEASUREMENT] = "°C";
json[MCMT_EXPIRE_AFTER] = 900;
}
serializeJsonPretty(json, outgoingData.message);
memcpy(&message.message, &outgoingData, sizeof(esp_now_payload_data_t));
@ -420,11 +476,13 @@ void sendConfigMessage(const uint8_t type)
if (type == ENST_DHT11 || type == ENST_DHT22)
{
outgoingData.deviceType = ENDT_SENSOR;
json["name"] = deviceName + " humidity";
json["unit"] = 3;
json["type"] = HACT_SENSOR;
json["class"] = HASDC_HUMIDITY;
json["template"] = "humidity";
json[MCMT_DEVICE_NAME] = config.deviceName + " humidity";
json[MCMT_DEVICE_UNIT] = 3;
json[MCMT_COMPONENT_TYPE] = HACT_SENSOR;
json[MCMT_DEVICE_CLASS] = HASDC_HUMIDITY;
json[MCMT_VALUE_TEMPLATE] = "humidity";
json[MCMT_UNIT_OF_MEASUREMENT] = "%";
json[MCMT_EXPIRE_AFTER] = 900;
serializeJsonPretty(json, outgoingData.message);
memcpy(&message.message, &outgoingData, sizeof(esp_now_payload_data_t));
@ -441,9 +499,9 @@ void sendStatusMessage(const uint8_t type)
statusMessageTimerSemaphore = false;
esp_now_payload_data_t outgoingData{ENDT_SWITCH, ENPT_STATE};
espnow_message_t message;
StaticJsonDocument<sizeof(esp_now_payload_data_t::message)> json;
DynamicJsonDocument json(sizeof(esp_now_payload_data_t::message));
if (type == ENST_NONE)
json["state"] = relayStatus ? payloadOn : payloadOff;
json["state"] = relayStatus ? "ON" : "OFF";
if (type == ENST_DS18B20)
{
outgoingData.deviceType = ENDT_SENSOR;