mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 10:46:31 +00:00
Changed command `TimedPower
` refactored from String to LList
This commit is contained in:
parent
4a4fe27cee
commit
95f76d623f
@ -17,7 +17,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Berry solidification of strings longer than 255 bytes (#20529)
|
- Berry solidification of strings longer than 255 bytes (#20529)
|
||||||
- Berry syntax coloring for Notepad++ by FransO (#20541)
|
- Berry syntax coloring for Notepad++ by FransO (#20541)
|
||||||
- Berry/Zigbee web hook per device for customized status display (#20542)
|
- Berry/Zigbee web hook per device for customized status display (#20542)
|
||||||
- Zigbee ``ZbEmulation`` to selectively exclude some devices from Hue/Alexa emulation
|
- Zigbee ``ZbEmulation`` to selectively exclude some devices from Hue/Alexa emulation (#20552)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
|
|
||||||
@ -28,6 +28,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- ESP8266 platform update from 2024.01.00 to 2024.01.01 (#20539)
|
- ESP8266 platform update from 2024.01.00 to 2024.01.01 (#20539)
|
||||||
- ESP8266 Framework (Arduino Core) from v2.7.5 to v2.7.6 (#20539)
|
- ESP8266 Framework (Arduino Core) from v2.7.5 to v2.7.6 (#20539)
|
||||||
- Refactor Pio filesystem download script (#20544)
|
- Refactor Pio filesystem download script (#20544)
|
||||||
|
- Command ``TimedPower`` refactored from String to LList
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Scripter memory leak in `>w x` (#20473)
|
- Scripter memory leak in `>w x` (#20473)
|
||||||
|
@ -149,6 +149,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
|||||||
- Berry solidification of strings longer than 255 bytes [#20529](https://github.com/arendst/Tasmota/issues/20529)
|
- Berry solidification of strings longer than 255 bytes [#20529](https://github.com/arendst/Tasmota/issues/20529)
|
||||||
- Berry syntax coloring for Notepad++ by FransO [#20541](https://github.com/arendst/Tasmota/issues/20541)
|
- Berry syntax coloring for Notepad++ by FransO [#20541](https://github.com/arendst/Tasmota/issues/20541)
|
||||||
- Berry/Zigbee web hook per device for customized status display [#20542](https://github.com/arendst/Tasmota/issues/20542)
|
- Berry/Zigbee web hook per device for customized status display [#20542](https://github.com/arendst/Tasmota/issues/20542)
|
||||||
|
- Zigbee ``ZbEmulation`` to selectively exclude some devices from Hue/Alexa emulation [#20552](https://github.com/arendst/Tasmota/issues/20552)
|
||||||
- LVGL `lv.str_arr` [#20480](https://github.com/arendst/Tasmota/issues/20480)
|
- LVGL `lv.str_arr` [#20480](https://github.com/arendst/Tasmota/issues/20480)
|
||||||
- LVGL option to add `lv.keyboard` extra widget [#20496](https://github.com/arendst/Tasmota/issues/20496)
|
- LVGL option to add `lv.keyboard` extra widget [#20496](https://github.com/arendst/Tasmota/issues/20496)
|
||||||
- HASPmota `haspmota.page_show()` to change page [#20333](https://github.com/arendst/Tasmota/issues/20333)
|
- HASPmota `haspmota.page_show()` to change page [#20333](https://github.com/arendst/Tasmota/issues/20333)
|
||||||
|
@ -221,7 +221,6 @@ const uint16_t MAX_LOGSZ = 700; // Max number of characters in log l
|
|||||||
const uint8_t SENSOR_MAX_MISS = 5; // Max number of missed sensor reads before deciding it's offline
|
const uint8_t SENSOR_MAX_MISS = 5; // Max number of missed sensor reads before deciding it's offline
|
||||||
|
|
||||||
const uint32_t MIN_BACKLOG_DELAY = 200; // Minimal backlog delay in mSeconds
|
const uint32_t MIN_BACKLOG_DELAY = 200; // Minimal backlog delay in mSeconds
|
||||||
const uint8_t MAX_TIMED_CMND = 16; // Max number of timed commands
|
|
||||||
|
|
||||||
const uint32_t SOFT_BAUDRATE = 9600; // Default software serial baudrate
|
const uint32_t SOFT_BAUDRATE = 9600; // Default software serial baudrate
|
||||||
const uint32_t APP_BAUDRATE = 115200; // Default serial baudrate
|
const uint32_t APP_BAUDRATE = 115200; // Default serial baudrate
|
||||||
|
@ -294,11 +294,6 @@ HardwareSerial TasConsole = Serial; // Only serial interface
|
|||||||
|
|
||||||
char EmptyStr[1] = { 0 }; // Provide a pointer destination to an empty char string
|
char EmptyStr[1] = { 0 }; // Provide a pointer destination to an empty char string
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t time;
|
|
||||||
String command;
|
|
||||||
} tTimedCmnd;
|
|
||||||
|
|
||||||
struct TasmotaGlobal_t {
|
struct TasmotaGlobal_t {
|
||||||
uint32_t global_update; // Timestamp of last global temperature and humidity update
|
uint32_t global_update; // Timestamp of last global temperature and humidity update
|
||||||
uint32_t baudrate; // Current Serial baudrate
|
uint32_t baudrate; // Current Serial baudrate
|
||||||
@ -413,8 +408,6 @@ struct TasmotaGlobal_t {
|
|||||||
uint8_t pwm_dimmer_led_bri; // Adjusted brightness LED level
|
uint8_t pwm_dimmer_led_bri; // Adjusted brightness LED level
|
||||||
#endif // USE_PWM_DIMMER
|
#endif // USE_PWM_DIMMER
|
||||||
|
|
||||||
tTimedCmnd timed_cmnd[MAX_TIMED_CMND]; // Timed command buffer
|
|
||||||
|
|
||||||
#ifdef MQTT_DATA_STRING
|
#ifdef MQTT_DATA_STRING
|
||||||
String mqtt_data; // Buffer filled by Response functions
|
String mqtt_data; // Buffer filled by Response functions
|
||||||
#else
|
#else
|
||||||
|
@ -655,44 +655,38 @@ void CmndPower(void)
|
|||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t time;
|
||||||
|
char* command;
|
||||||
|
} tTimedCmnd;
|
||||||
|
LList<tTimedCmnd> timed_cmnd; // Timed command buffer
|
||||||
|
|
||||||
bool SetTimedCmnd(uint32_t time, const char *command) {
|
bool SetTimedCmnd(uint32_t time, const char *command) {
|
||||||
uint32_t now = millis();
|
// Remove command if present
|
||||||
// Try to use the same slot if command is already present
|
for (auto &elem : timed_cmnd) {
|
||||||
for (uint32_t i = 0; i < MAX_TIMED_CMND; i++) {
|
if (strcmp(command, elem.command) == 0) { // Equal
|
||||||
if (TasmotaGlobal.timed_cmnd[i].time != 0) {
|
free(elem.command);
|
||||||
if (!strcmp(command, TasmotaGlobal.timed_cmnd[i].command.c_str())) {
|
timed_cmnd.remove(&elem);
|
||||||
// Stored command already present
|
break;
|
||||||
TasmotaGlobal.timed_cmnd[i].time = now + time;
|
|
||||||
if (0 == TasmotaGlobal.timed_cmnd[i].time) { // Skip empty slot flag
|
|
||||||
TasmotaGlobal.timed_cmnd[i].time++;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Try to find an empty slot and add command
|
// Add command
|
||||||
for (uint32_t i = 0; i < MAX_TIMED_CMND; i++) {
|
char* cmnd = (char*)malloc(strlen(command) +1);
|
||||||
if (0 == TasmotaGlobal.timed_cmnd[i].time) { // Free slot
|
if (cmnd) {
|
||||||
TasmotaGlobal.timed_cmnd[i].command = command;
|
strcpy(cmnd, command);
|
||||||
TasmotaGlobal.timed_cmnd[i].time = now + time;
|
tTimedCmnd &elem = timed_cmnd.addToLast();
|
||||||
if (0 == TasmotaGlobal.timed_cmnd[i].time) { // Skip empty slot flag
|
elem.time = millis() + time;
|
||||||
TasmotaGlobal.timed_cmnd[i].time++;
|
elem.command = cmnd;
|
||||||
}
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("TIM: No more timer slots left"));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetTimedCmnd(const char *command) {
|
void ResetTimedCmnd(const char *command) {
|
||||||
for (uint32_t i = 0; i < MAX_TIMED_CMND; i++) {
|
for (auto &elem : timed_cmnd) {
|
||||||
if (TasmotaGlobal.timed_cmnd[i].time != 0) {
|
if (strncmp(command, elem.command, strlen(command)) == 0) { // StartsWith
|
||||||
if (!strncmp(command, TasmotaGlobal.timed_cmnd[i].command.c_str(), strlen(command))) {
|
free(elem.command);
|
||||||
// Stored command starts with command
|
timed_cmnd.remove(&elem);
|
||||||
TasmotaGlobal.timed_cmnd[i].time = 0;
|
|
||||||
TasmotaGlobal.timed_cmnd[i].command = (const char*) nullptr; // Force deallocation of the String internal memory
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -701,31 +695,23 @@ void ShowTimedCmnd(const char *command) {
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
Response_P(PSTR("{\"%s\":"), XdrvMailbox.command);
|
Response_P(PSTR("{\"%s\":"), XdrvMailbox.command);
|
||||||
for (uint32_t i = 0; i < MAX_TIMED_CMND; i++) {
|
for (auto &elem : timed_cmnd) {
|
||||||
if (TasmotaGlobal.timed_cmnd[i].time != 0) {
|
if (strncmp(command, elem.command, strlen(command)) == 0) { // StartsWith
|
||||||
if (!strncmp(command, TasmotaGlobal.timed_cmnd[i].command.c_str(), strlen(command))) {
|
ResponseAppend_P(PSTR("%s{\"" D_JSON_REMAINING "\":%d,\"" D_JSON_COMMAND "\":\"%s\"}"),
|
||||||
// Stored command starts with command
|
(found) ? "," : "[", elem.time - now, elem.command);
|
||||||
ResponseAppend_P(PSTR("%s"), (found) ? "," : "[");
|
found = true;
|
||||||
found = true;
|
|
||||||
ResponseAppend_P(PSTR("{\"" D_JSON_REMAINING "\":%d,\"" D_JSON_COMMAND "\":\"%s\"}"), TasmotaGlobal.timed_cmnd[i].time - now, TasmotaGlobal.timed_cmnd[i].command.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found) {
|
ResponseAppend_P((found) ? PSTR("]}") : PSTR("\"" D_JSON_EMPTY "\"}"));
|
||||||
ResponseAppend_P(PSTR("]}"));
|
|
||||||
} else {
|
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_EMPTY "\"}"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopTimedCmnd(void) {
|
void LoopTimedCmnd(void) {
|
||||||
uint32_t now = millis();
|
for (auto &elem : timed_cmnd) {
|
||||||
for (uint32_t i = 0; i < MAX_TIMED_CMND; i++) {
|
if (TimeReached(elem.time)) {
|
||||||
if ((TasmotaGlobal.timed_cmnd[i].time > 0) && (now > TasmotaGlobal.timed_cmnd[i].time)) {
|
char* command = elem.command;
|
||||||
TasmotaGlobal.timed_cmnd[i].time = 0;
|
timed_cmnd.remove(&elem);
|
||||||
String cmd = TasmotaGlobal.timed_cmnd[i].command;
|
ExecuteCommand(command, SRC_TIMER);
|
||||||
TasmotaGlobal.timed_cmnd[i].command = (const char*) nullptr; // Force deallocation of the String internal memory
|
free(command);
|
||||||
ExecuteCommand((char*)cmd.c_str(), SRC_TIMER);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -763,7 +749,7 @@ void CmndTimedPower(void) {
|
|||||||
const uint8_t end_state[] = { POWER_ON, POWER_OFF, POWER_TOGGLE, POWER_BLINK_STOP };
|
const uint8_t end_state[] = { POWER_ON, POWER_OFF, POWER_TOGGLE, POWER_BLINK_STOP };
|
||||||
char cmnd[CMDSZ];
|
char cmnd[CMDSZ];
|
||||||
snprintf_P(cmnd, sizeof(cmnd), PSTR(D_CMND_POWER "%d %d"), XdrvMailbox.index, end_state[start_state]);
|
snprintf_P(cmnd, sizeof(cmnd), PSTR(D_CMND_POWER "%d %d"), XdrvMailbox.index, end_state[start_state]);
|
||||||
if (SetTimedCmnd(time, cmnd)) { // Skip if no more timers left (MAX_TIMED_CMND)
|
if (SetTimedCmnd(time, cmnd)) { // Skip if no more room for timers
|
||||||
XdrvMailbox.payload = start_state;
|
XdrvMailbox.payload = start_state;
|
||||||
CmndPower();
|
CmndPower();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user