Fix rules related exception or watchdog

Fix rules related exception or watchdog by adding a rules mutex solving possible rule loops as in case of Var/Mem/Add/Sub/Mult and Scale (#8757)
This commit is contained in:
Theo Arends 2020-06-22 21:47:40 +02:00
parent 46cbcdda46
commit 610f1cef00

View File

@ -168,6 +168,7 @@ struct RULES {
uint16_t vars_event = 0; uint16_t vars_event = 0;
uint8_t mems_event = 0; uint8_t mems_event = 0;
bool teleperiod = false; bool teleperiod = false;
bool busy = false;
char event_data[100]; char event_data[100];
} Rules; } Rules;
@ -564,7 +565,6 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule)
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Match 1 %d"), match); //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Match 1 %d"), match);
if (bitRead(Settings.rule_once, rule_set)) { if (bitRead(Settings.rule_once, rule_set)) {
if (match) { // Only allow match state changes if (match) { // Only allow match state changes
if (!bitRead(Rules.triggers[rule_set], Rules.trigger_count[rule_set])) { if (!bitRead(Rules.triggers[rule_set], Rules.trigger_count[rule_set])) {
@ -751,28 +751,34 @@ bool RulesProcessEvent(char *json_event)
{ {
bool serviced = false; bool serviced = false;
if (!Rules.busy) {
Rules.busy = true;
#ifdef USE_DEBUG_DRIVER #ifdef USE_DEBUG_DRIVER
ShowFreeMem(PSTR("RulesProcessEvent")); ShowFreeMem(PSTR("RulesProcessEvent"));
#endif #endif
String event_saved = json_event; String event_saved = json_event;
// json_event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} // json_event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}}
// json_event = {"System":{"Boot":1}} // json_event = {"System":{"Boot":1}}
// json_event = {"SerialReceived":"on"} - invalid but will be expanded to {"SerialReceived":{"Data":"on"}} // json_event = {"SerialReceived":"on"} - invalid but will be expanded to {"SerialReceived":{"Data":"on"}}
char *p = strchr(json_event, ':'); char *p = strchr(json_event, ':');
if ((p != NULL) && !(strchr(++p, ':'))) { // Find second colon if ((p != NULL) && !(strchr(++p, ':'))) { // Find second colon
event_saved.replace(F(":"), F(":{\"Data\":")); event_saved.replace(F(":"), F(":{\"Data\":"));
event_saved += F("}"); event_saved += F("}");
// event_saved = {"SerialReceived":{"Data":"on"}} // event_saved = {"SerialReceived":{"Data":"on"}}
} }
event_saved.toUpperCase(); event_saved.toUpperCase();
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Event %s"), event_saved.c_str()); //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Event %s"), event_saved.c_str());
for (uint32_t i = 0; i < MAX_RULE_SETS; i++) { for (uint32_t i = 0; i < MAX_RULE_SETS; i++) {
if (GetRuleLen(i) && bitRead(Settings.rule_enabled, i)) { if (GetRuleLen(i) && bitRead(Settings.rule_enabled, i)) {
if (RuleSetProcess(i, event_saved)) { serviced = true; } if (RuleSetProcess(i, event_saved)) { serviced = true; }
}
} }
Rules.busy = false;
} }
return serviced; return serviced;
} }
@ -796,7 +802,7 @@ void RulesInit(void)
void RulesEvery50ms(void) void RulesEvery50ms(void)
{ {
if (Settings.rule_enabled) { // Any rule enabled if (Settings.rule_enabled && !Rules.busy) { // Any rule enabled
char json_event[120]; char json_event[120];
if (-1 == Rules.new_power) { Rules.new_power = power; } if (-1 == Rules.new_power) { Rules.new_power = power; }
@ -932,7 +938,7 @@ void RulesEvery100ms(void)
void RulesEverySecond(void) void RulesEverySecond(void)
{ {
if (Settings.rule_enabled) { // Any rule enabled if (Settings.rule_enabled && !Rules.busy) { // Any rule enabled
char json_event[120]; char json_event[120];
if (RtcTime.valid) { if (RtcTime.valid) {
@ -956,7 +962,7 @@ void RulesEverySecond(void)
void RulesSaveBeforeRestart(void) void RulesSaveBeforeRestart(void)
{ {
if (Settings.rule_enabled) { // Any rule enabled if (Settings.rule_enabled && !Rules.busy) { // Any rule enabled
char json_event[32]; char json_event[32];
strncpy_P(json_event, PSTR("{\"System\":{\"Save\":1}}"), sizeof(json_event)); strncpy_P(json_event, PSTR("{\"System\":{\"Save\":1}}"), sizeof(json_event));