mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-24 23:07:17 +00:00
Rules fixes and additions
5.14.0a * Add rules %mem1% to %mem5% variable names storing data in flash (#2780) * Add rules test on %varx% or %memx% (#2780) * Fix anomalies in rules (#2778)
This commit is contained in:
parent
acd4c93201
commit
06258e5a68
@ -5,11 +5,14 @@
|
||||
* Add KNX communication enhancement (#2742)
|
||||
* Add KNX energy data (#2750)
|
||||
* Add python script fw-server.py in tools folder to create a simple OTA server (#2759)
|
||||
* Add rules %mem1% to %mem5% variable names storing data in flash (#2780)
|
||||
* Add rules test on %varx% or %memx% (#2780)
|
||||
* Fix display selection of un-available GPIO options in Module Configuration webpage (#2718)
|
||||
* Fix timer re-trigger within one minute after restart (#2744)
|
||||
* Fix IRSend not accepting data value of 0 (#2751)
|
||||
* Fix vars on rules (#2769)
|
||||
* Fix bug in KNX menu (#2770)
|
||||
* Fix anomalies in rules (#2778)
|
||||
*
|
||||
* 5.14.0 20180515
|
||||
* Update language files
|
||||
|
@ -271,8 +271,9 @@ struct SYSCFG {
|
||||
byte knx_GA_param[MAX_KNX_GA]; // 6E2 Type of Input (relay changed, button pressed, sensor read <-teleperiod)
|
||||
byte knx_CB_param[MAX_KNX_CB]; // 6EC Type of Output (set relay, toggle relay, reply sensor value)
|
||||
|
||||
byte free_6f6[266]; // 6F6
|
||||
byte free_6f6[216]; // 6F6
|
||||
|
||||
char mems[RULES_MAX_MEMS][10]; // 7CE
|
||||
char rules[MAX_RULE_SIZE]; // 800 uses 512 bytes in v5.12.0m
|
||||
|
||||
// A00 - FFF free locations
|
||||
@ -286,6 +287,7 @@ struct RTCMEM {
|
||||
unsigned long energy_kWhtotal; // 008
|
||||
unsigned long pulse_counter[MAX_COUNTERS]; // 00C
|
||||
power_t power; // 01C
|
||||
// 020 next free location
|
||||
} RtcSettings;
|
||||
|
||||
struct TIME_T {
|
||||
|
@ -50,6 +50,7 @@ typedef unsigned long power_t; // Power (Relay) type
|
||||
#define MAX_DOMOTICZ_SNS_IDX 12 // Max number of Domoticz sensors indices
|
||||
#define MAX_KNX_GA 10 // Max number of KNX Group Addresses to read that can be set
|
||||
#define MAX_KNX_CB 10 // Max number of KNX Group Addresses to write that can be set
|
||||
#define RULES_MAX_MEMS 5 // Max number of saved vars
|
||||
#define MAX_RULE_SIZE 512 // Max number of characters in rules
|
||||
|
||||
#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x]
|
||||
|
@ -72,11 +72,13 @@
|
||||
#define D_CMND_RULE "Rule"
|
||||
#define D_CMND_RULETIMER "RuleTimer"
|
||||
#define D_CMND_EVENT "Event"
|
||||
#define D_CMND_VAR "Var"
|
||||
#define D_CMND_MEM "Mem"
|
||||
|
||||
#define D_JSON_INITIATED "Initiated"
|
||||
|
||||
enum RulesCommands { CMND_RULE, CMND_RULETIMER, CMND_EVENT };
|
||||
const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMND_EVENT ;
|
||||
enum RulesCommands { CMND_RULE, CMND_RULETIMER, CMND_EVENT, CMND_VAR, CMND_MEM };
|
||||
const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMND_EVENT "|" D_CMND_VAR "|" D_CMND_MEM ;
|
||||
|
||||
String rules_event_value;
|
||||
unsigned long rules_timer[MAX_RULE_TIMERS] = { 0 };
|
||||
@ -146,6 +148,7 @@ bool RulesRuleMatch(String &event, String &rule)
|
||||
// rule = "INA219#CURRENT>0.100"
|
||||
|
||||
bool match = false;
|
||||
char stemp[10];
|
||||
|
||||
// Step1: Analyse rule
|
||||
int pos = rule.indexOf('#');
|
||||
@ -179,7 +182,24 @@ bool RulesRuleMatch(String &event, String &rule)
|
||||
char tmp_value[CMDSZ] = { 0 };
|
||||
double rule_value = 0;
|
||||
if (pos > 0) {
|
||||
snprintf(tmp_value, sizeof(tmp_value), rule_name.substring(pos + 1).c_str());
|
||||
String rule_param = rule_name.substring(pos + 1);
|
||||
for (byte i = 0; i < RULES_MAX_VARS; i++) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%VAR%d%%"), i +1);
|
||||
if (rule_param.startsWith(stemp)) {
|
||||
rule_param = vars[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (byte i = 0; i < RULES_MAX_MEMS; i++) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%MEM%d%%"), i +1);
|
||||
if (rule_param.startsWith(stemp)) {
|
||||
rule_param = Settings.mems[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
rule_param.toUpperCase();
|
||||
snprintf(tmp_value, sizeof(tmp_value), rule_param.c_str());
|
||||
|
||||
int temp_value = GetStateNumber(tmp_value);
|
||||
if (temp_value > -1) {
|
||||
rule_value = temp_value;
|
||||
@ -288,29 +308,27 @@ bool RulesProcess()
|
||||
commands.trim();
|
||||
String ucommand = commands;
|
||||
ucommand.toUpperCase();
|
||||
if (ucommand.startsWith("VAR")) {
|
||||
uint8_t idx = ucommand.charAt(3) - '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])) {
|
||||
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(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);
|
||||
// if (!ucommand.startsWith("BACKLOG")) { commands = "backlog " + commands; } // Always use Backlog to prevent power race exception
|
||||
if (ucommand.indexOf("EVENT ") != -1) { commands = "backlog " + commands; } // Always use Backlog with event to prevent rule event loop exception
|
||||
commands.replace(F("%value%"), rules_event_value);
|
||||
for (byte i = 0; i < RULES_MAX_VARS; i++) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%var%d%%"), i +1);
|
||||
commands.replace(stemp, vars[i]);
|
||||
}
|
||||
for (byte i = 0; i < RULES_MAX_MEMS; i++) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%mem%d%%"), i +1);
|
||||
commands.replace(stemp, Settings.mems[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(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);
|
||||
serviced = true;
|
||||
}
|
||||
rules_trigger_count++;
|
||||
@ -454,6 +472,18 @@ boolean RulesCommand()
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||
}
|
||||
else if ((CMND_VAR == command_code) && (index > 0) && (index <= RULES_MAX_VARS)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
strlcpy(vars[index -1], ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, sizeof(vars[index -1]));
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||
}
|
||||
else if ((CMND_MEM == command_code) && (index > 0) && (index <= RULES_MAX_MEMS)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
strlcpy(Settings.mems[index -1], ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, sizeof(Settings.mems[index -1]));
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mems[index -1]);
|
||||
}
|
||||
else serviced = false; // Unknown command
|
||||
|
||||
return serviced;
|
||||
|
Loading…
x
Reference in New Issue
Block a user