[LED] Refactor LED handling (#2051)

Refactor LED handling into a library
Use a task instead of relying on the loop for precise timing

Co-authored-by: Florian <1technophile@users.noreply.github.com>
This commit is contained in:
FlorianandFlorian authored and GitHub committed 2024-09-13 09:55:56 -05:00
1 parent 20af9ccf11
commit 435b8ca3d9
14 files changed
+932 -437

No files matched your search

+75 -251
View File
@@ -434,260 +434,84 @@ ss_cnt_parameters cnt_parameters_array[cnt_parameters_array_size] = {
# define ota_timeout_millis 30000
#endif
/*-------------ERRORS, INFOS, SEND RECEIVE Display through LED----------------*/
#ifndef RGB_INDICATORS // Management of Errors, reception/emission and informations indicators with basic LED
/*-------------DEFINE PINs FOR STATUS LEDs----------------*/
# ifndef LED_SEND_RECEIVE
# ifdef ESP8266
//# define LED_SEND_RECEIVE 40
# elif ESP32
//# define LED_SEND_RECEIVE 40
# endif
# endif
# ifndef LED_SEND_RECEIVE_ON
# define LED_SEND_RECEIVE_ON HIGH
# endif
# ifndef LED_ERROR
# ifdef ESP8266
//# define LED_ERROR 42
# elif ESP32
//# define LED_ERROR 42
# endif
# endif
# ifndef LED_ERROR_ON
# define LED_ERROR_ON HIGH
# endif
# ifndef RGB_LED_ON_ON
# define RGB_LED_ON_ON HIGH
# endif
# ifndef LED_INFO
# ifdef ESP8266
//# define LED_INFO 44
# elif ESP32
//# define LED_INFO 44
# endif
# endif
# ifndef LED_INFO_ON
# define LED_INFO_ON HIGH
# endif
# ifdef RGB_LED_ON
# define SetupIndicatorError() \
pinMode(RGB_LED_ON, OUTPUT);
# define ONIndicatorON() digitalWrite(RGB_LED_ON, RGB_LED_ON_ON)
# else
# define ONIndicatorON()
# endif
# ifdef LED_ERROR
# define SetupIndicatorError() \
pinMode(LED_ERROR, OUTPUT); \
ErrorIndicatorOFF();
# define ErrorIndicatorON() digitalWrite(LED_ERROR, LED_ERROR_ON)
# define ErrorIndicatorOFF() digitalWrite(LED_ERROR, !LED_ERROR_ON)
# else
# define SetupIndicatorError()
# define ErrorIndicatorON()
# define ErrorIndicatorOFF()
# endif
# ifdef LED_SEND_RECEIVE
# define SetupIndicatorSendReceive() \
pinMode(LED_SEND_RECEIVE, OUTPUT); \
SendReceiveIndicatorOFF();
# define SendReceiveIndicatorON() digitalWrite(LED_SEND_RECEIVE, LED_SEND_RECEIVE_ON)
# define SendReceiveIndicatorOFF() digitalWrite(LED_SEND_RECEIVE, !LED_SEND_RECEIVE_ON)
# else
# define SetupIndicatorSendReceive()
# define SendReceiveIndicatorON()
# define SendReceiveIndicatorOFF()
# endif
# ifdef LED_INFO
# define SetupIndicatorInfo() \
pinMode(LED_INFO, OUTPUT); \
InfoIndicatorOFF();
# define InfoIndicatorON() digitalWrite(LED_INFO, LED_INFO_ON)
# define InfoIndicatorOFF() digitalWrite(LED_INFO, !LED_INFO_ON)
# else
# define SetupIndicatorInfo()
# define InfoIndicatorON()
# define InfoIndicatorOFF()
# endif
# define CriticalIndicatorON() // Not used
# define PowerIndicatorON() // Not used
# define PowerIndicatorOFF() // Not used
# define SetupIndicators() // Not used
#else // Management of Errors, reception/emission and informations indicators with RGB LED
# include <Adafruit_NeoPixel.h>
# ifndef ANEOPIX_IND_TYPE // needs library constants
# define ANEOPIX_IND_TYPE NEO_GRB + NEO_KHZ800 // ws2812 and alike
# endif
Adafruit_NeoPixel leds(ANEOPIX_IND_NUM_LEDS, ANEOPIX_IND_DATA_GPIO, ANEOPIX_IND_TYPE);
# ifdef ANEOPIX_IND_DATA_GPIO2 // Only used for Critical Indicator
// assume the same LED type
Adafruit_NeoPixel leds2(ANEOPIX_IND_NUM_LEDS, ANEOPIX_IND_DATA_GPIO2, ANEOPIX_IND_TYPE);
# endif
# ifdef ANEOPIX_IND_DATA_GPIO3
// assume the same LED type
Adafruit_NeoPixel leds3(ANEOPIX_IND_NUM_LEDS, ANEOPIX_IND_DATA_GPIO3, ANEOPIX_IND_TYPE);
# endif
// LED index depending on state, each state can have a different LED index or be grouped if there is a limited number of LEDs
#ifndef LED_ERROR
# define LED_ERROR 0
#endif
#ifndef LED_PROCESSING
# define LED_PROCESSING 0
#endif
#ifndef LED_BROKER
# define LED_BROKER 0
#endif
#ifndef LED_NETWORK
# define LED_NETWORK 0
#endif
#ifndef LED_POWER
# define LED_POWER -1
#endif
# ifndef RGB_LED_POWER
# define RGB_LED_POWER -1 // If the RGB Led is linked to GPIO pin for power define it here
// Single standard LED pin
#ifndef LED_PIN
# ifdef LED_BUILTIN
# define LED_PIN LED_BUILTIN
# endif
# ifndef ANEOPIX_BRIGHTNESS
# define ANEOPIX_BRIGHTNESS 20 // Set Default maximum RGB brightness to approx 10% (0-255 scale)
#endif
#ifndef LED_PIN_ON
# define LED_PIN_ON HIGH
#endif
#ifndef LED_ACTUATOR_ONOFF
# ifdef LED_BUILTIN
# define LED_ACTUATOR_ONOFF LED_BUILTIN
# endif
# ifndef DEFAULT_ADJ_BRIGHTNESS
# define DEFAULT_ADJ_BRIGHTNESS 255 // Set Default RGB adjustable brightness
# endif
# ifndef ANEOPIX_COLOR_SCHEME // allow for different color combinations
# define ANEOPIX_COLOR_SCHEME 0
# endif
// Allow to set LED used (for example thingpulse gateway has 4 we use them independently)
# ifndef ANEOPIX_ON_LED
# define ANEOPIX_ON_LED 0 // First Led
# endif
# ifndef ANEOPIX_INFO_LED
# define ANEOPIX_INFO_LED 0 // First Led
# endif
# ifndef ANEOPIX_SEND_RECEIVE_LED
# define ANEOPIX_SEND_RECEIVE_LED 0 // First Led
# endif
# ifndef ANEOPIX_ERROR_LED
# define ANEOPIX_ERROR_LED 0 // First Led
# endif
# ifndef ANEOPIX_CRITICAL_LED
# define ANEOPIX_CRITICAL_LED 0 // First Led
# endif
// compile time calculation of color values
# define ANEOPIX_RED ((0xFF * ANEOPIX_BRIGHTNESS) >> 8) << 16
# define ANEOPIX_RED_DIM ((0x3F * ANEOPIX_BRIGHTNESS) >> 8) << 16 // dimmed /4
# define ANEOPIX_ORANGE (((0xFF * ANEOPIX_BRIGHTNESS) >> 8) << 16) | \
(((0xA5 * ANEOPIX_BRIGHTNESS) >> 8) << 8)
# define ANEOPIX_GOLD (((0xFF * ANEOPIX_BRIGHTNESS) >> 8) << 16) | \
(((0xD7 * ANEOPIX_BRIGHTNESS) >> 8) << 8)
# define ANEOPIX_GREEN ((0xFF * ANEOPIX_BRIGHTNESS) >> 8) << 8
# define ANEOPIX_GREEN_DIM ((0x3F * ANEOPIX_BRIGHTNESS) >> 8) << 8 // dimmed /4
# define ANEOPIX_AQUA (((0xFF * ANEOPIX_BRIGHTNESS) >> 8) << 8) | \
(0xFF * ANEOPIX_BRIGHTNESS) >> 8
# define ANEOPIX_BLUE (0xFF * ANEOPIX_BRIGHTNESS) >> 8
# define ANEOPIX_BLUE_DIM (0x3F * ANEOPIX_BRIGHTNESS) >> 8 // dimmed /4
# define ANEOPIX_BLACK 0
#endif
# if ANEOPIX_COLOR_SCHEME == 0
// original color combination remains default
# define ANEOPIX_INFO ANEOPIX_GREEN
# define ANEOPIX_ERROR ANEOPIX_ORANGE
# define ANEOPIX_SENDRECEIVE ANEOPIX_BLUE
# define ANEOPIX_CRITICAL ANEOPIX_RED // second led
# define ANEOPIX_POWER ANEOPIX_GREEN // second led
# define ANEOPIX_BOOT ANEOPIX_BLACK // unused
# define ANEOPIX_OFF ANEOPIX_BLACK
// color combinations tested for good visibility of onboard leds
# elif ANEOPIX_COLOR_SCHEME == 1
# define ANEOPIX_INFO ANEOPIX_GREEN_DIM // dimmed green info background
# define ANEOPIX_ERROR ANEOPIX_RED_DIM
# define ANEOPIX_SENDRECEIVE ANEOPIX_GOLD // bright gold = sending
# define ANEOPIX_CRITICAL ANEOPIX_BLACK // unused
# define ANEOPIX_POWER ANEOPIX_BLACK // unused
# define ANEOPIX_BOOT ANEOPIX_AQUA
# define ANEOPIX_OFF ANEOPIX_BLACK
# else
# define ANEOPIX_INFO ANEOPIX_BLUE_DIM // dimmed blue info background
# define ANEOPIX_ERROR ANEOPIX_RED_DIM
# define ANEOPIX_SENDRECEIVE ANEOPIX_GOLD // bright gold = sending
# define ANEOPIX_CRITICAL ANEOPIX_BLACK // unused
# define ANEOPIX_POWER ANEOPIX_BLACK // unused
# define ANEOPIX_BOOT ANEOPIX_AQUA
# define ANEOPIX_OFF ANEOPIX_BLACK
# endif
# if !defined(ANEOPIX_IND_DATA_GPIO2) && !defined(ANEOPIX_IND_DATA_GPIO3)
// during boot the RGB LED is on to signal also reboots
# define SetupIndicators() \
if (RGB_LED_POWER > -1) { \
pinMode(RGB_LED_POWER, OUTPUT); \
digitalWrite(RGB_LED_POWER, HIGH); \
} \
leds.begin(); \
leds.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_BOOT); \
leds.show();
# elif defined(ANEOPIX_IND_DATA_GPIO2) && !defined(ANEOPIX_IND_DATA_GPIO3)
# define SetupIndicators() \
if (RGB_LED_POWER > -1) { \
pinMode(RGB_LED_POWER, OUTPUT); \
digitalWrite(RGB_LED_POWER, HIGH); \
} \
leds.begin(); \
leds2.begin();
# else
# define SetupIndicators() \
if (RGB_LED_POWER > -1) { \
pinMode(RGB_LED_POWER, OUTPUT); \
digitalWrite(RGB_LED_POWER, HIGH); \
} \
leds.begin(); \
leds2.begin(); \
leds3.begin();
# endif
# ifndef RGB_LED_ERROR
# define RGB_LED_ERROR leds
# endif
# ifndef RGB_LED_SR
# define RGB_LED_SR leds
# endif
# ifndef RGB_LED_INFO
# define RGB_LED_INFO leds
# endif
# ifndef RGB_LED_ON
# define RGB_LED_ON leds
# endif
# define ONIndicatorON() \
RGB_LED_ON.setPixelColor(ANEOPIX_ON_LED, ANEOPIX_POWER); \
RGB_LED_ON.setBrightness(SYSConfig.rgbbrightness); \
RGB_LED_ON.show();
# define ErrorIndicatorON() \
RGB_LED_ERROR.setPixelColor(ANEOPIX_ERROR_LED, ANEOPIX_ERROR); \
RGB_LED_ERROR.setBrightness(SYSConfig.rgbbrightness); \
RGB_LED_ERROR.show();
# define ErrorIndicatorOFF() \
RGB_LED_ERROR.setPixelColor(ANEOPIX_ERROR_LED, ANEOPIX_OFF); \
RGB_LED_ERROR.show();
# define SendReceiveIndicatorON() \
RGB_LED_SR.setPixelColor(ANEOPIX_SEND_RECEIVE_LED, ANEOPIX_SENDRECEIVE); \
RGB_LED_SR.setBrightness(SYSConfig.rgbbrightness); \
RGB_LED_SR.show();
# define SendReceiveIndicatorOFF() \
RGB_LED_SR.setPixelColor(ANEOPIX_SEND_RECEIVE_LED, ANEOPIX_OFF); \
RGB_LED_SR.show();
# define InfoIndicatorON() \
RGB_LED_INFO.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_INFO); \
RGB_LED_INFO.setBrightness(SYSConfig.rgbbrightness); \
RGB_LED_INFO.show();
# define InfoIndicatorOFF() \
RGB_LED_INFO.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_OFF); \
RGB_LED_INFO.show();
# ifdef ANEOPIX_IND_DATA_GPIO2 // Used for relay power indicator
// For the critical ON indicator there is no method to turn it off, the only way is to unplug the device
// This enable to have persistence of the indicator to inform the user
# ifndef LED_CRITICAL
# define LED_CRITICAL leds2
# endif
# ifndef LED_POWER
# define LED_POWER leds2
# endif
# define CriticalIndicatorON() \
LED_CRITICAL.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_CRITICAL); \
LED_CRITICAL.setBrightness(255); \
LED_CRITICAL.show();
# define PowerIndicatorON() \
LED_POWER.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_INFO); \
LED_POWER.setBrightness(SYSConfig.rgbbrightness); \
LED_POWER.show();
# define PowerIndicatorOFF() \
LED_POWER.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_OFF); \
LED_POWER.show();
# endif
# define SetupIndicatorInfo()
# define SetupIndicatorSendReceive()
# define SetupIndicatorError()
// TODO adapt to other boards
#ifndef DEFAULT_ADJ_BRIGHTNESS
# define DEFAULT_ADJ_BRIGHTNESS 255 // Set Default RGB adjustable brightness
#endif
#ifndef LED_POWER_COLOR
# define LED_POWER_COLOR 0x00FF00 // Green
#endif
#ifndef LED_PROCESSING_COLOR
# define LED_PROCESSING_COLOR 0x0000FF // Blue
#endif
#ifndef LED_WAITING_ONBOARD_COLOR
# define LED_WAITING_ONBOARD_COLOR 0xFFA500 // Orange
#endif
#ifndef LED_ONBOARD_COLOR
# define LED_ONBOARD_COLOR 0xFFFF00 // Yellow
#endif
#ifndef LED_NETWORK_OK_COLOR
# define LED_NETWORK_OK_COLOR 0x00FF00 // Green
#endif
#ifndef LED_NETWORK_ERROR_COLOR
# define LED_NETWORK_ERROR_COLOR 0xFFA500 // Orange
#endif
#ifndef LED_BROKER_OK_COLOR
# define LED_BROKER_OK_COLOR 0x00FF00 // Green
#endif
#ifndef LED_BROKER_ERROR_COLOR
# define LED_BROKER_ERROR_COLOR 0xFFA500 // Orange
#endif
#ifndef LED_OFFLINE_COLOR
# define LED_OFFLINE_COLOR 0x0000FF // Blue
#endif
#ifndef LED_OTA_LOCAL_COLOR
# define LED_OTA_LOCAL_COLOR 0xFF00FF // Magenta
#endif
#ifndef LED_OTA_REMOTE_COLOR
# define LED_OTA_REMOTE_COLOR 0x8000FF // Purple
#endif
#ifndef LED_ERROR_COLOR
# define LED_ERROR_COLOR 0xFF0000 // Red
#endif
#ifndef LED_ACTUATOR_ONOFF_COLOR
# define LED_ACTUATOR_ONOFF_COLOR 0x00FF00 // Green
#endif
#ifndef LED_COLOR_BLACK
# define LED_COLOR_BLACK 0x000000
#endif
#ifdef ESP8266
@@ -827,7 +651,7 @@ struct SYSConfig_s {
bool offline;
bool discovery; // HA discovery convention
bool ohdiscovery; // OH discovery specificities
#ifdef RGB_INDICATORS
#ifdef LED_ADDRESSABLE
int rgbbrightness; // brightness of the RGB LED
#endif
enum PowerMode powerMode;
+22 -10
View File
@@ -100,11 +100,13 @@ void ONOFFConfig_load(){};
# endif
void updatePowerIndicator() {
# ifdef LED_ACTUATOR_ONOFF
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) {
PowerIndicatorON();
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ACTUATOR_ONOFF_COLOR);
} else {
PowerIndicatorOFF();
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_COLOR_BLACK);
}
# endif
}
void setupONOFF() {
@@ -142,11 +144,13 @@ void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) {
Log.notice(F("GPIO number: %d" CR), gpio);
pinMode(gpio, OUTPUT);
digitalWrite(gpio, boolSWITCHTYPE);
# ifdef LED_ACTUATOR_ONOFF
if (boolSWITCHTYPE == ACTUATOR_ON) {
PowerIndicatorON();
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ACTUATOR_ONOFF_COLOR);
} else {
PowerIndicatorOFF();
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_COLOR_BLACK);
}
# endif
# ifdef ESP32
if (ONOFFConfig.useLastStateOnStart) {
ONOFFdata["save"] = true;
@@ -221,11 +225,13 @@ void MQTTtoONOFF(char* topicOri, char* datacallback) {
ON = false;
digitalWrite(gpio, ON);
# ifdef LED_ACTUATOR_ONOFF
if (ON == ACTUATOR_ON) {
PowerIndicatorON();
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ACTUATOR_ONOFF_COLOR);
} else {
PowerIndicatorOFF();
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_COLOR_BLACK);
}
# endif
// we acknowledge the sending by publishing the value to an acknowledgement topic
char b = ON;
pub(subjectGTWONOFFtoMQTT, &b);
@@ -246,7 +252,9 @@ void overLimitTemp(void* pvParameters) {
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { // This could be with the previous condition, but it is better to trigger the digitalRead only if the previous condition is met to avoid the digitalRead
Log.error(F("[ActuatorONOFF] OverTemperature detected ( %F > %F ) switching OFF Actuator" CR), internalTempc, MAX_TEMP_ACTUATOR);
ActuatorTrigger();
CriticalIndicatorON();
# ifdef LED_ACTUATOR_ONOFF
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ERROR_COLOR, -1);
# endif
}
}
previousInternalTempc = internalTempc;
@@ -266,7 +274,9 @@ void overLimitCurrent(float RN8209current) {
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { // This could be with the previous condition, but it is better to trigger the digitalRead only if the previous condition is met to avoid the digitalRead
Log.error(F("[ActuatorONOFF] OverCurrent detected ( %F > %F ) switching OFF Actuator" CR), RN8209current, MAX_CURRENT_ACTUATOR);
ActuatorTrigger();
CriticalIndicatorON();
# ifdef LED_ACTUATOR_ONOFF
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ERROR_COLOR, -1);
# endif
}
}
RN8209previousCurrent = RN8209current;
@@ -284,11 +294,13 @@ void ActuatorTrigger() {
uint8_t level = !digitalRead(ACTUATOR_ONOFF_GPIO);
Log.trace(F("Actuator triggered %d" CR), level);
digitalWrite(ACTUATOR_ONOFF_GPIO, level);
# ifdef LED_ACTUATOR_ONOFF
if (level == ACTUATOR_ON) {
PowerIndicatorON();
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ACTUATOR_ONOFF_COLOR);
} else {
PowerIndicatorOFF();
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_COLOR_BLACK);
}
# endif
# ifdef ESP32
if (ONOFFConfig.useLastStateOnStart) {
-1
View File
@@ -203,6 +203,5 @@ void M5Print(char* line1, char* line2, char* line3) {
M5.Lcd.drawString(line2, 5, M5.Lcd.height() * 0.8, 1);
M5.Lcd.drawString(line3, 5, M5.Lcd.height() * 0.9, 1);
delay(2000);
InfoIndicatorOFF(); // to switch off no need of condition
}
#endif
+7 -2
View File
@@ -53,8 +53,13 @@ void testDevice() {
void testLeds() {
Log.notice(F("LED Test" CR));
InfoIndicatorON();
SendReceiveIndicatorON();
ledManager.setMode(0, 0, LEDManager::Mode::STATIC, LED_NETWORK_OK_COLOR, -1);
delay(1000);
ledManager.setMode(0, 1, LEDManager::Mode::STATIC, LED_NETWORK_OK_COLOR, -1);
delay(1000);
ledManager.setMode(0, 2, LEDManager::Mode::STATIC, LED_NETWORK_OK_COLOR, -1);
delay(1000);
ledManager.setMode(0, 3, LEDManager::Mode::STATIC, LED_NETWORK_OK_COLOR, -1);
Log.notice(F("LED Test Finished" CR));
}
+1 -1
View File
@@ -557,7 +557,7 @@ void pubMqttDiscovery() {
stateClassNone, //State Class
"false", "true" //state_off, state_on
);
# ifdef RGB_INDICATORS
# ifdef LED_ADDRESSABLE
createDiscovery("number", //set Type
subjectSYStoMQTT, "SYS: LED Brightness", (char*)getUniqueId("rgbb", "").c_str(), //set state_topic,name,uniqueId
will_Topic, "", "{{ (value_json.rgbb/2.55) | round(0) }}", //set availability_topic,device_class,value_template,
-2
View File
@@ -64,8 +64,6 @@ void MeasureGPIOInput() {
resetTime = millis();
} else if ((millis() - resetTime) > 3000) {
Log.trace(F("Button Held" CR));
InfoIndicatorOFF();
SendReceiveIndicatorOFF();
// Switching off the relay during reset or failsafe operations
# ifdef ZactuatorONOFF
uint8_t level = digitalRead(ACTUATOR_ONOFF_GPIO);
+5 -5
View File
@@ -1937,7 +1937,7 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {
// Queue completed message
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
Log.warning(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
free(message);
} else {
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
@@ -2003,7 +2003,7 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {
// Queue completed message
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
Log.warning(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
free(message);
} else {
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
@@ -2331,7 +2331,7 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {
line4.toCharArray(message->line4, WEBUI_TEXT_WIDTH);
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
Log.warning(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
free(message);
} else {
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
@@ -2389,7 +2389,7 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {
// Queue completed message
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
Log.warning(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
free(message);
} else {
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
@@ -2441,7 +2441,7 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {
// Queue completed message
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
Log.warning(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
free(message);
} else {
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
+159 -69
View File
@@ -38,7 +38,8 @@ enum GatewayState {
BROKER_DISCONNECTED,
LOCAL_OTA_IN_PROGRESS,
REMOTE_OTA_IN_PROGRESS,
SLEEPING
SLEEPING,
ERROR
};
GatewayState gatewayState = GatewayState::WAITING_ONBOARDING;
@@ -86,8 +87,11 @@ bool ready_to_sleep = false;
#include <memory>
#include "LEDManager.h"
#include "TheengsUtils.h"
LEDManager ledManager;
struct JsonBundle {
StaticJsonDocument<JSON_MSG_BUFFER> doc;
};
@@ -382,6 +386,8 @@ void Config_update(JsonObject& data, const char* key, T& var) {
bool jsonDispatch(JsonObject& data) {
bool res = false;
if (data.containsKey("origin")) {
GatewayState previousGatewayState = gatewayState;
gatewayState = GatewayState::PROCESSING;
#if message_UTCtimestamp == true
data["UTCtime"] = TheengsUtils::UTCtimestamp();
#endif
@@ -405,8 +411,10 @@ bool jsonDispatch(JsonObject& data) {
res = true;
}
#endif
gatewayState = previousGatewayState; // restore the previous state
} else {
Log.error(F("No origin in JSON filtered" CR));
gatewayState = GatewayState::ERROR;
}
return res;
}
@@ -416,6 +424,7 @@ boolean enqueueJsonObject(const StaticJsonDocument<JSON_MSG_BUFFER>& jsonDoc, in
receivedMessages++;
if (jsonDoc.size() == 0) {
Log.error(F("Empty JSON, skipping" CR));
gatewayState = GatewayState::ERROR;
return true;
}
if (queueLength >= QueueSize) {
@@ -430,6 +439,7 @@ boolean enqueueJsonObject(const StaticJsonDocument<JSON_MSG_BUFFER>& jsonDoc, in
// Semaphore check before enqueueing a document
if (xSemaphoreTake(xQueueMutex, pdMS_TO_TICKS(timeout)) == pdFALSE) {
Log.error(F("xQueueMutex not taken" CR));
gatewayState = GatewayState::ERROR;
blockedMessages++;
return false;
}
@@ -474,6 +484,7 @@ std::string generateHash(const std::string& input) {
void buildTopicFromId(JsonObject& Jsondata, const char* origin) {
if (!Jsondata.containsKey("id")) {
Log.error(F("No id in Jsondata" CR));
gatewayState = GatewayState::ERROR;
return;
}
@@ -491,6 +502,7 @@ void buildTopicFromId(JsonObject& Jsondata, const char* origin) {
topic = Jsondata["uuid"].as<std::string>();
} else {
Log.error(F("No uuid in Jsondata" CR));
gatewayState = GatewayState::ERROR;
}
}
@@ -520,6 +532,7 @@ void emptyQueue() {
#ifdef ESP32
if (xSemaphoreTake(xQueueMutex, pdMS_TO_TICKS(QueueSemaphoreTimeOutTask)) == pdFALSE) {
Log.error(F("xQueueMutex not taken" CR));
gatewayState = GatewayState::ERROR;
return;
}
#endif
@@ -530,6 +543,7 @@ void emptyQueue() {
#endif
if (error) {
Log.error(F("deserialize jsonQueue.front() failed: %s, buffer capacity: %u" CR), error.c_str(), jsonBuffer.capacity());
gatewayState = GatewayState::ERROR;
} else {
if (jsonDispatch(obj))
queueLengthSum++;
@@ -566,6 +580,7 @@ bool pub(const char* topicori, JsonObject& data) {
}
if (data.size() == 0) {
Log.error(F("Empty JSON, not published" CR));
gatewayState = GatewayState::ERROR;
return res;
}
String topic = String(mqtt_topic) + String(gateway_name) + String(topicori);
@@ -662,11 +677,11 @@ bool pubMQTT(const char* topic, const char* payload, bool retainFlag) {
#ifdef ESP32
if (xSemaphoreTake(xMqttMutex, pdMS_TO_TICKS(QueueSemaphoreTimeOutTask)) == pdFALSE) {
Log.error(F("xMqttMutex not taken" CR));
gatewayState = GatewayState::ERROR;
return res;
}
#endif
if (mqtt && mqtt->connected()) {
SendReceiveIndicatorON();
Log.notice(F("[ OMG->MQTT ] topic: %s msg: %s " CR), topic, payload);
res = mqtt->publish(topic, payload, 0, retainFlag);
} else {
@@ -784,7 +799,7 @@ void SYSConfig_init() {
SYSConfig.discovery = DEFAULT_DISCOVERY;
SYSConfig.ohdiscovery = OpenHABDiscovery;
#endif
#ifdef RGB_INDICATORS
#ifdef LED_ADDRESSABLE
SYSConfig.rgbbrightness = DEFAULT_ADJ_BRIGHTNESS;
#endif
SYSConfig.powerMode = DEFAULT_LOW_POWER_MODE;
@@ -798,7 +813,7 @@ void SYSConfig_fromJson(JsonObject& SYSdata) {
Config_update(SYSdata, "disc", SYSConfig.discovery);
Config_update(SYSdata, "ohdisc", SYSConfig.ohdiscovery);
#endif
#ifdef RGB_INDICATORS
#ifdef LED_ADDRESSABLE
Config_update(SYSdata, "rgbb", SYSConfig.rgbbrightness);
#endif
Config_update(SYSdata, "powermode", SYSConfig.powerMode);
@@ -816,7 +831,7 @@ void SYSConfig_save() {
SYSdata["disc"] = SYSConfig.discovery;
SYSdata["ohdisc"] = SYSConfig.ohdiscovery;
# endif
# ifdef RGB_INDICATORS
# ifdef LED_ADDRESSABLE
SYSdata["rgbb"] = SYSConfig.rgbbrightness;
# endif
String conf = "";
@@ -855,6 +870,7 @@ void SYSConfig_load() {
preferences.end();
if (error) {
Log.error(F("SYS config deserialization failed: %s, buffer capacity: %u" CR), error.c_str(), jsonBuffer.capacity());
gatewayState = GatewayState::ERROR;
return;
}
if (jsonBuffer.isNull()) {
@@ -878,7 +894,7 @@ std::pair<String, uint16_t> discoverMQTTbroker() {
Log.trace(F("Browsing for MQTT service" CR));
int n = MDNS.queryService("mqtt", "tcp");
if (n == 0) {
Log.error(F("no services found" CR));
Log.warning(F("no services found" CR));
} else {
Log.trace(F("%d service(s) found" CR), n);
for (int i = 0; i < n; ++i) {
@@ -889,7 +905,7 @@ std::pair<String, uint16_t> discoverMQTTbroker() {
Log.trace(F("One MQTT server found setting parameters" CR));
return {MDNS.IP(0).toString(), uint16_t(MDNS.port(0))};
} else {
Log.error(F("Several MQTT servers found, please deactivate mDNS and set your default server" CR));
Log.warning(F("Several MQTT servers found, please deactivate mDNS and set your default server" CR));
}
}
return {"", 0};
@@ -1043,6 +1059,7 @@ void setupMQTT() {
if (cnt_parameters_backup) {
// this was the first attempt to connect to a new server and it failed, revert to old settings
Log.error(F("MQTT connection failed, reverting to previous settings" CR));
gatewayState = GatewayState::ERROR;
cnt_parameters_array[cnt_index] = cnt_parameters_backup->parameters;
cnt_index = cnt_parameters_backup->cnt_index;
mqttSetupPending = true;
@@ -1051,10 +1068,7 @@ void setupMQTT() {
return;
}
ErrorIndicatorON();
delayWithOTA(5000);
ErrorIndicatorOFF();
delayWithOTA(5000);
delayWithOTA(10000);
if (failure_number_mqtt > maxRetryWatchDog) {
# ifndef ESPWifiManualSetup
@@ -1114,12 +1128,14 @@ void setESPWifiProtocolTxPower() {
# if WifiGMode == true
if (esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G) != ESP_OK) {
Log.error(F("Failed to change WifiMode." CR));
gatewayState = GatewayState::ERROR;
}
# endif
# if WifiGMode == false
if (esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N) != ESP_OK) {
Log.error(F("Failed to change WifiMode." CR));
gatewayState = GatewayState::ERROR;
}
# endif
@@ -1153,12 +1169,14 @@ void setESPWifiProtocolTxPower() {
# if WifiGMode == true
if (!wifi_set_phy_mode(PHY_MODE_11G)) {
Log.error(F("Failed to change WifiMode." CR));
gatewayState = GatewayState::ERROR;
}
# endif
# if WifiGMode == false
if (!wifi_set_phy_mode(PHY_MODE_11N)) {
Log.error(F("Failed to change WifiMode." CR));
gatewayState = GatewayState::ERROR;
}
# endif
@@ -1190,6 +1208,88 @@ void setESPWifiProtocolTxPower() {
}
#endif
#ifdef ESP32
void updateAndHandleLEDsTask(void* pvParameters) {
for (;;) {
updateAndHandleLEDsTask();
vTaskDelay(pdMS_TO_TICKS(100));
}
}
#endif
void updateAndHandleLEDsTask() {
static GatewayState previousGatewayState;
if (previousGatewayState != gatewayState) {
#ifdef LED_POWER
ledManager.setMode(0, LED_POWER, LEDManager::STATIC, LED_POWER_COLOR, -1);
#endif
switch (gatewayState) {
case PROCESSING:
#ifdef LED_PROCESSING
ledManager.setMode(0, LED_PROCESSING, LEDManager::BLINK, LED_PROCESSING_COLOR, 3);
#endif
break;
case WAITING_ONBOARDING:
#ifdef LED_BROKER
ledManager.setMode(0, LED_BROKER, LEDManager::STATIC, LED_WAITING_ONBOARD_COLOR, -1);
#endif
break;
case ONBOARDING:
#ifdef LED_BROKER
ledManager.setMode(0, LED_BROKER, LEDManager::STATIC, LED_ONBOARD_COLOR, -1);
#endif
break;
case NTWK_CONNECTED:
#ifdef LED_NETWORK
ledManager.setMode(0, LED_NETWORK, LEDManager::STATIC, LED_NETWORK_OK_COLOR, -1);
#endif
break;
case BROKER_CONNECTED:
#ifdef LED_BROKER
ledManager.setMode(0, LED_BROKER, LEDManager::STATIC, LED_BROKER_OK_COLOR, -1);
#endif
break;
case NTWK_DISCONNECTED:
#ifdef LED_NETWORK
ledManager.setMode(0, LED_NETWORK, LEDManager::BLINK, LED_NETWORK_ERROR_COLOR, -1);
#endif
break;
case BROKER_DISCONNECTED:
#ifdef LED_BROKER
ledManager.setMode(0, LED_BROKER, LEDManager::BLINK, LED_BROKER_ERROR_COLOR, -1);
#endif
break;
case SLEEPING:
ledManager.setMode(0, -1, LEDManager::OFF, 0, -1);
break;
case OFFLINE:
#ifdef LED_NETWORK
ledManager.setMode(0, LED_NETWORK, LEDManager::BLINK, LED_OFFLINE_COLOR, -1);
#endif
break;
case LOCAL_OTA_IN_PROGRESS:
#ifdef LED_PROCESSING
ledManager.setMode(0, LED_PROCESSING, LEDManager::BLINK, LED_OTA_LOCAL_COLOR, -1);
#endif
break;
case REMOTE_OTA_IN_PROGRESS:
#ifdef LED_PROCESSING
ledManager.setMode(0, LED_PROCESSING, LEDManager::BLINK, LED_OTA_REMOTE_COLOR, -1);
#endif
break;
case ERROR:
#ifdef LED_ERROR
ledManager.setMode(0, LED_ERROR, LEDManager::BLINK, LED_ERROR_COLOR, 3);
#endif
break;
default:
break;
}
previousGatewayState = gatewayState;
}
ledManager.update();
}
void setup() {
//Launch serial for debugging purposes
Serial.begin(SERIAL_BAUD);
@@ -1208,12 +1308,17 @@ void setup() {
if (SYSConfig.offline)
gatewayState = GatewayState::OFFLINE;
//setup LED status
SetupIndicatorError();
SetupIndicatorSendReceive();
SetupIndicatorInfo();
SetupIndicators(); // For RGB Leds
ONIndicatorON();
#ifdef LED_ADDRESSABLE
# ifdef LED_ADDRESSABLE_PIN1
ledManager.addLEDStrip(LED_ADDRESSABLE_PIN1, LED_ADDRESSABLE_NUM);
# endif
# ifdef LED_ADDRESSABLE_PIN2
ledManager.addLEDStrip(LED_ADDRESSABLE_PIN2, LED_ADDRESSABLE_NUM);
# endif
ledManager.setBrightness(SYSConfig.rgbbrightness);
#elif LED_PIN
ledManager.addLEDStrip(LED_PIN, 1);
#endif
#ifdef ESP8266
# ifndef ZgatewaySRFB // if we are not in sonoff rf bridge case we apply the ESP8266 GPIO optimization
@@ -1221,6 +1326,7 @@ void setup() {
Serial.begin(SERIAL_BAUD, SERIAL_8N1, SERIAL_TX_ONLY); // enable on ESP8266 to free some pin
# endif
#elif ESP32
xTaskCreate(updateAndHandleLEDsTask, "updateAndHandleLEDsTask", 2500, NULL, 1, NULL);
xQueueMutex = xSemaphoreCreateMutex();
xMqttMutex = xSemaphoreCreateMutex();
# if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH)
@@ -1239,6 +1345,7 @@ void setup() {
gpio_num_t wake_pin0 = static_cast<gpio_num_t>(ESP32_EXT0_WAKE_PIN);
if (esp_sleep_enable_ext0_wakeup(wake_pin0, ESP32_EXT0_WAKE_PIN_STATE) != ESP_OK) {
Log.error(F("Failed to set deep sleep EXT0 Wakeup." CR));
gatewayState = GatewayState::ERROR;
}
#endif
#ifdef ESP32_EXT1_WAKE_PIN
@@ -1247,6 +1354,7 @@ void setup() {
esp_sleep_ext1_wakeup_mode_t wake_state1 = static_cast<esp_sleep_ext1_wakeup_mode_t>(ESP32_EXT1_WAKE_PIN_STATE);
if (esp_sleep_enable_ext1_wakeup(wake_pin_bitmask, wake_state1) != ESP_OK) {
Log.error(F("Failed to set deep sleep EXT1 Wakeup." CR));
gatewayState = GatewayState::ERROR;
}
#endif
#ifdef ESP32
@@ -1526,8 +1634,6 @@ void setOTA() {
ArduinoOTA.onStart([]() {
Log.trace(F("Start OTA, lock other functions" CR));
ErrorIndicatorON();
SendReceiveIndicatorON();
last_ota_activity_millis = millis();
#ifdef ESP32
ProcessLock = true;
@@ -1540,24 +1646,18 @@ void setOTA() {
ArduinoOTA.onEnd([]() {
Log.trace(F("\nOTA done" CR));
last_ota_activity_millis = 0;
ErrorIndicatorOFF();
SendReceiveIndicatorOFF();
lpDisplayPrint("OTA done");
ESPRestart(6);
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Log.trace(F("Progress: %u%%\r" CR), (progress / (total / 100)));
gatewayState = GatewayState::LOCAL_OTA_IN_PROGRESS;
#ifdef ESP32
//esp_task_wdt_reset();
#endif
last_ota_activity_millis = millis();
});
ArduinoOTA.onError([](ota_error_t error) {
last_ota_activity_millis = millis();
ErrorIndicatorOFF();
SendReceiveIndicatorOFF();
Serial.printf("Error[%u]: ", error);
gatewayState = GatewayState::ERROR;
if (error == OTA_AUTH_ERROR)
Log.error(F("Auth Failed" CR));
else if (error == OTA_BEGIN_ERROR)
@@ -1592,6 +1692,7 @@ void setupTLS(int index) {
Log.notice(F("Server cert found from ss_server_cert" CR));
} else {
Log.error(F("No server cert found" CR));
gatewayState = GatewayState::ERROR;
}
# if AWS_IOT
@@ -1609,6 +1710,7 @@ void setupTLS(int index) {
Log.notice(F("Client cert found from ss_client_cert" CR));
} else {
Log.error(F("No client cert found" CR));
gatewayState = GatewayState::ERROR;
}
if (cnt_parameters_array[index].client_key.length() > MIN_CERT_LENGTH) {
sClient->setPrivateKey(cnt_parameters_array[index].client_key.c_str());
@@ -1618,6 +1720,7 @@ void setupTLS(int index) {
Log.notice(F("Client key found from ss_client_key" CR));
} else {
Log.error(F("No client key found" CR));
gatewayState = GatewayState::ERROR;
}
# endif
# elif defined(ESP8266)
@@ -1696,6 +1799,7 @@ void setup_wifi() {
if (!WiFi.config(ip_adress, gateway_adress, subnet_adress, dns_adress)) {
Log.error(F("Wifi STA Failed to configure" CR));
gatewayState = GatewayState::ERROR;
}
# endif
@@ -1757,11 +1861,6 @@ void blockingWaitForReset() {
ActuatorTrigger();
}
# endif
# ifdef ESP32
//esp_task_wdt_delete(NULL);
# endif
InfoIndicatorOFF();
SendReceiveIndicatorOFF();
// Checking if the flash has already been erased to identify if we erase it or go into failsafe mode
// going to failsafe mode is done by doing a long button press from a state where the flash has already been erased
if (SPIFFS.begin()) {
@@ -1892,6 +1991,7 @@ void saveConfig() {
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Log.error(F("failed to open config file for writing" CR));
gatewayState = GatewayState::ERROR;
}
serializeJson(json, configFile);
@@ -1920,6 +2020,7 @@ bool loadConfigFromFlash() {
auto error = deserializeJson(json, configFile);
if (error) {
Log.error(F("deserialize config failed: %s, buffer capacity: %u" CR), error.c_str(), json.capacity());
gatewayState = GatewayState::ERROR;
}
if (!json.isNull()) {
Log.trace(F("\nparsed json, size: %u" CR), json.memoryUsage());
@@ -2155,8 +2256,6 @@ void setupwifi(bool reset_settings) {
if (!SYSConfig.offline && !wifi_reconnect_bypass()) // if we didn't connect with saved credential we start Wifimanager web portal
{
InfoIndicatorON();
ErrorIndicatorON();
Log.notice(F("Connect your phone to WIFI AP: %s with PWD: %s" CR), WifiManager_ssid, ota_pass);
gatewayState = GatewayState::ONBOARDING;
//fetches ssid and pass and tries to connect
@@ -2189,11 +2288,10 @@ void setupwifi(bool reset_settings) {
ESPRestart(3);
}
}
InfoIndicatorOFF();
ErrorIndicatorOFF();
}
displayPrint("Network connected");
gatewayState = GatewayState::NTWK_CONNECTED;
if (shouldSaveConfig) {
//read updated parameters
@@ -2276,6 +2374,7 @@ void setup_ethernet_esp32() {
}
} else {
Log.error(F("Ethernet not started" CR));
gatewayState = GatewayState::ERROR;
}
}
@@ -2296,11 +2395,11 @@ void WiFiEvent(WiFiEvent_t event) {
ethConnected = true;
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
Log.error(F("Ethernet Disconnected" CR));
Log.warning(F("Ethernet Disconnected" CR));
ethConnected = false;
break;
case ARDUINO_EVENT_ETH_STOP:
Log.error(F("Ethernet Stopped" CR));
Log.warning(F("Ethernet Stopped" CR));
ethConnected = false;
break;
default:
@@ -2357,8 +2456,8 @@ void loop() {
checkButton(); // check if a reset of wifi/mqtt settings is asked
#endif
#ifdef ESP32
//esp_task_wdt_reset();
#ifdef ESP8266
updateAndHandleLEDsTask(); // With ESP8266 we need to update the LEDs in the loop
#endif
if (!SYSConfig.offline) {
if (mqttSetupPending) {
@@ -2372,8 +2471,6 @@ void loop() {
// Switch off of the LED after TimeLedON
if (now > (timer_led_measures + (TimeLedON * 1000))) {
timer_led_measures = millis();
InfoIndicatorOFF();
SendReceiveIndicatorOFF();
}
if (ethConnected || WiFi.status() == WL_CONNECTED) {
@@ -2387,7 +2484,6 @@ void loop() {
#endif
mqtt->loop();
if (mqtt->connected()) { // MQTT client is still connected
InfoIndicatorON();
failure_number_ntwk = 0;
#ifdef ZmqttDiscovery
@@ -2435,20 +2531,13 @@ void loop() {
}
}
} else if (!SYSConfig.offline) { // disconnected from network
#ifdef ESP32
//esp_task_wdt_reset();
#endif
Log.warning(F("Network disconnected" CR));
gatewayState = GatewayState::NTWK_DISCONNECTED;
ErrorIndicatorON();
delay(2000); // add a delay to avoid ESP32 crash and reset
#ifdef ESP32
//esp_task_wdt_reset();
#endif
ErrorIndicatorOFF();
delay(2000);
if (!wifi_reconnect_bypass())
if (!wifi_reconnect_bypass()) {
sleep();
} else {
gatewayState = GatewayState::NTWK_CONNECTED;
}
}
// Function that doesn't need an active connection
#if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH)
@@ -2641,7 +2730,7 @@ String stateMeasures() {
SYSdata["uptime"] = uptime();
SYSdata["version"] = OMG_VERSION;
#ifdef RGB_INDICATORS
#ifdef LED_ADDRESSABLE
SYSdata["rgbb"] = SYSConfig.rgbbrightness;
#endif
#ifdef ZmqttDiscovery
@@ -2656,6 +2745,7 @@ String stateMeasures() {
// Some RTL_433 decoders have memory leak, this is a temporary workaround
if (freeMem < MinimumMemory) {
Log.error(F("Not enough memory %d, restarting" CR), freeMem);
gatewayState = GatewayState::ERROR;
ESPRestart(8);
}
#endif
@@ -2796,6 +2886,7 @@ void receivingMQTT(char* topicOri, char* datacallback) {
auto error = deserializeJson(jsonBuffer, datacallback);
if (error) {
Log.error(F("deserialize MQTT data failed: %s" CR), error.c_str());
gatewayState = GatewayState::ERROR;
return;
}
@@ -2873,7 +2964,6 @@ void receivingMQTT(char* topicOri, char* datacallback) {
MQTTtoWebUI(topicOri, jsondata);
# endif
#endif
SendReceiveIndicatorON();
MQTTtoSYS(topicOri, jsondata);
} else { // not a json object --> simple decoding
@@ -2950,11 +3040,13 @@ bool checkForUpdates() {
auto error = deserializeJson(jsonBuffer, payload);
if (error) {
Log.error(F("Deserialize MQTT data failed: %s" CR), error.c_str());
gatewayState = GatewayState::ERROR;
}
Log.trace(F("HttpCode %d" CR), httpCode);
Log.trace(F("Payload %s" CR), payload.c_str());
} else {
Log.error(F("Error on HTTP request"));
gatewayState = GatewayState::ERROR;
}
http.end(); //Free the resources
Log.notice(F("Update check done, free heap: %d"), ESP.getFreeHeap());
@@ -2994,6 +3086,7 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
if (url) {
if (!strstr((url + (strlen(url) - 5)), ".bin")) {
Log.error(F("Invalid firmware extension" CR));
gatewayState = GatewayState::ERROR;
return;
}
# if MQTT_HTTPS_FW_UPDATE_USE_PASSWORD > 0
@@ -3001,10 +3094,12 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
if (pwd) {
if (strcmp(pwd, ota_pass) != 0) {
Log.error(F("Invalid OTA password" CR));
gatewayState = GatewayState::ERROR;
return;
}
} else {
Log.error(F("No password sent" CR));
gatewayState = GatewayState::ERROR;
return;
}
# endif
@@ -3024,11 +3119,11 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
# endif
} else {
Log.error(F("Invalid URL" CR));
gatewayState = GatewayState::ERROR;
return;
}
# ifdef ESP32
ProcessLock = true;
//esp_task_wdt_delete(NULL); // Stop task watchdog during update
# ifdef ZgatewayBT
stopProcessing();
# endif
@@ -3036,8 +3131,6 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
Log.warning(F("Starting firmware update" CR));
gatewayState = GatewayState::REMOTE_OTA_IN_PROGRESS;
SendReceiveIndicatorON();
ErrorIndicatorON();
StaticJsonDocument<JSON_MSG_BUFFER> jsondata;
jsondata["release_summary"] = "Update in progress ...";
jsondata["origin"] = subjectRLStoMQTT;
@@ -3106,6 +3199,7 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
# elif ESP8266
Log.error(F("HTTP_UPDATE_FAILED Error (%d): %s\n" CR), ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
# endif
gatewayState = GatewayState::ERROR;
break;
case HTTP_UPDATE_NO_UPDATES:
@@ -3129,9 +3223,6 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
break;
}
SendReceiveIndicatorOFF();
ErrorIndicatorOFF();
ESPRestart(6);
}
}
@@ -3144,7 +3235,7 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
*/
void readCntParameters(int index) {
if (index < 0 || index > 2) {
Log.error(F("Invalid cnt index" CR));
Log.warning(F("Invalid cnt index" CR));
return;
}
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
@@ -3191,19 +3282,18 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
stateMeasures();
}
}
#ifdef RGB_INDICATORS
#ifdef LED_ADDRESSABLE
if (SYSdata.containsKey("rgbb") && SYSdata["rgbb"].is<float>()) {
if (SYSdata["rgbb"] >= 0 && SYSdata["rgbb"] <= 255) {
SYSConfig.rgbbrightness = TheengsUtils::round2(SYSdata["rgbb"]);
leds.setBrightness(SYSConfig.rgbbrightness);
leds.show();
ledManager.setBrightness(SYSConfig.rgbbrightness);
# ifdef ZactuatorONOFF
updatePowerIndicator();
# endif
Log.notice(F("RGB brightness: %d" CR), SYSConfig.rgbbrightness);
stateMeasures();
} else {
Log.error(F("RGB brightness value invalid - ignoring command" CR));
Log.warning(F("RGB brightness value invalid - ignoring command" CR));
}
}
#endif
@@ -3234,7 +3324,7 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
WiFi.waitForConnectResult(WiFi_TimeOut * 1000);
if (WiFi.status() != WL_CONNECTED) {
Log.error(F("Failed to connect to new AP; falling back" CR));
Log.warning(F("Failed to connect to new AP; falling back" CR));
WiFi.disconnect(true);
WiFi.begin(prev_ssid.c_str(), prev_pass.c_str());
#if defined(WifiGMode) || defined(WifiPower)
@@ -3290,7 +3380,7 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
if (SYSdata.containsKey("cnt_index") && SYSdata["cnt_index"].is<int>()) {
if (SYSdata["cnt_index"].as<int>() < 0 || SYSdata["cnt_index"].as<int>() > 2) {
Log.error(F("Invalid cnt index provided - ignoring command" CR));
Log.warning(F("Invalid cnt index provided - ignoring command" CR));
return;
}
@@ -3413,7 +3503,7 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
if (SYSConfig.discovery)
pubMqttDiscovery();
} else {
Log.error(F("Discovery command not a boolean" CR));
Log.warning(F("Discovery command not a boolean" CR));
}
Log.notice(F("Discovery state: %T" CR), SYSConfig.discovery);
}