mirror of https://github.com/arendst/Tasmota.git
Add new compare operators ("==", "!=" ,">=" and "<=") for rule
Introduce new compare operators for rules and did some optimization as well. The new "==" operator act as a real number comparison instead of the previous "=" operator which is doing string comparison which result in FALSE for "1 + 1 = 2". For example: rule1 on event#test do backlog var1 1;add1 1; event CompareWith2=2 endon on event#CompareWith2=%var1% do ledpower on endon ledpower off rule1 on event test
This commit is contained in:
parent
c998760deb
commit
09732c9f2d
|
@ -15,3 +15,4 @@ build
|
|||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
*.bak
|
||||
|
|
|
@ -78,6 +78,27 @@
|
|||
|
||||
#define D_JSON_INITIATED "Initiated"
|
||||
|
||||
#define COMPARE_OPERATOR_NONE -1
|
||||
#define COMPARE_OPERATOR_EQUAL 0
|
||||
#define COMPARE_OPERATOR_BIGGER 1
|
||||
#define COMPARE_OPERATOR_SMALLER 2
|
||||
#define COMPARE_OPERATOR_EXACT_DIVISION 3
|
||||
#define COMPARE_OPERATOR_NUMBER_EQUAL 4
|
||||
#define COMPARE_OPERATOR_NOT_EQUAL 5
|
||||
#define COMPARE_OPERATOR_BIGGER_EQUAL 6
|
||||
#define COMPARE_OPERATOR_SMALLER_EQUAL 7
|
||||
#define MAXIMUM_COMPARE_OPERATOR COMPARE_OPERATOR_SMALLER_EQUAL
|
||||
char* compare_operators[] = {
|
||||
"=",
|
||||
">",
|
||||
"<",
|
||||
"|",
|
||||
"==",
|
||||
"!=",
|
||||
">=",
|
||||
"<="
|
||||
};
|
||||
|
||||
enum RulesCommands { CMND_RULE, CMND_RULETIMER, CMND_EVENT, CMND_VAR, CMND_MEM, CMND_ADD, CMND_SUB, CMND_MULT, CMND_SCALE, CMND_CALC_RESOLUTION };
|
||||
const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMND_EVENT "|" D_CMND_VAR "|" D_CMND_MEM "|" D_CMND_ADD "|" D_CMND_SUB "|" D_CMND_MULT "|" D_CMND_SCALE "|" D_CMND_CALC_RESOLUTION ;
|
||||
|
||||
|
@ -128,31 +149,18 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule)
|
|||
|
||||
String rule_name = rule.substring(pos +1); // "CURRENT>0.100" or "BOOT" or "%var1%" or "MINUTE|5"
|
||||
|
||||
char compare = ' ';
|
||||
pos = rule_name.indexOf(">");
|
||||
if (pos > 0) {
|
||||
compare = '>';
|
||||
} else {
|
||||
pos = rule_name.indexOf("<");
|
||||
if (pos > 0) {
|
||||
compare = '<';
|
||||
} else {
|
||||
pos = rule_name.indexOf("=");
|
||||
if (pos > 0) {
|
||||
compare = '=';
|
||||
} else {
|
||||
pos = rule_name.indexOf("|"); // Modulo, cannot use % easily as it is used for variable detection
|
||||
if (pos > 0) {
|
||||
compare = '%';
|
||||
}
|
||||
}
|
||||
int8_t compare = COMPARE_OPERATOR_NONE;
|
||||
for (int8_t i=MAXIMUM_COMPARE_OPERATOR; i>=0; i--) {
|
||||
if ((pos = rule_name.indexOf(compare_operators[i])) > 0) {
|
||||
compare = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char rule_svalue[CMDSZ] = { 0 };
|
||||
double rule_value = 0;
|
||||
if (pos > 0) {
|
||||
String rule_param = rule_name.substring(pos + 1);
|
||||
if (compare != COMPARE_OPERATOR_NONE) {
|
||||
String rule_param = rule_name.substring(pos + strlen(compare_operators[compare]));
|
||||
for (uint8_t i = 0; i < MAX_RULE_VARS; i++) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%VAR%d%%"), i +1);
|
||||
if (rule_param.startsWith(stemp)) {
|
||||
|
@ -224,24 +232,32 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule)
|
|||
int int_value = int(value);
|
||||
int int_rule_value = int(rule_value);
|
||||
switch (compare) {
|
||||
case '%':
|
||||
if ((int_value > 0) && (int_rule_value > 0)) {
|
||||
if ((int_value % int_rule_value) == 0) { match = true; }
|
||||
}
|
||||
case COMPARE_OPERATOR_EXACT_DIVISION:
|
||||
match = (int_rule_value && (int_value % int_rule_value) == 0);
|
||||
break;
|
||||
case '>':
|
||||
if (value > rule_value) { match = true; }
|
||||
case COMPARE_OPERATOR_EQUAL:
|
||||
match = (!strcasecmp(str_value, rule_svalue)); // Compare strings - this also works for hexadecimals
|
||||
break;
|
||||
case '<':
|
||||
if (value < rule_value) { match = true; }
|
||||
case COMPARE_OPERATOR_BIGGER:
|
||||
match = (value > rule_value);
|
||||
break;
|
||||
case '=':
|
||||
// if (value == rule_value) { match = true; } // Compare values - only decimals or partly hexadecimals
|
||||
if (!strcasecmp(str_value, rule_svalue)) { match = true; } // Compare strings - this also works for hexadecimals
|
||||
case COMPARE_OPERATOR_SMALLER:
|
||||
match = (value < rule_value);
|
||||
break;
|
||||
case ' ':
|
||||
match = true; // Json value but not needed
|
||||
case COMPARE_OPERATOR_NUMBER_EQUAL:
|
||||
match = (value == rule_value);
|
||||
break;
|
||||
case COMPARE_OPERATOR_NOT_EQUAL:
|
||||
match = (value != rule_value);
|
||||
break;
|
||||
case COMPARE_OPERATOR_BIGGER_EQUAL:
|
||||
match = (value >= rule_value);
|
||||
break;
|
||||
case COMPARE_OPERATOR_SMALLER_EQUAL:
|
||||
match = (value <= rule_value);
|
||||
break;
|
||||
default:
|
||||
match = true;
|
||||
}
|
||||
} else match = true;
|
||||
|
||||
|
|
Loading…
Reference in New Issue