mirror of https://github.com/arendst/Tasmota.git
Fix Sonoff L1 (lite) smoother color transitions
This commit is contained in:
parent
810d967403
commit
feab616277
|
@ -25,6 +25,7 @@ All notable changes to this project will be documented in this file.
|
|||
- Hass and Tasmota discovery prefix topic notifications (#12972)
|
||||
- Unable to disable MusicSync mode on Sonoff L1 Lite regression from 9.3.0 (#12930)
|
||||
- Shelly Dimmer 2 Energy usage (#12815)
|
||||
- Sonoff L1 (lite) smoother color transitions
|
||||
|
||||
## [9.5.0.6] 20210820
|
||||
### Added
|
||||
|
|
|
@ -157,6 +157,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
|||
- ESP32 core v2.0.0 setting hostname
|
||||
- ESP32-C3 settings layout for configuration backup and restore
|
||||
- ESP32-Solo OTA upgrade
|
||||
- Sonoff L1 (lite) smoother color transitions
|
||||
- DDS238-2 wrong reactive power value [#12283](https://github.com/arendst/Tasmota/issues/12283)
|
||||
- ESP32 Webcam add boundary marker before sending mjpeg image [#12376](https://github.com/arendst/Tasmota/issues/12376)
|
||||
- NO VALID JSON regression from may 4th [#12440](https://github.com/arendst/Tasmota/issues/12440)
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
#define XLGT_05 5
|
||||
|
||||
#define SONOFF_L1_START_DELAY // Sync Nuvotron power state with Tasmota on power up
|
||||
//#define SONOFF_L1_ALLOW_REMOTE_INTERRUPT // During schemes 2..4
|
||||
//#define SONOFF_L1_ALLOW_REMOTE_INTERRUPT // During schemes 2..4 or if fade is active
|
||||
#define SONOFF_L1_DEBUG1 // Add send and receive logging
|
||||
|
||||
#define SONOFF_L1_BUSY 200 // Time in milliseconds to handle a serial request
|
||||
|
||||
#define SONOFF_L1_BUFFER_SIZE 170
|
||||
|
||||
#define SONOFF_L1_MODE_COLORFUL 1 // [Color key] Colorful (static color)
|
||||
|
@ -46,10 +48,10 @@
|
|||
|
||||
struct SNFL1 {
|
||||
char *buffer;
|
||||
#ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT
|
||||
uint32_t process_time = 0;
|
||||
uint32_t unlock = 0;
|
||||
bool receive_ready = true;
|
||||
#endif
|
||||
uint32_t busy = SONOFF_L1_BUSY;
|
||||
uint16_t sequence;
|
||||
uint8_t color[3];
|
||||
uint8_t dimmer;
|
||||
uint8_t power;
|
||||
|
@ -75,18 +77,29 @@ void SnfL1SendDelayed(void) {
|
|||
}
|
||||
#endif // SONOFF_L1_START_DELAY
|
||||
|
||||
#include <Ticker.h>
|
||||
Ticker SnfL1Backlog;
|
||||
|
||||
void SnfL1SendBacklog(void) {
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("SL1: ++Exec backlog"));
|
||||
|
||||
SnfL1SetChannels(true);
|
||||
}
|
||||
|
||||
void SnfL1Send(void) {
|
||||
#ifdef SONOFF_L1_DEBUG1
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("SL1: Send %s"), Snfl1.buffer);
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("SL1: Send '%s'"), Snfl1.buffer);
|
||||
#endif
|
||||
Serial.print(Snfl1.buffer);
|
||||
Serial.write(0x1B);
|
||||
Serial.flush();
|
||||
|
||||
Snfl1.process_time = millis();
|
||||
Snfl1.unlock = Snfl1.process_time + Snfl1.busy; // Wait for 'AT+RESULT="sequence":"1630250830439"'
|
||||
}
|
||||
|
||||
void SnfL1SerialSendOk(void) {
|
||||
void SnfL1SendOk(void) {
|
||||
snprintf_P(Snfl1.buffer, SONOFF_L1_BUFFER_SIZE, PSTR("AT+SEND=ok"));
|
||||
|
||||
SnfL1Send();
|
||||
}
|
||||
|
||||
|
@ -101,16 +114,47 @@ bool SnfL1SerialInput(void) {
|
|||
} else {
|
||||
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.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+RESULT="sequence":"0458" = L1
|
||||
// AT+RESULT="sequence":"0458","switch" = L1 lite - just returns part of receive buffer
|
||||
// AT+RESULT="sequence":"1554682835320" = L1 both
|
||||
// AT+UPDATE="sequence":"1554682835320","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
|
||||
#ifdef SONOFF_L1_DEBUG1
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("SL1: Rcvd %s"), TasmotaGlobal.serial_in_buffer);
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("SL1: Rcvd '%s'"), TasmotaGlobal.serial_in_buffer);
|
||||
#endif
|
||||
if (!strncmp(TasmotaGlobal.serial_in_buffer +3, "RESULT", 6)) {
|
||||
#ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT
|
||||
Snfl1.receive_ready = true;
|
||||
#endif
|
||||
Snfl1.busy = 500;
|
||||
#else
|
||||
/*
|
||||
// Read sequence number and calculate time it took from send of same sequence
|
||||
// this indicates Nuvoton processing speed (50-60 for L1, 30-40 for L1 lite)
|
||||
// Important for constant color change schemes and fade
|
||||
char *end_str;
|
||||
char *string = TasmotaGlobal.serial_in_buffer +10;
|
||||
char *token = strtok_r(string, ",", &end_str);
|
||||
if (token) {
|
||||
char* end_token;
|
||||
char* token2 = strtok_r(token, ":", &end_token);
|
||||
char* token3 = strtok_r(nullptr, ":", &end_token);
|
||||
if (!strncmp(token2, "\"sequence\"", 10) && (strlen(token3) > 3)) {
|
||||
token3 = token3 + strlen(token3) - 4; // Last three digits
|
||||
if (Snfl1.sequence == atoi(token3)) {
|
||||
Snfl1.busy = (millis() - Snfl1.process_time) + 30; // Add some scatter time
|
||||
if (Snfl1.busy > SONOFF_L1_BUSY) {
|
||||
Snfl1.busy = SONOFF_L1_BUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
Snfl1.busy = 80;
|
||||
#endif // SONOFF_L1_ALLOW_REMOTE_INTERRUPT
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("Sl1: ++Busy %d"), Snfl1.busy);
|
||||
|
||||
SnfL1SendOk();
|
||||
return true;
|
||||
|
||||
}
|
||||
else if (!strncmp(TasmotaGlobal.serial_in_buffer +3, "UPDATE", 6)) {
|
||||
char cmnd_dimmer[20];
|
||||
|
@ -190,6 +234,8 @@ bool SnfL1SerialInput(void) {
|
|||
token = strtok_r(nullptr, ",", &end_str);
|
||||
}
|
||||
|
||||
SnfL1SendOk();
|
||||
|
||||
if (is_power_change) {
|
||||
if (Settings->light_scheme > 0) {
|
||||
if (!switch_state) { // If power off RC button pressed stop schemes
|
||||
|
@ -197,9 +243,10 @@ bool SnfL1SerialInput(void) {
|
|||
snprintf_P(cmnd_scheme, sizeof(cmnd_scheme), PSTR(D_CMND_SCHEME " 0"));
|
||||
ExecuteCommand(cmnd_scheme, SRC_REMOTE);
|
||||
}
|
||||
} else {
|
||||
ExecuteCommandPower(1, switch_state, SRC_REMOTE);
|
||||
}
|
||||
// else {
|
||||
ExecuteCommandPower(1, switch_state, SRC_REMOTE);
|
||||
// }
|
||||
}
|
||||
else if (is_brightness_change) {
|
||||
ExecuteCommand(cmnd_dimmer, SRC_REMOTE);
|
||||
|
@ -221,8 +268,6 @@ bool SnfL1SerialInput(void) {
|
|||
}
|
||||
}
|
||||
|
||||
SnfL1SerialSendOk();
|
||||
|
||||
return true;
|
||||
}
|
||||
TasmotaGlobal.serial_in_byte = 0;
|
||||
|
@ -231,10 +276,10 @@ bool SnfL1SerialInput(void) {
|
|||
|
||||
/********************************************************************************************/
|
||||
|
||||
bool SnfL1SetChannels(void) {
|
||||
#ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT
|
||||
if (Snfl1.receive_ready || TimeReached(Snfl1.unlock)) {
|
||||
#endif
|
||||
void SnfL1SetChannels(bool backlog) {
|
||||
// Takes about 100ms at 9600 bps
|
||||
|
||||
if (!backlog) {
|
||||
uint8_t power = Light.power;
|
||||
bool power_changed = (Snfl1.power != power);
|
||||
Snfl1.power = power;
|
||||
|
@ -247,17 +292,23 @@ bool SnfL1SetChannels(void) {
|
|||
bool color_changed = false;
|
||||
if (!power_changed) {
|
||||
for (uint32_t i = 0; i < 3; i++) {
|
||||
if ((Snfl1.color[i] < scale_col[i] -5) || (Snfl1.color[i] > scale_col[i] +5)) {
|
||||
color_changed = true; // Allow scale-up margins of +/-5
|
||||
if (Snfl1.color[i] != scale_col[i]) {
|
||||
color_changed = true;
|
||||
}
|
||||
Snfl1.color[i] = scale_col[i];
|
||||
}
|
||||
}
|
||||
if (!power_changed && !dimmer_changed && !color_changed && (Snfl1.old_music_sync == Settings->sbflag1.sonoff_l1_music_sync)) { return true; }
|
||||
if (!power_changed && !dimmer_changed && !color_changed && (Snfl1.old_music_sync == Settings->sbflag1.sonoff_l1_music_sync)) { return; }
|
||||
}
|
||||
|
||||
if (TimeReached(Snfl1.unlock)) {
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("SL1: ++SC snd"));
|
||||
|
||||
uint32_t mode = (Settings->sbflag1.sonoff_l1_music_sync) ? SONOFF_L1_MODE_SYNC_TO_MUSIC : SONOFF_L1_MODE_COLORFUL;
|
||||
Snfl1.sequence = millis()%1000;
|
||||
snprintf_P(Snfl1.buffer, SONOFF_L1_BUFFER_SIZE, PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"switch\":\"%s\",\"light_type\":1,\"colorR\":%d,\"colorG\":%d,\"colorB\":%d,\"bright\":%d,\"mode\":%d"),
|
||||
LocalTime(), millis()%1000,
|
||||
LocalTime(), Snfl1.sequence,
|
||||
Snfl1.power ? "on" : "off",
|
||||
Snfl1.color[0], Snfl1.color[1], Snfl1.color[2],
|
||||
Snfl1.dimmer,
|
||||
|
@ -277,13 +328,14 @@ bool SnfL1SetChannels(void) {
|
|||
} else
|
||||
#endif // SONOFF_L1_START_DELAY
|
||||
SnfL1Send();
|
||||
} else {
|
||||
if (Settings->light_scheme == 0) {
|
||||
// Fix last fade state
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("SL1: ++SC bck"));
|
||||
|
||||
#ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT
|
||||
Snfl1.unlock = millis() + 500; // Allow time for the RC
|
||||
Snfl1.receive_ready = false;
|
||||
SnfL1Backlog.once_ms(SONOFF_L1_BUSY, SnfL1SendBacklog); // Set backlog
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SnfL1SetChannelsFromFunc(void) {
|
||||
|
@ -293,7 +345,8 @@ bool SnfL1SetChannelsFromFunc(void) {
|
|||
} else {
|
||||
Settings->sbflag1.sonoff_l1_music_sync = 0; // Disable MusicSync on user color change
|
||||
}
|
||||
return SnfL1SetChannels();
|
||||
SnfL1SetChannels(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SnfL1ModuleSelected(void) {
|
||||
|
@ -336,7 +389,7 @@ void CmndMusicSync(void) {
|
|||
if ((parm[2] > 0) && (parm[2] < 101)) {
|
||||
Snfl1.speed = parm[2]; // 1..100
|
||||
}
|
||||
SnfL1SetChannels();
|
||||
SnfL1SetChannels(false);
|
||||
}
|
||||
Response_P(PSTR("{\"%s\":{\"Mode\":\"%s\",\"Sensitive\":%d,\"Speed\":%d}}"),
|
||||
XdrvMailbox.command, GetStateText(Settings->sbflag1.sonoff_l1_music_sync), Snfl1.sensitive, Snfl1.speed);
|
||||
|
|
Loading…
Reference in New Issue