Change Sonoff L1 support

This commit is contained in:
Theo Arends 2019-10-17 12:20:26 +02:00
parent c10c057c9b
commit cd10e84ecf
8 changed files with 334 additions and 145 deletions

View File

@ -11,6 +11,7 @@
* Add WebUI for multiple, independent PWM channels
* Remove default DS18B20 driver and only support define DS18x20 (#6647)
* Add support for PMS3003 dust particle sensor
* Change Sonoff L1 support by adding define USE_SONOFF_L1
*
* 6.6.0.17 20191009
* Add command SetOption34 0..255 to set backlog delay. Default value is 200 (mSeconds) (#6562)

View File

@ -315,7 +315,7 @@
#define USE_TUYA_MCU // Add support for Tuya Serial MCU
#define TUYA_DIMMER_ID 0 // Default dimmer Id
#define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code)
#define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer and Sonoff L1 (+2k code)
#define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer (+2k code)
#define USE_SONOFF_IFAN // Add support for Sonoff iFan02 and iFan03 (+2k code)
#define USE_BUZZER // Add support for a buzzer (+0k6 code)
#define USE_ARILUX_RF // Add support for Arilux RF remote controller (+0k8 code, 252 iram (non 2.3.0))
@ -330,6 +330,7 @@
#define USE_MY92X1 // Add support for MY92X1 RGBCW led controller as used in Sonoff B1, Ailight and Lohas
#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code)
#define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code)
#define USE_SONOFF_L1 // Add support for Sonoff L1 led control
// -- Counter input -------------------------------
#define USE_COUNTER // Enable inputs as counter (+0k8 code)

View File

@ -86,6 +86,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
#undef USE_DISCOVERY // Disable mDNS (+8k code or +23.5k code with core 2_5_x, +0.3k mem)
// -- Optional modules -------------------------
//#define ROTARY_V1 // Add support for MI Desk Lamp
#define USE_SONOFF_IFAN // Add support for Sonoff iFan02 and iFan03 (+2k code)
#define USE_TUYA_MCU // Add support for Tuya Serial MCU
#ifndef TUYA_DIMMER_ID
@ -93,7 +94,6 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
#endif
//#define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code)
#define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer and Sonoff L1 (+2k code)
//#define ROTARY_V1 // Add support for MI Desk Lamp
#define USE_COUNTER // Enable counters
#undef USE_ADC_VCC // Add Analog input on selected devices
@ -150,8 +150,6 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
//#define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
//#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code)
#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
#define MP3_VOLUME 10 // Set the startup volume on init, the range can be 0..30(max)
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger
@ -167,6 +165,8 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
#define USE_SDM630_2 // Add support for Eastron SDM630-Modbus energy monitor (+0k6 code)
#define USE_DDS2382 // Add support for Hiking DDS2382 Modbus energy monitor (+0k6 code)
#define USE_DDSU666 // Add support for Chint DDSU666 Modbus energy monitor (+0k6 code)
//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
//#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code)
#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor
#define USE_MAX31855 // Add support for MAX31855 K-Type thermocouple sensor using softSPI
@ -419,7 +419,6 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
//#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor
#undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI
#undef USE_WS2812 // Disable WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by //
#undef USE_ARILUX_RF // Disable support for Arilux RF remote controller
#undef USE_SR04 // Disable support for for HC-SR04 ultrasonic devices
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
#undef USE_HX711 // Disable support for HX711 load cell

View File

@ -763,7 +763,7 @@ const uint8_t kModuleNiceList[] PROGMEM = {
SONOFF_T13,
SONOFF_LED, // Sonoff Light Devices
SONOFF_BN,
#ifdef USE_PS_16_DZ
#ifdef USE_SONOFF_L1
SONOFF_L1,
#endif
SONOFF_B1, // Sonoff Light Bulbs

View File

@ -471,7 +471,9 @@ void GetFeatures(void)
#ifdef USE_SONOFF_RF
feature5 |= 0x00002000; // xdrv_06_snfbridge.ino
#endif
// feature5 |= 0x00004000;
#ifdef USE_SONOFF_L1
feature5 |= 0x00004000;
#endif
// feature5 |= 0x00008000;
// feature5 |= 0x00010000;

View File

@ -1,5 +1,5 @@
/*
xdrv_19_ps16dz.dimmer.ino - PS_16_DZ dimmer and Sonoff L1 support for Sonoff-Tasmota
xdrv_19_ps16dz.dimmer.ino - PS_16_DZ dimmer support for Sonoff-Tasmota
Copyright (C) 2019 Joel Stein and Theo Arends
@ -20,64 +20,46 @@
#ifdef USE_LIGHT
#ifdef USE_PS_16_DZ
/*********************************************************************************************\
* PS 16 DZ Serial Dimmer and Sonoff L1
* PS 16 DZ Serial Dimmer
\*********************************************************************************************/
#define XDRV_19 19
#define PS16DZ_BUFFER_SIZE 140
#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]
#define PS16DZ_BUFFER_SIZE 80
#include <TasmotaSerial.h>
TasmotaSerial *PS16DZSerial = nullptr;
struct PS16DZ {
char *tx_buffer = nullptr; // Serial transmit buffer
char *rx_buffer = nullptr; // Serial receive buffer
int byte_counter = 0;
uint8_t color[3]; // Most recent serial sent/received values
uint8_t dimmer = 0;
bool supports_color = false;
bool switch_state = false;
} Ps16dz;
/*********************************************************************************************\
* Internal Functions
\*********************************************************************************************/
void PS16DZSerialSendTxBuffer(void)
void PS16DZSerialSend(const char *tx_buffer)
{
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send %s"), Ps16dz.tx_buffer);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Send %s"), tx_buffer);
PS16DZSerial->print(Ps16dz.tx_buffer);
PS16DZSerial->print(tx_buffer);
PS16DZSerial->write(0x1B);
PS16DZSerial->flush();
}
void PS16DZSerialSendOkCommand(void)
void PS16DZSerialSendOk(void)
{
snprintf_P(Ps16dz.tx_buffer, PS16DZ_BUFFER_SIZE, PSTR("AT+SEND=ok"));
PS16DZSerialSendTxBuffer();
char tx_buffer[16];
snprintf_P(tx_buffer, sizeof(tx_buffer), PSTR("AT+SEND=ok"));
PS16DZSerialSend(tx_buffer);
}
// 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(void)
{
uint8_t light_state_dimmer = light_state.getDimmer();
@ -85,74 +67,17 @@ void PS16DZSerialSendUpdateCommand(void)
light_state_dimmer = (light_state_dimmer < Settings.dimmer_hw_min) ? Settings.dimmer_hw_min : light_state_dimmer;
light_state_dimmer = (light_state_dimmer > Settings.dimmer_hw_max) ? Settings.dimmer_hw_max : light_state_dimmer;
snprintf_P(Ps16dz.tx_buffer, PS16DZ_BUFFER_SIZE, PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"switch\":\"%s\",\"bright\":%d"),
char tx_buffer[80];
snprintf_P(tx_buffer, sizeof(tx_buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"switch\":\"%s\",\"bright\":%d"),
LocalTime(), millis()%1000, power?"on":"off", light_state_dimmer);
if (Ps16dz.supports_color) {
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,\"colorR\":%d,\"colorG\":%d,\"colorB\":%d,\"light_types\":1"),
Ps16dz.tx_buffer, PS16DZ_SONOFF_L1_MODE_COLORFUL, light_state_rgb[0], light_state_rgb[1], light_state_rgb[2]);
}
PS16DZSerialSendTxBuffer();
PS16DZSerialSend(tx_buffer);
}
/*********************************************************************************************\
* API Functions
\*********************************************************************************************/
bool PS16DZSerialSendUpdateCommandIfRequired(void)
{
if (!PS16DZSerial) { return true; }
bool is_switch_change = (XdrvMailbox.payload != SRC_SWITCH);
bool is_brightness_change = (light_state.getDimmer() != Ps16dz.dimmer);
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 = (Ps16dz.supports_color && (memcmp(light_state_rgb, Ps16dz.color, 3) != 0));
if (is_switch_change || is_brightness_change || is_color_change) {
PS16DZSerialSendUpdateCommand();
}
return true;
}
bool PS16DZModuleSelected(void)
{
switch (my_module_type)
{
case PS_16_DZ:
devices_present++;
light_type = LT_SERIAL1;
break;
case SONOFF_L1:
devices_present++;
light_type = LT_PWM3;
break;
}
return true;
}
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));
if (Ps16dz.rx_buffer != nullptr) {
PS16DZSerial = new TasmotaSerial(pin[GPIO_RXD], pin[GPIO_TXD], 2);
if (PS16DZSerial->begin(19200)) {
if (PS16DZSerial->hardwareSerial()) { ClaimSerial(); }
}
}
}
}
void PS16DZSerialInput(void)
{
char scmnd[20];
@ -171,18 +96,18 @@ void PS16DZSerialInput(void)
Ps16dz.rx_buffer[Ps16dz.byte_counter++] = 0x00;
// AT+RESULT="sequence":"1554682835320"
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Received %s"), Ps16dz.rx_buffer);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Rcvd %s"), Ps16dz.rx_buffer);
if (!strncmp(Ps16dz.rx_buffer+3, "UPDATE", 6)) {
// AT+UPDATE="switch":"on","light_type":1,"colorR":255,"colorG":255,"colorB":255,"bright":100,"mode":19,"speed":100,"sensitive":100
if (!strncmp(Ps16dz.rx_buffer+3, "RESULT", 6)) {
}
else if (!strncmp(Ps16dz.rx_buffer+3, "UPDATE", 6)) {
// AT+UPDATE="switch":"on","bright":100
char *end_str;
char *string = Ps16dz.rx_buffer+10;
char *token = strtok_r(string, ",", &end_str);
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;
while (token != nullptr) {
@ -191,43 +116,13 @@ void PS16DZSerialInput(void)
char* token3 = strtok_r(nullptr, ":", &end_token);
if (!strncmp(token2, "\"switch\"", 8)) {
Ps16dz.switch_state = !strncmp(token3, "\"on\"", 4) ? true : false;
bool switch_state = !strncmp(token3, "\"on\"", 4) ? true : false;
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Switch %d"), Ps16dz.switch_state);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Switch %d"), switch_state);
is_switch_change = (Ps16dz.switch_state != power);
is_switch_change = (switch_state != power);
if (is_switch_change) {
ExecuteCommandPower(1, Ps16dz.switch_state, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
}
}
else if (!strncmp(token2, "\"color", 6)) {
char color_channel_name = token2[6];
int color_index;
switch(color_channel_name)
{
case 'R': color_index = 0;
break;
case 'G': color_index = 1;
break;
case 'B': color_index = 2;
break;
}
int color_value = atoi(token3);
Ps16dz.color[color_index] = color_value;
color_updated[color_index] = true;
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 R:%d, G:%d, B:%d"), Ps16dz.color[0], Ps16dz.color[1], Ps16dz.color[2]);
is_color_change = (memcmp(Ps16dz.color, Settings.light_color, 3) != 0);
}
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]);
ExecuteCommand(scmnd, SRC_SWITCH);
ExecuteCommandPower(1, switch_state, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
}
}
else if (!strncmp(token2, "\"bright\"", 8)) {
@ -249,11 +144,11 @@ void PS16DZSerialInput(void)
token = strtok_r(nullptr, ",", &end_str);
}
if (!is_color_change && !is_brightness_change) {
if (!is_brightness_change) {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PSZ: Update"));
PS16DZSerialSendOkCommand();
PS16DZSerialSendOk();
}
}
else if (!strncmp(Ps16dz.rx_buffer+3, "SETTING", 7)) {
@ -274,6 +169,39 @@ void PS16DZSerialInput(void)
}
}
bool PS16DZSerialSendUpdateCommandIfRequired(void)
{
if (!PS16DZSerial) { return true; }
bool is_switch_change = (XdrvMailbox.payload != SRC_SWITCH);
bool is_brightness_change = (light_state.getDimmer() != Ps16dz.dimmer);
if (is_switch_change || is_brightness_change) {
PS16DZSerialSendUpdateCommand();
}
return true;
}
void PS16DZInit(void)
{
Ps16dz.rx_buffer = (char*)(malloc(PS16DZ_BUFFER_SIZE));
if (Ps16dz.rx_buffer != nullptr) {
PS16DZSerial = new TasmotaSerial(pin[GPIO_RXD], pin[GPIO_TXD], 2);
if (PS16DZSerial->begin(19200)) {
if (PS16DZSerial->hardwareSerial()) { ClaimSerial(); }
}
}
}
bool PS16DZModuleSelected(void)
{
devices_present++;
light_type = LT_SERIAL1;
return true;
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
@ -282,20 +210,20 @@ bool Xdrv19(uint8_t function)
{
bool result = false;
if ((PS_16_DZ == my_module_type) || (SONOFF_L1 == my_module_type)) {
if (PS_16_DZ == my_module_type) {
switch (function) {
case FUNC_LOOP:
if (PS16DZSerial) { PS16DZSerialInput(); }
break;
case FUNC_MODULE_INIT:
result = PS16DZModuleSelected();
case FUNC_SET_DEVICE_POWER:
case FUNC_SET_CHANNELS:
result = PS16DZSerialSendUpdateCommandIfRequired();
break;
case FUNC_INIT:
PS16DZInit();
break;
case FUNC_SET_DEVICE_POWER:
case FUNC_SET_CHANNELS:
result = PS16DZSerialSendUpdateCommandIfRequired();
case FUNC_MODULE_INIT:
result = PS16DZModuleSelected();
break;
}
}

View File

@ -0,0 +1,258 @@
/*
xlgt_05_sonoff_l1.ino - Sonoff L1 led support for Sonoff-Tasmota
Copyright (C) 2019 Theo Arends
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_LIGHT
#ifdef USE_SONOFF_L1
/*********************************************************************************************\
* Sonoff L1
\*********************************************************************************************/
#define XLGT_05 5
#define SONOFF_L1_BUFFER_SIZE 140
#define SONOFF_L1_MODE_COLORFUL 1 // [Color key] Colorful (static color)
#define SONOFF_L1_MODE_COLORFUL_GRADIENT 2 // [SMOOTH] Colorful Gradient
#define SONOFF_L1_MODE_COLORFUL_BREATH 3 // [FADE] Colorful Breath
#define SONOFF_L1_MODE_DIY_GRADIENT 4 // DIY Gradient (fade in and out) [Speed 1- 100, color]
#define SONOFF_L1_MODE_DIY_PULSE 5 // DIY Pulse (faster fade in and out) [Speed 1- 100, color]
#define SONOFF_L1_MODE_DIY_BREATH 6 // DIY Breath (toggle on/off) [Speed 1- 100, color]
#define SONOFF_L1_MODE_DIY_STROBE 7 // DIY Strobe (faster toggle on/off) [Speed 1- 100, color]
#define SONOFF_L1_MODE_RGB_GRADIENT 8 // RGB Gradient
#define SONOFF_L1_MODE_RGB_PULSE 9 // [STROBE] RGB Pulse
#define SONOFF_L1_MODE_RGB_BREATH 10 // RGB Breath
#define SONOFF_L1_MODE_RGB_STROBE 11 // [FLASH] RGB strobe
#define SONOFF_L1_MODE_SYNC_TO_MUSIC 12 // Sync to music [Speed 1- 100, sensitivity 1 - 10]
struct SNFL1 {
uint32_t unlock = 0;
bool receive_ready = true;
} Snfl1;
/********************************************************************************************/
void SnfL1Send(const char *buffer)
{
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SL1: Send %s"), buffer);
Serial.print(buffer);
Serial.write(0x1B);
Serial.flush();
}
void SnfL1SerialSendOk(void)
{
char buffer[16];
snprintf_P(buffer, sizeof(buffer), PSTR("AT+SEND=ok"));
SnfL1Send(buffer);
}
bool SnfL1SerialInput(void)
{
if (serial_in_byte != 0x1B) {
if (serial_in_byte_counter >= 140) {
serial_in_byte_counter = 0;
}
if (serial_in_byte_counter || (!serial_in_byte_counter && ('A' == serial_in_byte))) { // A from AT
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
}
} else {
serial_in_buffer[serial_in_byte_counter++] = 0x00;
// AT+RESULT="sequence":"1554682835320"
// AT+UPDATE="sequence":"34906","switch":"on","light_type":1,"colorR":0,"colorG":16,"colorB":0,"bright":6,"mode":1
// AT+UPDATE="switch":"on","light_type":1,"colorR":255,"colorG":0,"colorB":0,"bright":6,"mode":1,"speed":100,"sensitive":10
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SL1: Rcvd %s"), serial_in_buffer);
if (!strncmp(serial_in_buffer +3, "RESULT", 6)) {
Snfl1.receive_ready = true;
}
else if (!strncmp(serial_in_buffer +3, "UPDATE", 6)) {
char cmnd_dimmer[20];
char cmnd_color[20];
char *end_str;
char *string = serial_in_buffer +10;
char *token = strtok_r(string, ",", &end_str);
bool color_updated[3] = { false, false, false };
uint8_t current_color[3];
memcpy(current_color, Settings.light_color, 3);
bool switch_state = false;
bool is_power_change = false;
bool is_color_change = false;
bool is_brightness_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, "\"sequence\"", 10)) {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SL1: Rcvd sequence %s"), token3);
token = nullptr;
}
else if (!strncmp(token2, "\"switch\"", 8)) {
switch_state = !strncmp(token3, "\"on\"", 4) ? true : false;
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SL1: Rcvd switch %d (%d)"), switch_state, Light.power);
is_power_change = (switch_state != Light.power);
}
else if (!strncmp(token2, "\"color", 6)) {
char color_channel_name = token2[6];
int color_index;
switch(color_channel_name)
{
case 'R': color_index = 0;
break;
case 'G': color_index = 1;
break;
case 'B': color_index = 2;
break;
}
int color_value = atoi(token3);
current_color[color_index] = color_value;
color_updated[color_index] = true;
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("SL1: Rcvd color R%d G%d B%d (R%d G%d B%d)"),
current_color[0], current_color[1], current_color[2],
Settings.light_color[0], Settings.light_color[1], Settings.light_color[2]);
is_color_change = (Light.power && (memcmp(current_color, Settings.light_color, 3) != 0));
}
snprintf_P(cmnd_color, sizeof(cmnd_color), PSTR(D_CMND_COLOR "2 %02x%02x%02x"), current_color[0], current_color[1], current_color[2]);
}
else if (!strncmp(token2, "\"bright\"", 8)) {
uint8_t dimmer = atoi(token3);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SL1: Rcvd dimmer %d (%d)"), dimmer, Settings.light_dimmer);
is_brightness_change = (Light.power && (dimmer > 0) && (dimmer != Settings.light_dimmer));
snprintf_P(cmnd_dimmer, sizeof(cmnd_dimmer), PSTR(D_CMND_DIMMER " %d"), dimmer);
}
token = strtok_r(nullptr, ",", &end_str);
}
if (is_power_change) {
if (Settings.light_scheme > 0) {
if (!switch_state) { // If power off RC button pressed stop schemes
char cmnd_scheme[20];
snprintf_P(cmnd_scheme, sizeof(cmnd_scheme), PSTR(D_CMND_SCHEME " 0"));
ExecuteCommand(cmnd_scheme, SRC_SWITCH);
}
} else {
ExecuteCommandPower(1, switch_state, SRC_SWITCH);
}
}
else if (is_brightness_change) {
ExecuteCommand(cmnd_dimmer, SRC_SWITCH);
}
else if (Light.power && is_color_change) {
if (0 == Settings.light_scheme) { // Fix spurious color receptions when scheme > 0
if (Settings.light_fade) { // Disable fade as RC button colors overrule and are immediate supressing ghost colors
char cmnd_fade[20];
snprintf_P(cmnd_fade, sizeof(cmnd_fade), PSTR(D_CMND_FADE " 0"));
ExecuteCommand(cmnd_fade, SRC_SWITCH);
}
ExecuteCommand(cmnd_color, SRC_SWITCH);
}
}
}
SnfL1SerialSendOk();
return true;
}
serial_in_byte = 0;
return false;
}
/********************************************************************************************/
bool SnfL1SetChannels(void)
{
if (Snfl1.receive_ready || TimeReached(Snfl1.unlock)) {
uint8_t *scale_col = (uint8_t*)XdrvMailbox.topic;
char buffer[140];
snprintf_P(buffer, sizeof(buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"switch\":\"%s\",\"light_type\":1,\"colorR\":%d,\"colorG\":%d,\"colorB\":%d,\"bright\":%d,\"mode\":%d"),
LocalTime(), millis()%1000,
Light.power ? "on" : "off",
scale_col[0], scale_col[1], scale_col[2],
light_state.getDimmer(),
SONOFF_L1_MODE_COLORFUL);
SnfL1Send(buffer);
Snfl1.unlock = millis() + 500; // Allow time for the RC
Snfl1.receive_ready = false;
}
return true;
}
void SnfL1ModuleSelected(void)
{
if (SONOFF_L1 == my_module_type) {
if ((pin[GPIO_RXD] < 99) && (pin[GPIO_TXD] < 99)) {
Settings.flag.mqtt_serial = 0;
baudrate = 19200;
light_type = LT_RGB;
light_flg = XLGT_05;
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("LGT: Sonoff L1 Found"));
}
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
bool Xlgt05(uint8_t function)
{
bool result = false;
switch (function) {
case FUNC_SERIAL:
result = SnfL1SerialInput();
break;
case FUNC_SET_CHANNELS:
result = SnfL1SetChannels();
break;
case FUNC_MODULE_INIT:
SnfL1ModuleSelected();
break;
}
return result;
}
#endif // USE_SONOFF_L1
#endif // USE_LIGHT

View File

@ -170,9 +170,9 @@ a_features = [[
"USE_MAX31865","USE_CHIRP","USE_SOLAX_X1","USE_PAJ7620"
],[
"USE_BUZZER","USE_RDM6300","USE_IBEACON","USE_SML_M",
"USE_INA226","USE_A4988_STEPPER","USE_DDS2382","USE_SM2135",
"USE_INA226","USE_A4988_Stepper","USE_DDS2382","USE_SM2135",
"USE_SHUTTER","USE_PCF8574","USE_DDSU666","USE_DEEPSLEEP",
"USE_SONOFF_SC","USE_SONOFF_RF","","",
"USE_SONOFF_SC","USE_SONOFF_RF","USE_SONOFF_L1","",
"","","","",
"","","","",
"","","","",