mirror of https://github.com/arendst/Tasmota.git
Merge branch 'development' of https://github.com/arendst/Sonoff-Tasmota into development
This commit is contained in:
commit
5007778e77
|
@ -1,9 +1,11 @@
|
|||
/* 5.13.1a
|
||||
* Change user_config.h otaurl to http://sonoff.maddox.co.uk/tasmota/sonoff.bin (#2588, #2602)
|
||||
* Fix compile error when ADC is enabled and Rules are disabled (#2608)
|
||||
* Fix rule power trigger when no backlog command is used (#2613)
|
||||
* Fix several timer data input and output errors (#2597, #2620)
|
||||
* Fix KNX config error (#2628)
|
||||
* Add Portuguese in Brazil language file
|
||||
* Add rule state test for On/Off in addition to 0/1 (#2613)
|
||||
* Updated Italian language file (#2618)
|
||||
*
|
||||
* 5.13.1 20180501
|
||||
|
|
|
@ -486,6 +486,12 @@ const char kPrefixes[3][PRFX_MAX_STRING_LENGTH] PROGMEM = {
|
|||
// support.ino
|
||||
static const char kMonthNames[] = D_MONTH3LIST;
|
||||
|
||||
const char kOptionOff[] PROGMEM = "OFF|" D_OFF "|" D_FALSE "|" D_STOP "|" D_CELSIUS ;
|
||||
const char kOptionOn[] PROGMEM = "ON|" D_ON "|" D_TRUE "|" D_START "|" D_FAHRENHEIT "|" D_USER ;
|
||||
const char kOptionToggle[] PROGMEM = "TOGGLE|" D_TOGGLE "|" D_ADMIN ;
|
||||
const char kOptionBlink[] PROGMEM = "BLINK|" D_BLINK ;
|
||||
const char kOptionBlinkOff[] PROGMEM = "BLINKOFF|" D_BLINKOFF ;
|
||||
|
||||
// webserver.ino
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_SNS_TEMP[] PROGMEM = "%s{s}%s " D_TEMPERATURE "{m}%s°%c{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
|
|
|
@ -96,12 +96,6 @@ const char kTasmotaCommands[] PROGMEM =
|
|||
D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|"
|
||||
D_CMND_I2CSCAN "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALDELIMITER;
|
||||
|
||||
const char kOptionOff[] PROGMEM = "OFF|" D_OFF "|" D_FALSE "|" D_STOP "|" D_CELSIUS ;
|
||||
const char kOptionOn[] PROGMEM = "ON|" D_ON "|" D_TRUE "|" D_START "|" D_FAHRENHEIT "|" D_USER ;
|
||||
const char kOptionToggle[] PROGMEM = "TOGGLE|" D_TOGGLE "|" D_ADMIN ;
|
||||
const char kOptionBlink[] PROGMEM = "BLINK|" D_BLINK ;
|
||||
const char kOptionBlinkOff[] PROGMEM = "BLINKOFF|" D_BLINKOFF ;
|
||||
|
||||
// Global variables
|
||||
int baudrate = APP_BAUDRATE; // Serial interface baud rate
|
||||
SerialConfig serial_config = SERIAL_8N1; // Serial interface configuration 8 data bits, No parity, 1 stop bit
|
||||
|
@ -436,21 +430,8 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||
}
|
||||
backlog_delay = MIN_BACKLOG_DELAY; // Reset backlog delay
|
||||
|
||||
if ((GetCommandCode(command, sizeof(command), dataBuf, kOptionOff) >= 0) || !strcasecmp(dataBuf, Settings.state_text[0])) {
|
||||
payload = 0;
|
||||
}
|
||||
if ((GetCommandCode(command, sizeof(command), dataBuf, kOptionOn) >= 0) || !strcasecmp(dataBuf, Settings.state_text[1])) {
|
||||
payload = 1;
|
||||
}
|
||||
if ((GetCommandCode(command, sizeof(command), dataBuf, kOptionToggle) >= 0) || !strcasecmp(dataBuf, Settings.state_text[2])) {
|
||||
payload = 2;
|
||||
}
|
||||
if (GetCommandCode(command, sizeof(command), dataBuf, kOptionBlink) >= 0) {
|
||||
payload = 3;
|
||||
}
|
||||
if (GetCommandCode(command, sizeof(command), dataBuf, kOptionBlinkOff) >= 0) {
|
||||
payload = 4;
|
||||
}
|
||||
int temp_payload = GetStateNumber(dataBuf);
|
||||
if (temp_payload > -1) { payload = temp_payload; }
|
||||
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR("RSLT: Payload %d, Payload16 %d"), payload, payload16);
|
||||
// AddLog(LOG_LEVEL_DEBUG);
|
||||
|
@ -462,12 +443,23 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||
bl_pointer--;
|
||||
char *blcommand = strtok(dataBuf, ";");
|
||||
while ((blcommand != NULL) && (backlog_index != bl_pointer)) {
|
||||
while(true) {
|
||||
while ((*blcommand != '\0') && (isblank(*blcommand))) { blcommand++; } // Trim leading spaces
|
||||
if (!strncasecmp_P(blcommand, PSTR(D_CMND_BACKLOG), strlen(D_CMND_BACKLOG))) {
|
||||
blcommand += strlen(D_CMND_BACKLOG); // Skip unnecessary command Backlog
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*blcommand != '\0') {
|
||||
backlog[backlog_index] = String(blcommand);
|
||||
backlog_index++;
|
||||
if (backlog_index >= MAX_BACKLOG) backlog_index = 0;
|
||||
}
|
||||
blcommand = strtok(NULL, ";");
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_APPENDED);
|
||||
// snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_APPENDED);
|
||||
mqtt_data[0] = '\0';
|
||||
} else {
|
||||
uint8_t blflag = (backlog_pointer == backlog_index);
|
||||
backlog_pointer = backlog_index;
|
||||
|
|
|
@ -447,6 +447,29 @@ int GetCommandCode(char* destination, size_t destination_size, const char* needl
|
|||
return result;
|
||||
}
|
||||
|
||||
int GetStateNumber(char *state_text)
|
||||
{
|
||||
char command[CMDSZ];
|
||||
int state_number = -1;
|
||||
|
||||
if ((GetCommandCode(command, sizeof(command), state_text, kOptionOff) >= 0) || !strcasecmp(state_text, Settings.state_text[0])) {
|
||||
state_number = 0;
|
||||
}
|
||||
else if ((GetCommandCode(command, sizeof(command), state_text, kOptionOn) >= 0) || !strcasecmp(state_text, Settings.state_text[1])) {
|
||||
state_number = 1;
|
||||
}
|
||||
else if ((GetCommandCode(command, sizeof(command), state_text, kOptionToggle) >= 0) || !strcasecmp(state_text, Settings.state_text[2])) {
|
||||
state_number = 2;
|
||||
}
|
||||
else if (GetCommandCode(command, sizeof(command), state_text, kOptionBlink) >= 0) {
|
||||
state_number = 3;
|
||||
}
|
||||
else if (GetCommandCode(command, sizeof(command), state_text, kOptionBlinkOff) >= 0) {
|
||||
state_number = 4;
|
||||
}
|
||||
return state_number;
|
||||
}
|
||||
|
||||
void SetSerialBaudrate(int baudrate)
|
||||
{
|
||||
Settings.baudrate = baudrate / 1200;
|
||||
|
|
|
@ -1407,7 +1407,7 @@ void HandlePreflightRequest()
|
|||
void HandleHttpCommand()
|
||||
{
|
||||
if (HttpUser()) { return; }
|
||||
char svalue[INPUT_BUFFER_SIZE]; // big to serve Backlog
|
||||
char svalue[INPUT_BUFFER_SIZE]; // Large to serve Backlog
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND));
|
||||
|
||||
|
@ -1477,7 +1477,7 @@ void HandleConsole()
|
|||
void HandleAjaxConsoleRefresh()
|
||||
{
|
||||
if (HttpUser()) { return; }
|
||||
char svalue[INPUT_BUFFER_SIZE]; // big to serve Backlog
|
||||
char svalue[INPUT_BUFFER_SIZE]; // Large to serve Backlog
|
||||
byte cflg = 1;
|
||||
byte counter = 0; // Initial start, should never be 0 again
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
* on power1#state=1 do color 001000 endon
|
||||
* on button1#state do publish cmnd/ring2/power %value% endon on button2#state do publish cmnd/strip1/power %value% endon
|
||||
* on switch1#state do power2 %value% endon
|
||||
* on analog#a0div10 do publish cmnd/ring2/dimmer %value% endon
|
||||
*
|
||||
* Notes:
|
||||
* Spaces after <on>, around <do> and before <endon> are mandatory
|
||||
|
@ -80,7 +81,8 @@ const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMN
|
|||
String rules_event_value;
|
||||
unsigned long rules_timer[MAX_RULE_TIMERS] = { 0 };
|
||||
uint8_t rules_quota = 0;
|
||||
long rules_power = -1;
|
||||
long rules_new_power = -1;
|
||||
long rules_old_power = -1;
|
||||
|
||||
uint32_t rules_triggers = 0;
|
||||
uint8_t rules_trigger_count = 0;
|
||||
|
@ -172,11 +174,16 @@ bool RulesRuleMatch(String &event, String &rule)
|
|||
}
|
||||
}
|
||||
|
||||
String tmp_value = "none";
|
||||
char tmp_value[CMDSZ] = { 0 };
|
||||
double rule_value = 0;
|
||||
if (pos > 0) {
|
||||
tmp_value = rule_name.substring(pos + 1); // "0.100"
|
||||
rule_value = CharToDouble((char*)tmp_value.c_str()); // 0.1 - This saves 9k code over toFLoat()!
|
||||
snprintf(tmp_value, sizeof(tmp_value), rule_name.substring(pos + 1).c_str());
|
||||
int temp_value = GetStateNumber(tmp_value);
|
||||
if (temp_value > -1) {
|
||||
rule_value = temp_value;
|
||||
} else {
|
||||
rule_value = CharToDouble((char*)tmp_value); // 0.1 - This saves 9k code over toFLoat()!
|
||||
}
|
||||
rule_name = rule_name.substring(0, pos); // "CURRENT"
|
||||
}
|
||||
|
||||
|
@ -188,9 +195,9 @@ bool RulesRuleMatch(String &event, String &rule)
|
|||
double value = 0;
|
||||
const char* str_value = root[rule_task][rule_name];
|
||||
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Task %s, Name %s, Value %s, TrigCnt %d, TrigSt %d, Source %s, Json %s"),
|
||||
// rule_task.c_str(), rule_name.c_str(), tmp_value.c_str(), rules_trigger_count, bitRead(rules_triggers, rules_trigger_count), event.c_str(), (str_value) ? str_value : "none");
|
||||
// AddLog(LOG_LEVEL_DEBUG);
|
||||
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Task %s, Name %s, Value |%s|, TrigCnt %d, TrigSt %d, Source %s, Json %s"),
|
||||
// rule_task.c_str(), rule_name.c_str(), tmp_value, rules_trigger_count, bitRead(rules_triggers, rules_trigger_count), event.c_str(), (str_value) ? str_value : "none");
|
||||
//AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
if (!root[rule_task][rule_name].success()) { return false; }
|
||||
// No value but rule_name is ok
|
||||
|
@ -239,6 +246,8 @@ bool RulesProcess()
|
|||
char vars[RULES_MAX_VARS][10] = { 0 };
|
||||
char stemp[10];
|
||||
|
||||
delay(0); // Prohibit possible loop software watchdog
|
||||
|
||||
if (!Settings.flag.rules_enabled) { return serviced; } // Not enabled
|
||||
if (!strlen(Settings.rules)) { return serviced; } // No rules
|
||||
|
||||
|
@ -266,8 +275,8 @@ bool RulesProcess()
|
|||
String commands = rules.substring(pevt +4, plen); // "Backlog Dimmer 10;Color 100000"
|
||||
plen += 6;
|
||||
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Trigger |%s|, Commands |%s|"), event_trigger.c_str(), commands.c_str());
|
||||
// AddLog(LOG_LEVEL_DEBUG);
|
||||
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Trigger |%s|, Commands |%s|"), event_trigger.c_str(), commands.c_str());
|
||||
//AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
rules_event_value = "";
|
||||
String event = event_saved;
|
||||
|
@ -277,9 +286,9 @@ bool RulesProcess()
|
|||
ucommand.toUpperCase();
|
||||
if (ucommand.startsWith("VAR")) {
|
||||
uint8_t idx = ucommand.charAt(3) - '1';
|
||||
// idx -= '1';
|
||||
if ((idx >= 0) && (idx < RULES_MAX_VARS)) { snprintf(vars[idx], sizeof(vars[idx]), rules_event_value.c_str()); }
|
||||
} else {
|
||||
// if (!ucommand.startsWith("BACKLOG")) { commands = "backlog " + commands; } // Always use Backlog to prevent power race condition
|
||||
commands.replace(F("%value%"), rules_event_value);
|
||||
for (byte i = 0; i < RULES_MAX_VARS; i++) {
|
||||
if (strlen(vars[i])) {
|
||||
|
@ -316,29 +325,21 @@ void RulesInit()
|
|||
rules_teleperiod = 0;
|
||||
}
|
||||
|
||||
void RulesSetPower()
|
||||
{
|
||||
if (Settings.flag.rules_enabled) {
|
||||
uint16_t new_power = XdrvMailbox.index;
|
||||
if (rules_power == -1) rules_power = new_power;
|
||||
uint16_t old_power = rules_power;
|
||||
rules_power = new_power;
|
||||
for (byte i = 0; i < devices_present; i++) {
|
||||
uint8_t new_state = new_power &1;
|
||||
uint8_t old_state = old_power &1;
|
||||
if (new_state != old_state) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Power%d\":{\"State\":%d}}"), i +1, new_state);
|
||||
RulesProcess();
|
||||
}
|
||||
new_power >>= 1;
|
||||
old_power >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RulesEvery50ms()
|
||||
{
|
||||
if (Settings.flag.rules_enabled) {
|
||||
if (rules_new_power != rules_old_power) {
|
||||
if (rules_old_power != -1) {
|
||||
for (byte i = 0; i < devices_present; i++) {
|
||||
uint8_t new_state = (rules_new_power >> i) &1;
|
||||
if (new_state != ((rules_old_power >> i) &1)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Power%d\":{\"State\":%d}}"), i +1, new_state);
|
||||
RulesProcess();
|
||||
}
|
||||
}
|
||||
}
|
||||
rules_old_power = rules_new_power;
|
||||
} else {
|
||||
rules_quota++;
|
||||
if (rules_quota &1) { // Every 100 ms
|
||||
mqtt_data[0] = '\0';
|
||||
|
@ -353,6 +354,7 @@ void RulesEvery50ms()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RulesEverySecond()
|
||||
|
@ -370,6 +372,11 @@ void RulesEverySecond()
|
|||
}
|
||||
}
|
||||
|
||||
void RulesSetPower()
|
||||
{
|
||||
rules_new_power = XdrvMailbox.index;
|
||||
}
|
||||
|
||||
void RulesTeleperiod()
|
||||
{
|
||||
rules_teleperiod = 1;
|
||||
|
@ -459,15 +466,15 @@ boolean Xdrv10(byte function)
|
|||
case FUNC_INIT:
|
||||
RulesInit();
|
||||
break;
|
||||
case FUNC_SET_POWER:
|
||||
RulesSetPower();
|
||||
break;
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
RulesEvery50ms();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
RulesEverySecond();
|
||||
break;
|
||||
case FUNC_SET_POWER:
|
||||
RulesSetPower();
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
result = RulesCommand();
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue