Merge pull request #88 from arendst/development

Update from Tasmota
This commit is contained in:
Adrian Scillato 2018-05-06 11:48:56 -03:00 committed by GitHub
commit 6efb9f70d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 102 additions and 71 deletions

View File

@ -1,8 +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

View File

@ -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&deg;%c{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>

View File

@ -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)) {
backlog[backlog_index] = String(blcommand);
backlog_index++;
if (backlog_index >= MAX_BACKLOG) backlog_index = 0;
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;

View File

@ -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;

View File

@ -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

View File

@ -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,40 +325,33 @@ 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) {
rules_quota++;
if (rules_quota &1) { // Every 100 ms
mqtt_data[0] = '\0';
uint16_t tele_period_save = tele_period;
tele_period = 2; // Do not allow HA updates during next function call
XsnsNextCall(FUNC_JSON_APPEND); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
tele_period = tele_period_save;
if (strlen(mqtt_data)) {
mqtt_data[0] = '{'; // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
RulesProcess();
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';
uint16_t tele_period_save = tele_period;
tele_period = 2; // Do not allow HA updates during next function call
XsnsNextCall(FUNC_JSON_APPEND); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
tele_period = tele_period_save;
if (strlen(mqtt_data)) {
mqtt_data[0] = '{'; // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
RulesProcess();
}
}
}
}
@ -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;