From d95d18d84e5b2b3d3e9b721322e267f7b0023bc3 Mon Sep 17 00:00:00 2001 From: reef-actor Date: Wed, 10 Apr 2019 13:54:50 +0100 Subject: [PATCH 1/8] Color handling for Sonoff L1 --- sonoff/sonoff_template.h | 24 ++++- sonoff/xdrv_19_ps16dz_dimmer.ino | 169 +++++++++++++++++++++++++++---- 2 files changed, 173 insertions(+), 20 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 5945c1fdd..3245f88b0 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -341,6 +341,7 @@ enum SupportedModules { ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, + SONOFF_L1, TECKIN_US, MANZOKU_EU_4, OBI2, @@ -352,7 +353,7 @@ enum SupportedModules { SP10, WAGA, SYF05, - MAXMODULE }; + MAXMODULE}; #define USER_MODULE 255 @@ -698,6 +699,7 @@ const uint8_t kModuleNiceList[] PROGMEM = { #endif #ifdef USE_PS_16_DZ PS_16_DZ, + SONOFF_L1, #endif H801, // Light Devices MAGICHOME, @@ -1768,6 +1770,26 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_USER, 0 }, + { "SONOFF L1", // Sonoff L1 RGB LED controller (ESP8266 w/ separate Nuvoton MCU) + GPIO_USER, + GPIO_TXD, // GPIO01 MCU serial control + GPIO_USER, + GPIO_RXD, // GPIO03 MCU serial control + GPIO_USER, + GPIO_USER, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + 0, // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + 0, // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPIO_USER, + GPIO_LED1, // GPIO13 WiFi LED - Link and Power status + GPIO_USER, + GPIO_USER, + GPIO_USER, + 0 + }, { "Teckin US", // Teckin SP20 US with Energy Monitoring // https://www.amazon.com/Outlet-Compatible-Monitoring-Function-Required/dp/B079Q5W22B // https://www.amazon.com/Outlet-ZOOZEE-Monitoring-Function-Compatible/dp/B07J2LR5KN diff --git a/sonoff/xdrv_19_ps16dz_dimmer.ino b/sonoff/xdrv_19_ps16dz_dimmer.ino index 0b7861cbc..fcb6c1fc4 100644 --- a/sonoff/xdrv_19_ps16dz_dimmer.ino +++ b/sonoff/xdrv_19_ps16dz_dimmer.ino @@ -22,20 +22,32 @@ #define XDRV_19 19 -#define PS16DZ_BUFFER_SIZE 80 +#define PS16DZ_BUFFER_SIZE 140 #define PS16DZ_TYPE_ACK 0 #define PS16DZ_TYPE_PWR 1 #define PS16DZ_TYPE_DIM 2 +#define PS16DZ_SONOFF_L1_MODE_COLORFUL 1 // Colorful (static color) +#define PS16DZ_SONOFF_L1_MODE_COLORFUL_GRADIENT 2 // Colorful Gradient +#define PS16DZ_SONOFF_L1_MODE_COLORFUL_BREATH 3 // Colorful Breath +#define PS16DZ_SONOFF_L1_MODE_DIY_GRADIENT 4 // DIY Gradient (fade in and out) [Speed 1- 100, color] +#define PS16DZ_SONOFF_L1_MODE_DIY_PULSE 5 // DIY Pulse (faster fade in and out) [Speed 1- 100, color] +#define PS16DZ_SONOFF_L1_MODE_DIY_BREATH 6 // DIY Breath (toggle on/off) [Speed 1- 100, color] +#define PS16DZ_SONOFF_L1_MODE_DIY_STROBE 7 // DIY Strobe (faster toggle on/off) [Speed 1- 100, color] +#define PS16DZ_SONOFF_L1_MODE_RGB_GRADIENT 8 // RGB Gradient +#define PS16DZ_SONOFF_L1_MODE_RGB_PULSE 9 // RGB Pulse +#define PS16DZ_SONOFF_L1_MODE_RGB_BREATH 10 // RGB Breath +#define PS16DZ_SONOFF_L1_MODE_RGB_STROBE 11 // RGB strobe +#define PS16DZ_SONOFF_L1_MODE_SYNC_TO_MUSIC 12 // Sync to music [Speed 1- 100, sensitivity 1 - 10] + #include TasmotaSerial *PS16DZSerial = nullptr; bool ps16dz_ignore_dim = false; // Flag to skip serial send to prevent looping when processing inbound states from the faceplate interaction -//uint64_t ps16dz_seq = 0; - +uint8_t color_channel_values[3]; // Most recent serial sent/received values char *ps16dz_tx_buffer = nullptr; // Serial transmit buffer char *ps16dz_rx_buffer = nullptr; // Serial receive buffer int ps16dz_byte_counter = 0; @@ -93,13 +105,42 @@ bool PS16DZSetPower(void) bool PS16DZSetChannels(void) { - PS16DZSerialDuty(((uint8_t*)XdrvMailbox.data)[0]); + if(PS16DZSerial) { + switch (light_subtype) { + case LST_SINGLE: + // PS16DZSerialDuty(((uint8_t*)XdrvMailbox.data)[0]); + break; + case LST_RGB: + P16DZSetChannelsIfRequired(); + break; + } + } + return true; } +void P16DZSetChannelsIfRequired() +{ + bool is_color_change = memcmp(XdrvMailbox.data, color_channel_values, 3) != 0; + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: channels were: R:%d, G:%d, B:%d"), + color_channel_values[0], + color_channel_values[1], + color_channel_values[2]); + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: channels received: R:%d, G:%d, B:%d, changed:%d"), + ((uint8_t*)XdrvMailbox.data)[0], + ((uint8_t*)XdrvMailbox.data)[1], + ((uint8_t*)XdrvMailbox.data)[2], + is_color_change); + + if(!is_color_change) return; + PS16DZSerialRGB(((uint8_t*)XdrvMailbox.data)[0], ((uint8_t*)XdrvMailbox.data)[1], ((uint8_t*)XdrvMailbox.data)[2]); +} + void PS16DZSerialDuty(uint8_t duty) { - if (duty > 0 && !ps16dz_ignore_dim && PS16DZSerial) { + if (duty > 0 && !ps16dz_ignore_dim) { if (duty < 25) { duty = 25; // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself } @@ -110,10 +151,30 @@ void PS16DZSerialDuty(uint8_t duty) ps16dz_ignore_dim = false; // reset flag AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send Dim Level skipped due to 0 or already set. Value=%d"), duty); - } } +void PS16DZSerialRGB(uint8_t red, uint8_t green, uint8_t blue) +{ + // Write out static color update eg. + // AT+UPDATE="sequence":"1554682835320","mode":1,"colorR":255,"colorB":101,"colorG":46,"light_types":1 + + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "AT+UPDATE=\"sequence\":\"")); + printTimestamp(); + int light_types_value = 1; + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s\",\"mode\":%d"), ps16dz_tx_buffer, PS16DZ_SONOFF_L1_MODE_COLORFUL); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"colorR\":%d"), ps16dz_tx_buffer, red); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"colorG\":%d"), ps16dz_tx_buffer, green); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"colorB\":%d"), ps16dz_tx_buffer, blue); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"light_types\":%d"), ps16dz_tx_buffer, light_types_value); + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send serial command: %s"), ps16dz_tx_buffer ); + + PS16DZSerial->print(ps16dz_tx_buffer); + PS16DZSerial->write(0x1B); + PS16DZSerial->flush(); +} + void PS16DZResetWifi(void) { if (!Settings.flag.button_restrict) { @@ -129,7 +190,17 @@ void PS16DZResetWifi(void) bool PS16DZModuleSelected(void) { - light_type = LT_SERIAL1; + switch (my_module_type) + { + case PS_16_DZ: + light_type = LT_SERIAL1; + break; + + case SONOFF_L1: + light_type = LT_PWM3; + break; + } + return true; } @@ -165,33 +236,88 @@ void PS16DZSerialInput(void) else { ps16dz_rx_buffer[ps16dz_byte_counter++] = 0x00; AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: command received: %s"), ps16dz_rx_buffer); - if(!strncmp(ps16dz_rx_buffer+3, "UPDATE", 6) || !strncmp(ps16dz_rx_buffer+3, "RESULT", 6)) { + if(!strncmp(ps16dz_rx_buffer+3, "UPDATE", 6)) { char *end_str; char *string = ps16dz_rx_buffer+10; char* token = strtok_r(string, ",", &end_str); + + char color_channel_name; + bool color_channel_updated[3] = { false, false, false }; + memcpy(color_channel_values, Settings.light_color, 3); + bool is_color_change = false; + while (token != nullptr) { char* end_token; char* token2 = strtok_r(token, ":", &end_token); char* token3 = strtok_r(nullptr, ":", &end_token); + if(!strncmp(token2, "\"switch\"", 8)){ bool ps16dz_power = !strncmp(token3, "\"on\"", 4)?true:false; AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: power received: %s"), token3); - if((power || Settings.light_dimmer > 0) && (power !=ps16dz_power)) { - ExecuteCommandPower(1, ps16dz_power, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction + // if((power || Settings.light_dimmer > 0) && (power !=ps16dz_power)) { + // ExecuteCommandPower(1, ps16dz_power, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction + // } + } + else if(sscanf(token2, "\"color%c\"", &color_channel_name)==1){ + + int color_channel_index; + + switch(color_channel_name) + { + case 'R': + color_channel_index = 0; + break; + case 'G': + color_channel_index = 1; + break; + case 'B': + color_channel_index = 2; + break; + } + + int color_channel_value = atoi(token3); + color_channel_values[color_channel_index] = color_channel_value; + color_channel_updated[color_channel_index] = true; + + bool all_color_channels_updated = + color_channel_updated[0] && + color_channel_updated[1] && + color_channel_updated[2]; + + if(all_color_channels_updated) + { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: color received: R:%d, G:%d, B:%d"), + color_channel_values[0], + color_channel_values[1], + color_channel_values[2]); + } + + is_color_change = memcmp(color_channel_values, Settings.light_color, 3) != 0; + + if(power && all_color_channels_updated && is_color_change) + { + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLOR " %02x%02x%02x"), + color_channel_values[0], + color_channel_values[1], + color_channel_values[2]); + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send CMND_COLOR_STR=%s"), scmnd ); + + ExecuteCommand(scmnd, SRC_SWITCH); } } else if(!strncmp(token2, "\"bright\"", 8)){ uint8_t ps16dz_bright = atoi(token3); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: brightness received: %d"), ps16dz_bright); - if(power && ps16dz_bright > 0 && ps16dz_bright != Settings.light_dimmer) { + // if(power && ps16dz_bright > 0 && ps16dz_bright != Settings.light_dimmer) { - snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), ps16dz_bright ); + // snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), ps16dz_bright ); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send CMND_DIMMER_STR=%s"), scmnd ); + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send CMND_DIMMER_STR=%s"), scmnd ); - ps16dz_ignore_dim = true; - ExecuteCommand(scmnd, SRC_SWITCH); - } + // ps16dz_ignore_dim = true; + // ExecuteCommand(scmnd, SRC_SWITCH); + // } } else if(!strncmp(token2, "\"sequence\"", 10)){ //ps16dz_seq = strtoull(token3+1, nullptr, 10); @@ -199,6 +325,12 @@ void PS16DZSerialInput(void) } token = strtok_r(nullptr, ",", &end_str); } + + if(!is_color_change) + { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Update received")); + PS16DZSendCommand(PS16DZ_TYPE_ACK); + } } else if(!strncmp(ps16dz_rx_buffer+3, "SETTING", 7)) { AddLog_P(LOG_LEVEL_DEBUG, PSTR("PSZ: Reset")); @@ -206,8 +338,6 @@ void PS16DZSerialInput(void) } memset(ps16dz_rx_buffer, 0, PS16DZ_BUFFER_SIZE); ps16dz_byte_counter = 0; - - PS16DZSendCommand(); } } } @@ -222,7 +352,8 @@ bool Xdrv19(uint8_t function) { bool result = false; - if (PS_16_DZ == my_module_type) { + if (PS_16_DZ == my_module_type || + SONOFF_L1 == my_module_type) { switch (function) { case FUNC_LOOP: if (PS16DZSerial) { PS16DZSerialInput(); } From b10fc6677ee2186fb0cff9c44531e8ddc9ee1de9 Mon Sep 17 00:00:00 2001 From: reef-actor <35917163+reef-actor@users.noreply.github.com> Date: Sat, 29 Jun 2019 03:25:39 +0100 Subject: [PATCH 2/8] Dimmer compatibility improvements for Sonoff L1 --- sonoff/xdrv_19_ps16dz_dimmer.ino | 118 +++++++++++++++++-------------- 1 file changed, 63 insertions(+), 55 deletions(-) diff --git a/sonoff/xdrv_19_ps16dz_dimmer.ino b/sonoff/xdrv_19_ps16dz_dimmer.ino index fcb6c1fc4..131e32f54 100644 --- a/sonoff/xdrv_19_ps16dz_dimmer.ino +++ b/sonoff/xdrv_19_ps16dz_dimmer.ino @@ -45,9 +45,8 @@ TasmotaSerial *PS16DZSerial = nullptr; -bool ps16dz_ignore_dim = false; // Flag to skip serial send to prevent looping when processing inbound states from the faceplate interaction - -uint8_t color_channel_values[3]; // Most recent serial sent/received values +uint8_t ps16dz_dimmer = 0; +uint8_t ps16dz_color[3]; // Most recent serial sent/received values char *ps16dz_tx_buffer = nullptr; // Serial transmit buffer char *ps16dz_rx_buffer = nullptr; // Serial receive buffer int ps16dz_byte_counter = 0; @@ -121,52 +120,58 @@ bool PS16DZSetChannels(void) void P16DZSetChannelsIfRequired() { - bool is_color_change = memcmp(XdrvMailbox.data, color_channel_values, 3) != 0; + uint8_t light_state_rgb[3]; + light_state.getRGB(&light_state_rgb[0], &light_state_rgb[1], &light_state_rgb[2]); + bool is_color_change = memcmp(light_state_rgb, ps16dz_color, 3) != 0; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: channels were: R:%d, G:%d, B:%d"), - color_channel_values[0], - color_channel_values[1], - color_channel_values[2]); + uint8_t light_state_dimmer; + light_state_dimmer = light_state.getDimmer(); + bool is_brightness_change = light_state_dimmer != ps16dz_dimmer; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: channels received: R:%d, G:%d, B:%d, changed:%d"), - ((uint8_t*)XdrvMailbox.data)[0], - ((uint8_t*)XdrvMailbox.data)[1], - ((uint8_t*)XdrvMailbox.data)[2], - is_color_change); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: SetChannel: last: R:%d, G:%d, B:%d, Brightness: %d"), ps16dz_color[0], ps16dz_color[1], ps16dz_color[2], ps16dz_dimmer); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: SetChannel: new: R:%d, G:%d, B:%d, Brightness: %d"), light_state_rgb[0], light_state_rgb[1], light_state_rgb[2], light_state_dimmer); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: SetChannel: Color changed %d, Brightness changed %d"), is_color_change, is_brightness_change); - if(!is_color_change) return; - PS16DZSerialRGB(((uint8_t*)XdrvMailbox.data)[0], ((uint8_t*)XdrvMailbox.data)[1], ((uint8_t*)XdrvMailbox.data)[2]); + if(!is_color_change && !is_brightness_change) return; + PS16DZSerialRGB(); } void PS16DZSerialDuty(uint8_t duty) { - if (duty > 0 && !ps16dz_ignore_dim) { - if (duty < 25) { - duty = 25; // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself - } - + if (duty > 0) + { + // Dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself + duty = (duty < 25) ? 25 : duty; PS16DZSendCommand(PS16DZ_TYPE_DIM, duty); - - } else { - ps16dz_ignore_dim = false; // reset flag - - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send Dim Level skipped due to 0 or already set. Value=%d"), duty); } } -void PS16DZSerialRGB(uint8_t red, uint8_t green, uint8_t blue) +// Write out static color update eg. +// AT+UPDATE="sequence":"1554682835320","bright":100,"mode":1,"colorR":255,"colorG":46,"colorB":101,"light_types":1 +void PS16DZSerialRGB() { - // Write out static color update eg. - // AT+UPDATE="sequence":"1554682835320","mode":1,"colorR":255,"colorB":101,"colorG":46,"light_types":1 + uint8_t light_state_dimmer; + light_state_dimmer = light_state.getDimmer(); + // Dimming acts odd below 10% - this mirrors the threshold set on the faceplate itself + light_state_dimmer = (light_state_dimmer < 10) ? 10 : light_state_dimmer; snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "AT+UPDATE=\"sequence\":\"")); printTimestamp(); - int light_types_value = 1; - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s\",\"mode\":%d"), ps16dz_tx_buffer, PS16DZ_SONOFF_L1_MODE_COLORFUL); - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"colorR\":%d"), ps16dz_tx_buffer, red); - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"colorG\":%d"), ps16dz_tx_buffer, green); - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"colorB\":%d"), ps16dz_tx_buffer, blue); - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"light_types\":%d"), ps16dz_tx_buffer, light_types_value); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s\",\"bright\":%d"), ps16dz_tx_buffer, light_state_dimmer); + + bool light_supports_color = LST_RGB <= light_subtype; + if(light_supports_color) + { + int light_types_value = 1; + uint8_t light_state_rgb[3]; + light_state.getRGB(&light_state_rgb[0], &light_state_rgb[1], &light_state_rgb[2]); + + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"mode\":%d"), ps16dz_tx_buffer, PS16DZ_SONOFF_L1_MODE_COLORFUL); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"colorR\":%d"), ps16dz_tx_buffer, light_state_rgb[0]); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"colorG\":%d"), ps16dz_tx_buffer, light_state_rgb[1]); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"colorB\":%d"), ps16dz_tx_buffer, light_state_rgb[2]); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"light_types\":%d"), ps16dz_tx_buffer, light_types_value); + } AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send serial command: %s"), ps16dz_tx_buffer ); @@ -243,8 +248,11 @@ void PS16DZSerialInput(void) char color_channel_name; bool color_channel_updated[3] = { false, false, false }; - memcpy(color_channel_values, Settings.light_color, 3); + memcpy(ps16dz_color, Settings.light_color, 3); bool is_color_change = false; + bool is_brightness_change = false; + + bool light_supports_color = LST_RGB <= light_subtype; while (token != nullptr) { char* end_token; @@ -258,7 +266,7 @@ void PS16DZSerialInput(void) // ExecuteCommandPower(1, ps16dz_power, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction // } } - else if(sscanf(token2, "\"color%c\"", &color_channel_name)==1){ + else if(light_supports_color && sscanf(token2, "\"color%c\"", &color_channel_name)==1){ int color_channel_index; @@ -276,7 +284,7 @@ void PS16DZSerialInput(void) } int color_channel_value = atoi(token3); - color_channel_values[color_channel_index] = color_channel_value; + ps16dz_color[color_channel_index] = color_channel_value; color_channel_updated[color_channel_index] = true; bool all_color_channels_updated = @@ -287,37 +295,37 @@ void PS16DZSerialInput(void) if(all_color_channels_updated) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: color received: R:%d, G:%d, B:%d"), - color_channel_values[0], - color_channel_values[1], - color_channel_values[2]); + ps16dz_color[0], + ps16dz_color[1], + ps16dz_color[2]); } - is_color_change = memcmp(color_channel_values, Settings.light_color, 3) != 0; + is_color_change = memcmp(ps16dz_color, Settings.light_color, 3) != 0; if(power && all_color_channels_updated && is_color_change) { - snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLOR " %02x%02x%02x"), - color_channel_values[0], - color_channel_values[1], - color_channel_values[2]); + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLOR "2 %02x%02x%02x"), + ps16dz_color[0], + ps16dz_color[1], + ps16dz_color[2]); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send CMND_COLOR_STR=%s"), scmnd ); - ExecuteCommand(scmnd, SRC_SWITCH); } } else if(!strncmp(token2, "\"bright\"", 8)){ - uint8_t ps16dz_bright = atoi(token3); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: brightness received: %d"), ps16dz_bright); - // if(power && ps16dz_bright > 0 && ps16dz_bright != Settings.light_dimmer) { - // snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), ps16dz_bright ); + ps16dz_dimmer = atoi(token3); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: brightness received: %d"), ps16dz_dimmer); - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send CMND_DIMMER_STR=%s"), scmnd ); + is_brightness_change = ps16dz_dimmer != Settings.light_dimmer; - // ps16dz_ignore_dim = true; - // ExecuteCommand(scmnd, SRC_SWITCH); - // } + if(power && ps16dz_dimmer > 0 && is_brightness_change) { + + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), ps16dz_dimmer ); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send CMND_DIMMER_STR=%s"), scmnd ); + ExecuteCommand(scmnd, SRC_SWITCH); + } } else if(!strncmp(token2, "\"sequence\"", 10)){ //ps16dz_seq = strtoull(token3+1, nullptr, 10); @@ -326,7 +334,7 @@ void PS16DZSerialInput(void) token = strtok_r(nullptr, ",", &end_str); } - if(!is_color_change) + if(!is_color_change && !is_brightness_change) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Update received")); PS16DZSendCommand(PS16DZ_TYPE_ACK); From 2a19735c925955808085a23155bcd694de13dc4a Mon Sep 17 00:00:00 2001 From: reef-actor <35917163+reef-actor@users.noreply.github.com> Date: Sun, 30 Jun 2019 19:32:34 +0100 Subject: [PATCH 3/8] Switch compatibility improvements for Sonoff L1 --- sonoff/xdrv_19_ps16dz_dimmer.ino | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sonoff/xdrv_19_ps16dz_dimmer.ino b/sonoff/xdrv_19_ps16dz_dimmer.ino index 131e32f54..3d2440694 100644 --- a/sonoff/xdrv_19_ps16dz_dimmer.ino +++ b/sonoff/xdrv_19_ps16dz_dimmer.ino @@ -45,6 +45,7 @@ TasmotaSerial *PS16DZSerial = nullptr; +bool ps16dz_switch = false; uint8_t ps16dz_dimmer = 0; uint8_t ps16dz_color[3]; // Most recent serial sent/received values char *ps16dz_tx_buffer = nullptr; // Serial transmit buffer @@ -249,6 +250,7 @@ void PS16DZSerialInput(void) char color_channel_name; bool color_channel_updated[3] = { false, false, false }; memcpy(ps16dz_color, Settings.light_color, 3); + bool is_switch_change = false; bool is_color_change = false; bool is_brightness_change = false; @@ -260,11 +262,16 @@ void PS16DZSerialInput(void) char* token3 = strtok_r(nullptr, ":", &end_token); if(!strncmp(token2, "\"switch\"", 8)){ - bool ps16dz_power = !strncmp(token3, "\"on\"", 4)?true:false; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: power received: %s"), token3); - // if((power || Settings.light_dimmer > 0) && (power !=ps16dz_power)) { - // ExecuteCommandPower(1, ps16dz_power, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction - // } + + ps16dz_switch = !strncmp(token3, "\"on\"", 4)?true:false; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: switch received: %d"), ps16dz_switch); + + is_switch_change = ps16dz_switch != power; + + if(is_switch_change) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send CMND_POWER=%d"), ps16dz_switch ); + ExecuteCommandPower(1, ps16dz_switch, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction + } } else if(light_supports_color && sscanf(token2, "\"color%c\"", &color_channel_name)==1){ @@ -321,7 +328,6 @@ void PS16DZSerialInput(void) is_brightness_change = ps16dz_dimmer != Settings.light_dimmer; if(power && ps16dz_dimmer > 0 && is_brightness_change) { - snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), ps16dz_dimmer ); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send CMND_DIMMER_STR=%s"), scmnd ); ExecuteCommand(scmnd, SRC_SWITCH); From c489d56ea2c9764e67006defc12e6590f2e36000 Mon Sep 17 00:00:00 2001 From: reef-actor <35917163+reef-actor@users.noreply.github.com> Date: Sun, 30 Jun 2019 21:04:24 +0100 Subject: [PATCH 4/8] Refactor Sonoff L1 to reduce duplication --- sonoff/xdrv_19_ps16dz_dimmer.ino | 195 ++++++++++++------------------- 1 file changed, 76 insertions(+), 119 deletions(-) diff --git a/sonoff/xdrv_19_ps16dz_dimmer.ino b/sonoff/xdrv_19_ps16dz_dimmer.ino index 3d2440694..a4f8021c3 100644 --- a/sonoff/xdrv_19_ps16dz_dimmer.ino +++ b/sonoff/xdrv_19_ps16dz_dimmer.ino @@ -24,10 +24,6 @@ #define PS16DZ_BUFFER_SIZE 140 -#define PS16DZ_TYPE_ACK 0 -#define PS16DZ_TYPE_PWR 1 -#define PS16DZ_TYPE_DIM 2 - #define PS16DZ_SONOFF_L1_MODE_COLORFUL 1 // Colorful (static color) #define PS16DZ_SONOFF_L1_MODE_COLORFUL_GRADIENT 2 // Colorful Gradient #define PS16DZ_SONOFF_L1_MODE_COLORFUL_BREATH 3 // Colorful Breath @@ -45,6 +41,7 @@ TasmotaSerial *PS16DZSerial = nullptr; +bool ps16dz_supports_color = false; bool ps16dz_switch = false; uint8_t ps16dz_dimmer = 0; uint8_t ps16dz_color[3]; // Most recent serial sent/received values @@ -56,100 +53,61 @@ int ps16dz_byte_counter = 0; * Internal Functions \*********************************************************************************************/ -void printTimestamp(void) -{ - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s%d%03d"), ps16dz_tx_buffer, LocalTime(), millis()%1000); -} - -void PS16DZSendCommand(char type = 0, uint8_t value = 0) -{ - switch(type){ - case PS16DZ_TYPE_ACK: - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "AT+SEND=ok")); - break; - case PS16DZ_TYPE_PWR: - case PS16DZ_TYPE_DIM: - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "AT+UPDATE=\"sequence\":\"")); - printTimestamp(); - if ( type == PS16DZ_TYPE_PWR) { - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s\",\"switch\":\"%s\""), ps16dz_tx_buffer, value?"on":"off"); - } - else if ( type == PS16DZ_TYPE_DIM) { - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s\",\"bright\":%d"), ps16dz_tx_buffer, round(value * (100. / 255.))); - } - break; - } - - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send serial command: %s"), ps16dz_tx_buffer ); - - PS16DZSerial->print(ps16dz_tx_buffer); - PS16DZSerial->write(0x1B); - PS16DZSerial->flush(); -} - bool PS16DZSetPower(void) { - bool status = false; - - uint8_t rpower = XdrvMailbox.index; - int16_t source = XdrvMailbox.payload; - - if (source != SRC_SWITCH && PS16DZSerial) { // ignore to prevent loop from pushing state from faceplate interaction - - PS16DZSendCommand(PS16DZ_TYPE_PWR, rpower); - - status = true; - } - return status; + return PS16DZSerialSendUpdateCommandIfRequired(); } bool PS16DZSetChannels(void) { - if(PS16DZSerial) { - switch (light_subtype) { - case LST_SINGLE: - // PS16DZSerialDuty(((uint8_t*)XdrvMailbox.data)[0]); - break; - case LST_RGB: - P16DZSetChannelsIfRequired(); - break; - } + return PS16DZSerialSendUpdateCommandIfRequired(); +} + +bool PS16DZSerialSendUpdateCommandIfRequired() +{ + if(!PS16DZSerial) return true; + + bool is_switch_change = PS16DZSwitchHasChanged(); + bool is_brightness_change = PS16DZDimmerHasChanged(); + bool is_color_change = ps16dz_supports_color && PS16DZColorHasChanged(); + + bool change_has_occurred = is_switch_change || is_brightness_change || is_color_change; + if(change_has_occurred) + { + PS16DZSerialSendUpdateCommand(); } return true; } -void P16DZSetChannelsIfRequired() +bool PS16DZSwitchHasChanged() +{ + int16_t source = XdrvMailbox.payload; + bool source_is_valid = source != SRC_SWITCH; + return source_is_valid; +} + +bool PS16DZDimmerHasChanged() +{ + uint8_t light_state_dimmer = light_state.getDimmer(); + bool dimmer_has_changed = light_state_dimmer != ps16dz_dimmer; + return dimmer_has_changed; +} + +bool PS16DZColorHasChanged() { uint8_t light_state_rgb[3]; light_state.getRGB(&light_state_rgb[0], &light_state_rgb[1], &light_state_rgb[2]); - bool is_color_change = memcmp(light_state_rgb, ps16dz_color, 3) != 0; - - uint8_t light_state_dimmer; - light_state_dimmer = light_state.getDimmer(); - bool is_brightness_change = light_state_dimmer != ps16dz_dimmer; - - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: SetChannel: last: R:%d, G:%d, B:%d, Brightness: %d"), ps16dz_color[0], ps16dz_color[1], ps16dz_color[2], ps16dz_dimmer); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: SetChannel: new: R:%d, G:%d, B:%d, Brightness: %d"), light_state_rgb[0], light_state_rgb[1], light_state_rgb[2], light_state_dimmer); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: SetChannel: Color changed %d, Brightness changed %d"), is_color_change, is_brightness_change); - - if(!is_color_change && !is_brightness_change) return; - PS16DZSerialRGB(); + bool color_has_changed = memcmp(light_state_rgb, ps16dz_color, 3) != 0; + return color_has_changed; } -void PS16DZSerialDuty(uint8_t duty) -{ - if (duty > 0) - { - // Dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself - duty = (duty < 25) ? 25 : duty; - PS16DZSendCommand(PS16DZ_TYPE_DIM, duty); - } -} - -// Write out static color update eg. -// AT+UPDATE="sequence":"1554682835320","bright":100,"mode":1,"colorR":255,"colorG":46,"colorB":101,"light_types":1 -void PS16DZSerialRGB() +// Send a serial update command to the LED controller +// For dimmer types: +// AT+UPDATE="sequence":"1554682835320","switch":"on":"bright":100 +// For color types: +// AT+UPDATE="sequence":"1554682835320","switch":"on":,"bright":100,"mode":1,"colorR":255,"colorG":46,"colorB":101,"light_types":1 +void PS16DZSerialSendUpdateCommand() { uint8_t light_state_dimmer; light_state_dimmer = light_state.getDimmer(); @@ -157,11 +115,11 @@ void PS16DZSerialRGB() light_state_dimmer = (light_state_dimmer < 10) ? 10 : light_state_dimmer; snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "AT+UPDATE=\"sequence\":\"")); - printTimestamp(); - snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s\",\"bright\":%d"), ps16dz_tx_buffer, light_state_dimmer); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s%d%03d"), ps16dz_tx_buffer, LocalTime(), millis()%1000); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s\",\"switch\":\"%s\""), ps16dz_tx_buffer, power?"on":"off"); + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"bright\":%d"), ps16dz_tx_buffer, light_state_dimmer); - bool light_supports_color = LST_RGB <= light_subtype; - if(light_supports_color) + if(ps16dz_supports_color) { int light_types_value = 1; uint8_t light_state_rgb[3]; @@ -173,12 +131,21 @@ void PS16DZSerialRGB() snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"colorB\":%d"), ps16dz_tx_buffer, light_state_rgb[2]); snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "%s,\"light_types\":%d"), ps16dz_tx_buffer, light_types_value); } + PS16DZSerialSendTxBuffer(); +} - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send serial command: %s"), ps16dz_tx_buffer ); +void PS16DZSerialSendOkCommand() +{ + snprintf_P(ps16dz_tx_buffer, PS16DZ_BUFFER_SIZE, PSTR( "AT+SEND=ok")); + PS16DZSerialSendTxBuffer(); +} - PS16DZSerial->print(ps16dz_tx_buffer); - PS16DZSerial->write(0x1B); - PS16DZSerial->flush(); +void PS16DZSerialSendTxBuffer() +{ + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send serial command: %s"), ps16dz_tx_buffer ); + PS16DZSerial->print(ps16dz_tx_buffer); + PS16DZSerial->write(0x1B); + PS16DZSerial->flush(); } void PS16DZResetWifi(void) @@ -212,6 +179,8 @@ bool PS16DZModuleSelected(void) void PS16DZInit(void) { + ps16dz_supports_color = light_state.getColorMode() == LCM_RGB; + ps16dz_tx_buffer = (char*)(malloc(PS16DZ_BUFFER_SIZE)); if (ps16dz_tx_buffer != nullptr) { ps16dz_rx_buffer = (char*)(malloc(PS16DZ_BUFFER_SIZE)); @@ -248,14 +217,12 @@ void PS16DZSerialInput(void) char* token = strtok_r(string, ",", &end_str); char color_channel_name; - bool color_channel_updated[3] = { false, false, false }; + bool color_updated[3] = { false, false, false }; memcpy(ps16dz_color, Settings.light_color, 3); bool is_switch_change = false; bool is_color_change = false; bool is_brightness_change = false; - bool light_supports_color = LST_RGB <= light_subtype; - while (token != nullptr) { char* end_token; char* token2 = strtok_r(token, ":", &end_token); @@ -273,48 +240,38 @@ void PS16DZSerialInput(void) ExecuteCommandPower(1, ps16dz_switch, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction } } - else if(light_supports_color && sscanf(token2, "\"color%c\"", &color_channel_name)==1){ + else if(ps16dz_supports_color && sscanf(token2, "\"color%c\"", &color_channel_name)==1){ - int color_channel_index; + int color_index; switch(color_channel_name) { - case 'R': - color_channel_index = 0; + case 'R': color_index = 0; break; - case 'G': - color_channel_index = 1; + case 'G': color_index = 1; break; - case 'B': - color_channel_index = 2; + case 'B': color_index = 2; break; } - int color_channel_value = atoi(token3); - ps16dz_color[color_channel_index] = color_channel_value; - color_channel_updated[color_channel_index] = true; + int color_value = atoi(token3); + ps16dz_color[color_index] = color_value; + color_updated[color_index] = true; - bool all_color_channels_updated = - color_channel_updated[0] && - color_channel_updated[1] && - color_channel_updated[2]; + bool all_color_channels_updated = color_updated[0] && color_updated[1] && color_updated[2]; if(all_color_channels_updated) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: color received: R:%d, G:%d, B:%d"), - ps16dz_color[0], - ps16dz_color[1], - ps16dz_color[2]); + ps16dz_color[0], ps16dz_color[1], ps16dz_color[2]); + + is_color_change = memcmp(ps16dz_color, Settings.light_color, 3) != 0; } - is_color_change = memcmp(ps16dz_color, Settings.light_color, 3) != 0; - - if(power && all_color_channels_updated && is_color_change) + if(power && is_color_change) { snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLOR "2 %02x%02x%02x"), - ps16dz_color[0], - ps16dz_color[1], - ps16dz_color[2]); + ps16dz_color[0], ps16dz_color[1], ps16dz_color[2]); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send CMND_COLOR_STR=%s"), scmnd ); ExecuteCommand(scmnd, SRC_SWITCH); @@ -334,7 +291,7 @@ void PS16DZSerialInput(void) } } else if(!strncmp(token2, "\"sequence\"", 10)){ - //ps16dz_seq = strtoull(token3+1, nullptr, 10); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: sequence received: %s"), token3); } token = strtok_r(nullptr, ",", &end_str); @@ -343,7 +300,7 @@ void PS16DZSerialInput(void) if(!is_color_change && !is_brightness_change) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Update received")); - PS16DZSendCommand(PS16DZ_TYPE_ACK); + PS16DZSerialSendOkCommand(); } } else if(!strncmp(ps16dz_rx_buffer+3, "SETTING", 7)) { From b930cd1474d18a591b6dc5900f54637ca73359d5 Mon Sep 17 00:00:00 2001 From: reef-actor <35917163+reef-actor@users.noreply.github.com> Date: Sun, 30 Jun 2019 23:51:32 +0100 Subject: [PATCH 5/8] Add changelog entry for Sonoff L1 support --- sonoff/_changelog.ino | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 0ebffba3b..a9d29bda4 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,8 @@ -/* 6.5.0.16 20190611 +/* + * 6.5.0.16 + * Add support for Sonoff L1 + * + * 6.5.0.16 20190611 * Refactored TLS based on BearSSL, warning breaking change for fingerprints validation (see doc) * Add checkbox to GUI password field enabling visibility during password entry only (#5934) * Add using heap when more than 199 IRSend values need to be send. May need increase of define MQTT_MAX_PACKET_SIZE too (#5950) From decd91aac0ddc0e2db1bfaa56138ad650f42eac1 Mon Sep 17 00:00:00 2001 From: reef-actor <35917163+reef-actor@users.noreply.github.com> Date: Mon, 1 Jul 2019 22:50:59 +0100 Subject: [PATCH 6/8] Remove sscanf call and use strncmp instead --- sonoff/xdrv_19_ps16dz_dimmer.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonoff/xdrv_19_ps16dz_dimmer.ino b/sonoff/xdrv_19_ps16dz_dimmer.ino index a4f8021c3..74c7cd070 100644 --- a/sonoff/xdrv_19_ps16dz_dimmer.ino +++ b/sonoff/xdrv_19_ps16dz_dimmer.ino @@ -216,7 +216,6 @@ void PS16DZSerialInput(void) char *string = ps16dz_rx_buffer+10; char* token = strtok_r(string, ",", &end_str); - char color_channel_name; bool color_updated[3] = { false, false, false }; memcpy(ps16dz_color, Settings.light_color, 3); bool is_switch_change = false; @@ -240,8 +239,9 @@ void PS16DZSerialInput(void) ExecuteCommandPower(1, ps16dz_switch, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction } } - else if(ps16dz_supports_color && sscanf(token2, "\"color%c\"", &color_channel_name)==1){ + else if(!strncmp(token2, "\"color", 6)) { + char color_channel_name = token2[6]; int color_index; switch(color_channel_name) From 18f5be9598c96ecbc2bf0c283110b95b84b5a147 Mon Sep 17 00:00:00 2001 From: reef-actor <35917163+reef-actor@users.noreply.github.com> Date: Mon, 1 Jul 2019 23:01:21 +0100 Subject: [PATCH 7/8] Move new entries in SupportedModules and kModules to the ends of the lists --- sonoff/sonoff_template.h | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 3245f88b0..a5f89c48f 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -341,7 +341,6 @@ enum SupportedModules { ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, - SONOFF_L1, TECKIN_US, MANZOKU_EU_4, OBI2, @@ -353,6 +352,7 @@ enum SupportedModules { SP10, WAGA, SYF05, + SONOFF_L1, MAXMODULE}; #define USER_MODULE 255 @@ -1770,26 +1770,6 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_USER, 0 }, - { "SONOFF L1", // Sonoff L1 RGB LED controller (ESP8266 w/ separate Nuvoton MCU) - GPIO_USER, - GPIO_TXD, // GPIO01 MCU serial control - GPIO_USER, - GPIO_RXD, // GPIO03 MCU serial control - GPIO_USER, - GPIO_USER, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - 0, // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - 0, // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPIO_USER, - GPIO_LED1, // GPIO13 WiFi LED - Link and Power status - GPIO_USER, - GPIO_USER, - GPIO_USER, - 0 - }, { "Teckin US", // Teckin SP20 US with Energy Monitoring // https://www.amazon.com/Outlet-Compatible-Monitoring-Function-Required/dp/B079Q5W22B // https://www.amazon.com/Outlet-ZOOZEE-Monitoring-Function-Compatible/dp/B07J2LR5KN @@ -2000,6 +1980,26 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { 0, // GPIO15 wired to GND GPIO_USER, // GPIO16 N.C. ADC0_USER // ADC0 A0 Analog input + }, + { "SONOFF L1", // Sonoff L1 RGB LED controller (ESP8266 w/ separate Nuvoton MCU) + GPIO_USER, + GPIO_TXD, // GPIO01 MCU serial control + GPIO_USER, + GPIO_RXD, // GPIO03 MCU serial control + GPIO_USER, + GPIO_USER, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + 0, // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + 0, // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPIO_USER, + GPIO_LED1, // GPIO13 WiFi LED - Link and Power status + GPIO_USER, + GPIO_USER, + GPIO_USER, + 0 } }; From 53b1a920c7a06e81868f5a407fe7f03c2b731154 Mon Sep 17 00:00:00 2001 From: reef-actor <35917163+reef-actor@users.noreply.github.com> Date: Mon, 1 Jul 2019 23:14:03 +0100 Subject: [PATCH 8/8] Revert "Add changelog entry for Sonoff L1 support" This reverts commit b930cd1474d18a591b6dc5900f54637ca73359d5. --- sonoff/_changelog.ino | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index a9d29bda4..0ebffba3b 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,8 +1,4 @@ -/* - * 6.5.0.16 - * Add support for Sonoff L1 - * - * 6.5.0.16 20190611 +/* 6.5.0.16 20190611 * Refactored TLS based on BearSSL, warning breaking change for fingerprints validation (see doc) * Add checkbox to GUI password field enabling visibility during password entry only (#5934) * Add using heap when more than 199 IRSend values need to be send. May need increase of define MQTT_MAX_PACKET_SIZE too (#5950)