[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:
1 parent
20af9ccf11
commit
435b8ca3d9
14 files changed
+932
-437
No files matched your search
+75
-251
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user