From 4675dbea1c52208c540128e416c3b597400fccb3 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Fri, 27 Apr 2018 18:06:19 +0200 Subject: [PATCH] Add rules variables and teleperiod trigger 5.12.0m * Add rule variables and teleperiod trigger to accomodate user HA messages --- sonoff/_releasenotes.ino | 1 + sonoff/sonoff.ino | 7 +++++- sonoff/xdrv_00_mqtt.ino | 3 ++- sonoff/xdrv_09_timers.ino | 8 +++---- sonoff/xdrv_10_rules.ino | 49 ++++++++++++++++++++++++++++++++------- sonoff/xsns_09_bmp.ino | 7 +++++- 6 files changed, 60 insertions(+), 15 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index c56d6fda0..4be23c8d7 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -3,6 +3,7 @@ * Remove sonoff-xxl * Add sonoff-classic, sonoff-allsensors and sonoff-knx * Add some coloring to important web buttons + * Add rule variables and teleperiod trigger to accomodate user HA messages * Add define MQTT_TELE_RETAIN compile option default set to 0 (#1071) * Add user selectable defines for Sunrise/set Dawn option (#2378) * Add random window to timers (#2447) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 71a2a33d4..ab223790a 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1462,7 +1462,12 @@ void PerformEverySecond() MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN); mqtt_data[0] = '\0'; - if (MqttShowSensor()) { MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); } + if (MqttShowSensor()) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); +#ifdef USE_RULES + RulesTeleperiod(); // Allow rule based HA messages +#endif // USE_RULES + } } } diff --git a/sonoff/xdrv_00_mqtt.ino b/sonoff/xdrv_00_mqtt.ino index 7d47f37b5..8328cef82 100644 --- a/sonoff/xdrv_00_mqtt.ino +++ b/sonoff/xdrv_00_mqtt.ino @@ -648,7 +648,8 @@ bool MqttCommand() mqtt_data[0] = '\0'; } MqttPublishDirect(stemp1, false); - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE); +// snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE); + mqtt_data[0] = '\0'; } } } diff --git a/sonoff/xdrv_09_timers.ino b/sonoff/xdrv_09_timers.ino index 981609b41..aa1287f20 100644 --- a/sonoff/xdrv_09_timers.ino +++ b/sonoff/xdrv_09_timers.ino @@ -201,7 +201,7 @@ void ApplyTimerOffsets(Timer *duskdawn) if (timeBuffer > (uint16_t)duskdawn->time) { timeBuffer = 1440 - (timeBuffer - (uint16_t)duskdawn->time); duskdawn->days = duskdawn->days >> 1; - duskdawn->days = duskdawn->days |= (stored.days << 6); + duskdawn->days |= (stored.days << 6); } else { timeBuffer = (uint16_t)duskdawn->time - timeBuffer; } @@ -212,7 +212,7 @@ void ApplyTimerOffsets(Timer *duskdawn) if (timeBuffer > 1440) { timeBuffer -= 1440; duskdawn->days = duskdawn->days << 1; - duskdawn->days = duskdawn->days |= (stored.days >> 6); + duskdawn->days |= (stored.days >> 6); } } duskdawn->time = timeBuffer; @@ -279,8 +279,8 @@ void TimerEverySecond() #endif if (xtimer.arm) { set_time += timer_window[i]; // Add random time offset - if (set_time < 0) { set_time == 0; } // Stay today; - if (set_time > 1439) { set_time == 1439; } + if (set_time < 0) { set_time = 0; } // Stay today; + if (set_time > 1439) { set_time = 1439; } if (time == set_time) { if (xtimer.days & days) { Settings.timer[i].arm = xtimer.repeat; diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino index afe6baa18..f92edcf55 100644 --- a/sonoff/xdrv_10_rules.ino +++ b/sonoff/xdrv_10_rules.ino @@ -62,6 +62,7 @@ \*********************************************************************************************/ #define MAX_RULE_TIMERS 8 +#define RULES_MAX_VARS 5 #ifndef ULONG_MAX #define ULONG_MAX 0xffffffffUL @@ -83,6 +84,7 @@ long rules_power = -1; uint32_t rules_triggers = 0; uint8_t rules_trigger_count = 0; +uint8_t rules_teleperiod = 0; /*******************************************************************************************/ @@ -146,6 +148,12 @@ bool RulesRuleMatch(String &event, String &rule) if (pos == -1) { return false; } // No # sign in rule String rule_task = rule.substring(0, pos); // "INA219" or "SYSTEM" + if (rules_teleperiod) { + int ppos = rule_task.indexOf("TELE-"); // "TELE-INA219" or "INA219" + if (ppos == -1) { return false; } // No pre-amble in rule + rule_task = rule.substring(5, pos); // "INA219" or "SYSTEM" + } + String rule_name = rule.substring(pos +1); // "CURRENT>0.100" or "BOOT" char compare = ' '; @@ -228,6 +236,8 @@ bool RulesRuleMatch(String &event, String &rule) bool RulesProcess() { bool serviced = false; + char vars[RULES_MAX_VARS][10] = { 0 }; + char stemp[10]; if (!Settings.flag.rules_enabled) { return serviced; } // Not enabled if (!strlen(Settings.rules)) { return serviced; } // No rules @@ -262,17 +272,32 @@ bool RulesProcess() rules_event_value = ""; String event = event_saved; if (RulesRuleMatch(event, event_trigger)) { - commands.replace(F("%value%"), rules_event_value); - char command[commands.length() +1]; - snprintf(command, sizeof(command), commands.c_str()); + commands.trim(); + String ucommand = commands; + 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 { + commands.replace(F("%value%"), rules_event_value); + for (byte i = 0; i < RULES_MAX_VARS; i++) { + if (strlen(vars[i])) { + snprintf_P(stemp, sizeof(stemp), PSTR("%%var%d%%"), i +1); + commands.replace(stemp, vars[i]); + } + } + char command[commands.length() +1]; + snprintf(command, sizeof(command), commands.c_str()); - snprintf_P(log_data, sizeof(log_data), PSTR("RUL: %s performs \"%s\""), event_trigger.c_str(), command); - AddLog(LOG_LEVEL_INFO); + snprintf_P(log_data, sizeof(log_data), PSTR("RUL: %s performs \"%s\""), event_trigger.c_str(), command); + AddLog(LOG_LEVEL_INFO); -// snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, D_CMND_RULE, D_JSON_INITIATED); -// MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RULE)); +// snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, D_CMND_RULE, D_JSON_INITIATED); +// MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RULE)); - ExecuteCommand(command); + ExecuteCommand(command); + } serviced = true; } rules_trigger_count++; @@ -288,6 +313,7 @@ void RulesInit() Settings.flag.rules_enabled = 0; Settings.flag.rules_once = 0; } + rules_teleperiod = 0; } void RulesSetPower() @@ -344,6 +370,13 @@ void RulesEverySecond() } } +void RulesTeleperiod() +{ + rules_teleperiod = 1; + RulesProcess(); + rules_teleperiod = 0; +} + boolean RulesCommand() { char command[CMDSZ]; diff --git a/sonoff/xsns_09_bmp.ino b/sonoff/xsns_09_bmp.ino index 01eb29799..e6b4e03fd 100644 --- a/sonoff/xsns_09_bmp.ino +++ b/sonoff/xsns_09_bmp.ino @@ -465,7 +465,12 @@ void BmpShow(boolean json) mqtt_data, bmp_name, temperature, (bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : ""); #endif // USE_BME680 #ifdef USE_DOMOTICZ - if (0 == tele_period) DomoticzTempHumPressureSensor(temperature, humidity, pressure); + if (0 == tele_period) { + DomoticzTempHumPressureSensor(temperature, humidity, pressure); +#ifdef USE_BME680 + if (bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)g); } +#endif // USE_BME680 + } #endif // USE_DOMOTICZ #ifdef USE_KNX