mirror of https://github.com/arendst/Tasmota.git
commit
b6e6b263f3
|
@ -5,11 +5,14 @@
|
||||||
* Add KNX communication enhancement (#2742)
|
* Add KNX communication enhancement (#2742)
|
||||||
* Add KNX energy data (#2750)
|
* Add KNX energy data (#2750)
|
||||||
* Add python script fw-server.py in tools folder to create a simple OTA server (#2759)
|
* 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 display selection of un-available GPIO options in Module Configuration webpage (#2718)
|
||||||
* Fix timer re-trigger within one minute after restart (#2744)
|
* Fix timer re-trigger within one minute after restart (#2744)
|
||||||
* Fix IRSend not accepting data value of 0 (#2751)
|
* Fix IRSend not accepting data value of 0 (#2751)
|
||||||
* Fix vars on rules (#2769)
|
* Fix vars on rules (#2769)
|
||||||
* Fix bug in KNX menu (#2770)
|
* Fix bug in KNX menu (#2770)
|
||||||
|
* Fix anomalies in rules (#2778)
|
||||||
*
|
*
|
||||||
* 5.14.0 20180515
|
* 5.14.0 20180515
|
||||||
* Update language files
|
* 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_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 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
|
char rules[MAX_RULE_SIZE]; // 800 uses 512 bytes in v5.12.0m
|
||||||
|
|
||||||
// A00 - FFF free locations
|
// A00 - FFF free locations
|
||||||
|
@ -286,6 +287,7 @@ struct RTCMEM {
|
||||||
unsigned long energy_kWhtotal; // 008
|
unsigned long energy_kWhtotal; // 008
|
||||||
unsigned long pulse_counter[MAX_COUNTERS]; // 00C
|
unsigned long pulse_counter[MAX_COUNTERS]; // 00C
|
||||||
power_t power; // 01C
|
power_t power; // 01C
|
||||||
|
// 020 next free location
|
||||||
} RtcSettings;
|
} RtcSettings;
|
||||||
|
|
||||||
struct TIME_T {
|
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_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_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 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 MAX_RULE_SIZE 512 // Max number of characters in rules
|
||||||
|
|
||||||
#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x]
|
#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x]
|
||||||
|
|
|
@ -72,11 +72,13 @@
|
||||||
#define D_CMND_RULE "Rule"
|
#define D_CMND_RULE "Rule"
|
||||||
#define D_CMND_RULETIMER "RuleTimer"
|
#define D_CMND_RULETIMER "RuleTimer"
|
||||||
#define D_CMND_EVENT "Event"
|
#define D_CMND_EVENT "Event"
|
||||||
|
#define D_CMND_VAR "Var"
|
||||||
|
#define D_CMND_MEM "Mem"
|
||||||
|
|
||||||
#define D_JSON_INITIATED "Initiated"
|
#define D_JSON_INITIATED "Initiated"
|
||||||
|
|
||||||
enum RulesCommands { CMND_RULE, CMND_RULETIMER, 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 ;
|
const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMND_EVENT "|" D_CMND_VAR "|" D_CMND_MEM ;
|
||||||
|
|
||||||
String rules_event_value;
|
String rules_event_value;
|
||||||
unsigned long rules_timer[MAX_RULE_TIMERS] = { 0 };
|
unsigned long rules_timer[MAX_RULE_TIMERS] = { 0 };
|
||||||
|
@ -146,6 +148,7 @@ bool RulesRuleMatch(String &event, String &rule)
|
||||||
// rule = "INA219#CURRENT>0.100"
|
// rule = "INA219#CURRENT>0.100"
|
||||||
|
|
||||||
bool match = false;
|
bool match = false;
|
||||||
|
char stemp[10];
|
||||||
|
|
||||||
// Step1: Analyse rule
|
// Step1: Analyse rule
|
||||||
int pos = rule.indexOf('#');
|
int pos = rule.indexOf('#');
|
||||||
|
@ -179,7 +182,24 @@ bool RulesRuleMatch(String &event, String &rule)
|
||||||
char tmp_value[CMDSZ] = { 0 };
|
char tmp_value[CMDSZ] = { 0 };
|
||||||
double rule_value = 0;
|
double rule_value = 0;
|
||||||
if (pos > 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);
|
int temp_value = GetStateNumber(tmp_value);
|
||||||
if (temp_value > -1) {
|
if (temp_value > -1) {
|
||||||
rule_value = temp_value;
|
rule_value = temp_value;
|
||||||
|
@ -288,29 +308,27 @@ bool RulesProcess()
|
||||||
commands.trim();
|
commands.trim();
|
||||||
String ucommand = commands;
|
String ucommand = commands;
|
||||||
ucommand.toUpperCase();
|
ucommand.toUpperCase();
|
||||||
if (ucommand.startsWith("VAR")) {
|
// if (!ucommand.startsWith("BACKLOG")) { commands = "backlog " + commands; } // Always use Backlog to prevent power race exception
|
||||||
uint8_t idx = ucommand.charAt(3) - '1';
|
if (ucommand.indexOf("EVENT ") != -1) { commands = "backlog " + commands; } // Always use Backlog with event to prevent rule event loop exception
|
||||||
if ((idx >= 0) && (idx < RULES_MAX_VARS)) { snprintf(vars[idx], sizeof(vars[idx]), rules_event_value.c_str()); }
|
commands.replace(F("%value%"), rules_event_value);
|
||||||
} else {
|
for (byte i = 0; i < RULES_MAX_VARS; i++) {
|
||||||
// if (!ucommand.startsWith("BACKLOG")) { commands = "backlog " + commands; } // Always use Backlog to prevent power race condition
|
snprintf_P(stemp, sizeof(stemp), PSTR("%%var%d%%"), i +1);
|
||||||
commands.replace(F("%value%"), rules_event_value);
|
commands.replace(stemp, vars[i]);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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;
|
serviced = true;
|
||||||
}
|
}
|
||||||
rules_trigger_count++;
|
rules_trigger_count++;
|
||||||
|
@ -454,6 +472,18 @@ boolean RulesCommand()
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
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
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
return serviced;
|
return serviced;
|
||||||
|
|
|
@ -489,7 +489,7 @@ const char HueConfigResponse_JSON[] PROGMEM =
|
||||||
"\"last use date\":\"{dt\","
|
"\"last use date\":\"{dt\","
|
||||||
"\"create date\":\"{dt\","
|
"\"create date\":\"{dt\","
|
||||||
"\"name\":\"Remote\"}},"
|
"\"name\":\"Remote\"}},"
|
||||||
"\"swversion\":\"01039019\","
|
"\"swversion\":\"01041302\","
|
||||||
"\"apiversion\":\"1.17.0\","
|
"\"apiversion\":\"1.17.0\","
|
||||||
"\"swupdate\":{\"updatestate\":0,\"url\":\"\",\"text\":\"\",\"notify\": false},"
|
"\"swupdate\":{\"updatestate\":0,\"url\":\"\",\"text\":\"\",\"notify\": false},"
|
||||||
"\"linkbutton\":false,"
|
"\"linkbutton\":false,"
|
||||||
|
|
Loading…
Reference in New Issue