[Uncrustify] Make rules source code files better readable

Since the `ESPEasyRules.ino` file is newly introduced in this branch, now is the best moment to tidy up the source code.
Also included the used Uncrustify.cfg file.
This commit is contained in:
Gijs Noorlander
2018-12-02 00:35:00 +01:00
parent 8369c330de
commit 6ae627b32a
4 changed files with 641 additions and 427 deletions
+113 -101
View File
@@ -4,117 +4,129 @@
#include <ctype.h>
#include <Arduino.h>
bool IsNumeric(const char * source)
bool IsNumeric(const char *source)
{
bool result = false;
if (source) {
int len = strlen(source);
if (len != 0) {
int i;
for (i = 0; i < len && isdigit(source[i]); i++) ;
result = i == len;
}
}
return result;
bool result = false;
if (source) {
int len = strlen(source);
if (len != 0) {
int i;
for (i = 0; i < len && isdigit(source[i]); i++) {}
result = i == len;
}
}
return result;
}
String Command_GetORSetIP(struct EventStruct *event,
const __FlashStringHelper *targetDescription,
const char *Line,
byte* IP,
IPAddress dhcpIP,
int arg)
String Command_GetORSetIP(struct EventStruct *event,
const __FlashStringHelper *targetDescription,
const char *Line,
byte *IP,
IPAddress dhcpIP,
int arg)
{
bool hasArgument = false;
{
// Check if command is valid. Leave in separate scope to delete the TmpStr1
String TmpStr1;
if (GetArgv(Line, TmpStr1, arg + 1)) {
hasArgument = true;
if (!str2ip(TmpStr1.c_str(), IP)) {
String result = F("Invalid parameter: ");
result += TmpStr1;
return return_result(event, result);
}
}
}
if (!hasArgument) {
serialPrintln();
String result = targetDescription;
if (useStaticIP()) {
result += formatIP(IP);
} else {
result += formatIP(dhcpIP);
result += F("(DHCP)");
}
return return_result(event, result);
}
return return_command_success();
bool hasArgument = false;
{
// Check if command is valid. Leave in separate scope to delete the TmpStr1
String TmpStr1;
if (GetArgv(Line, TmpStr1, arg + 1)) {
hasArgument = true;
if (!str2ip(TmpStr1.c_str(), IP)) {
String result = F("Invalid parameter: ");
result += TmpStr1;
return return_result(event, result);
}
}
}
if (!hasArgument) {
serialPrintln();
String result = targetDescription;
if (useStaticIP()) {
result += formatIP(IP);
} else {
result += formatIP(dhcpIP);
result += F("(DHCP)");
}
return return_result(event, result);
}
return return_command_success();
}
String Command_GetORSetString(struct EventStruct *event,
const __FlashStringHelper *targetDescription,
const char *Line,
char * target,
size_t len,
int arg
)
String Command_GetORSetString(struct EventStruct *event,
const __FlashStringHelper *targetDescription,
const char *Line,
char *target,
size_t len,
int arg
)
{
bool hasArgument = false;
{
// Check if command is valid. Leave in separate scope to delete the TmpStr1
String TmpStr1;
if (GetArgv(Line, TmpStr1, arg + 1)) {
hasArgument = true;
if (TmpStr1.length() > len) {
String result = targetDescription;
result += F(" is too large. max size is ");
result += len;
serialPrintln();
return return_result(event, result);
} else {
strcpy(target, TmpStr1.c_str());
}
}
}
if (hasArgument) {
serialPrintln();
String result = targetDescription;
result += target;
return return_result(event, result);
}
return return_command_success();
bool hasArgument = false;
{
// Check if command is valid. Leave in separate scope to delete the TmpStr1
String TmpStr1;
if (GetArgv(Line, TmpStr1, arg + 1)) {
hasArgument = true;
if (TmpStr1.length() > len) {
String result = targetDescription;
result += F(" is too large. max size is ");
result += len;
serialPrintln();
return return_result(event, result);
} else {
strcpy(target, TmpStr1.c_str());
}
}
}
if (hasArgument) {
serialPrintln();
String result = targetDescription;
result += target;
return return_result(event, result);
}
return return_command_success();
}
String Command_GetORSetBool(struct EventStruct *event,
const __FlashStringHelper *targetDescription,
const char *Line,
bool *value,
int arg)
String Command_GetORSetBool(struct EventStruct *event,
const __FlashStringHelper *targetDescription,
const char *Line,
bool *value,
int arg)
{
bool hasArgument = false;
{
// Check if command is valid. Leave in separate scope to delete the TmpStr1
String TmpStr1;
if (GetArgv(Line, TmpStr1, arg + 1)) {
hasArgument = true;
TmpStr1.toLowerCase();
if (IsNumeric(TmpStr1.c_str())) {
*value = atoi(TmpStr1.c_str()) > 0;
}
else if (strcmp_P(PSTR("on"), TmpStr1.c_str()) == 0) *value = true;
else if (strcmp_P(PSTR("true"), TmpStr1.c_str()) == 0) *value = true;
else if (strcmp_P(PSTR("off"), TmpStr1.c_str()) == 0) *value = false;
else if (strcmp_P(PSTR("false"), TmpStr1.c_str()) == 0) *value = false;
}
}
if (hasArgument) {
String result = targetDescription;
result += toString(*value);
return return_result(event, result);
}
return return_command_success();
bool hasArgument = false;
{
// Check if command is valid. Leave in separate scope to delete the TmpStr1
String TmpStr1;
if (GetArgv(Line, TmpStr1, arg + 1)) {
hasArgument = true;
TmpStr1.toLowerCase();
if (IsNumeric(TmpStr1.c_str())) {
*value = atoi(TmpStr1.c_str()) > 0;
}
else if (strcmp_P(PSTR("on"), TmpStr1.c_str()) == 0) { *value = true; }
else if (strcmp_P(PSTR("true"), TmpStr1.c_str()) == 0) { *value = true; }
else if (strcmp_P(PSTR("off"), TmpStr1.c_str()) == 0) { *value = false; }
else if (strcmp_P(PSTR("false"), TmpStr1.c_str()) == 0) { *value = false; }
}
}
if (hasArgument) {
String result = targetDescription;
result += toString(*value);
return return_result(event, result);
}
return return_command_success();
}
#endif // COMMAND_COMMON_H
+32 -28
View File
@@ -4,44 +4,48 @@
#include "../ESPEasy-Globals.h"
String Command_Rules_Execute(struct EventStruct *event, const char* Line)
String Command_Rules_Execute(struct EventStruct *event, const char *Line)
{
String filename;
if (GetArgv(Line, filename, 2)) {
String event;
rulesProcessingFile(filename, event);
}
return return_command_success();
String filename;
if (GetArgv(Line, filename, 2)) {
String event;
rulesProcessingFile(filename, event);
}
return return_command_success();
}
String Command_Rules_UseRules(struct EventStruct *event, const char* Line)
String Command_Rules_UseRules(struct EventStruct *event, const char *Line)
{
return Command_GetORSetBool(event, F("Rules:"),
Line,
(bool*)&Settings.UseRules,
1);
return Command_GetORSetBool(event, F("Rules:"),
Line,
(bool *)&Settings.UseRules,
1);
}
String Command_Rules_Events(struct EventStruct *event, const char* Line)
String Command_Rules_Events(struct EventStruct *event, const char *Line)
{
String eventName = Line;
eventName = eventName.substring(6);
eventName.replace('$', '#');
if (Settings.UseRules)
rulesProcessing(eventName);
return return_command_success();
String eventName = Line;
eventName = eventName.substring(6);
eventName.replace('$', '#');
if (Settings.UseRules) {
rulesProcessing(eventName);
}
return return_command_success();
}
String Command_Rules_Let(struct EventStruct *event, const char* Line)
String Command_Rules_Let(struct EventStruct *event, const char *Line)
{
String TmpStr1;
if (GetArgv(Line, TmpStr1, 3)) {
float result = 0.0;
Calculate(TmpStr1.c_str(), &result);
customFloatVar[event->Par1-1] = result;
}
return return_command_success();
String TmpStr1;
if (GetArgv(Line, TmpStr1, 3)) {
float result = 0.0;
Calculate(TmpStr1.c_str(), &result);
customFloatVar[event->Par1 - 1] = result;
}
return return_command_success();
}
#endif // COMMAND_RULES_H
+253 -298
View File
@@ -1,12 +1,10 @@
#define RULE_FILE_SEPARAROR '/'
#define RULE_MAX_FILENAME_LENGTH 24
String EventToFileName(String& eventName)
{
String EventToFileName(String &eventName) {
int size = eventName.length();
int index = eventName.indexOf('=');
if(index >- 1)
{
if (index > -1) {
size = index;
}
#if defined(ESP8266)
@@ -15,54 +13,52 @@ String EventToFileName(String& eventName)
#if defined(ESP32)
String fileName = F("/rules/");
#endif
fileName += eventName.substring(0,size);
fileName.replace('#',RULE_FILE_SEPARAROR);
fileName += eventName.substring(0, size);
fileName.replace('#', RULE_FILE_SEPARAROR);
fileName.toLowerCase();
return fileName;
return fileName;
}
String FileNameToEvent(String& fileName)
{
#if defined(ESP8266)
String FileNameToEvent(String &fileName) {
#if defined(ESP8266)
String eventName = fileName.substring(6);
#endif
#if defined(ESP32)
#endif
#if defined(ESP32)
String eventName = fileName.substring(7);
#endif
eventName.replace(RULE_FILE_SEPARAROR,'#');
#endif
eventName.replace(RULE_FILE_SEPARAROR, '#');
return eventName;
}
void checkRuleSets(){
for (byte x=0; x < RULESETS_MAX; x++){
#if defined(ESP8266)
void checkRuleSets() {
for (byte x = 0; x < RULESETS_MAX; x++) {
#if defined(ESP8266)
String fileName = F("rules");
#endif
#if defined(ESP32)
#endif
#if defined(ESP32)
String fileName = F("/rules");
#endif
fileName += x+1;
fileName += F(".txt");
if (SPIFFS.exists(fileName))
activeRuleSets[x] = true;
else
activeRuleSets[x] = false;
#endif
fileName += x + 1;
fileName += F(".txt");
if (SPIFFS.exists(fileName))
activeRuleSets[x] = true;
else
activeRuleSets[x] = false;
if (Settings.SerialLogLevel == LOG_LEVEL_DEBUG_DEV){
serialPrint(fileName);
serialPrint(" ");
serialPrintln(String(activeRuleSets[x]));
if (Settings.SerialLogLevel == LOG_LEVEL_DEBUG_DEV) {
serialPrint(fileName);
serialPrint(" ");
serialPrintln(String(activeRuleSets[x]));
}
}
}
/********************************************************************************************\
Rules processing
\*********************************************************************************************/
void rulesProcessing(String& event)
{
if (!Settings.UseRules) return;
void rulesProcessing(String &event) {
if (!Settings.UseRules)
return;
checkRAM(F("rulesProcessing"));
unsigned long timer = millis();
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
@@ -72,31 +68,27 @@ void rulesProcessing(String& event)
}
if (Settings.OldRulesEngine()) {
for (byte x = 0; x < RULESETS_MAX; x++)
{
#if defined(ESP8266)
String fileName = F("rules");
#endif
#if defined(ESP32)
String fileName = F("/rules");
#endif
fileName += x+1;
for (byte x = 0; x < RULESETS_MAX; x++) {
#if defined(ESP8266)
String fileName = F("rules");
#endif
#if defined(ESP32)
String fileName = F("/rules");
#endif
fileName += x + 1;
fileName += F(".txt");
if(activeRuleSets[x])
if (activeRuleSets[x])
rulesProcessingFile(fileName, event);
}
}
else
{
} else {
String fileName = EventToFileName(event);
//if exists processed the rule file
if(SPIFFS.exists(fileName))
rulesProcessingFile(fileName, event);
// if exists processed the rule file
if (SPIFFS.exists(fileName))
rulesProcessingFile(fileName, event);
else
addLog(LOG_LEVEL_DEBUG
, String(F("EVENT: ")) + event
+ String(F(" is ingnored. File ")) + fileName
+ String(F(" not found.")));
addLog(LOG_LEVEL_DEBUG, String(F("EVENT: ")) + event +
String(F(" is ingnored. File ")) + fileName +
String(F(" not found.")));
}
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
@@ -108,17 +100,16 @@ void rulesProcessing(String& event)
addLog(LOG_LEVEL_DEBUG, log);
}
backgroundtasks();
}
/********************************************************************************************\
Rules processing
\*********************************************************************************************/
String rulesProcessingFile(const String& fileName, String& event)
{
if (!Settings.UseRules) return "";
String rulesProcessingFile(const String &fileName, String &event) {
if (!Settings.UseRules)
return "";
checkRAM(F("rulesProcessingFile"));
if (Settings.SerialLogLevel == LOG_LEVEL_DEBUG_DEV){
if (Settings.SerialLogLevel == LOG_LEVEL_DEBUG_DEV) {
serialPrint(F("RuleDebug Processing:"));
serialPrintln(fileName);
serialPrintln(F(" flags CMI parse output:"));
@@ -129,8 +120,7 @@ String rulesProcessingFile(const String& fileName, String& event)
String log = "";
nestingLevel++;
if (nestingLevel > RULES_MAX_NESTING_LEVEL)
{
if (nestingLevel > RULES_MAX_NESTING_LEVEL) {
addLog(LOG_LEVEL_ERROR, F("EVENT: Error: Nesting level exceeded!"));
nestingLevel--;
return (log);
@@ -148,12 +138,10 @@ String rulesProcessingFile(const String& fileName, String& event)
byte ifBlock = 0;
byte fakeIfBlock = 0;
byte *buf = new byte[RULES_BUFFER_SIZE]();
int len = 0;
while (f.available())
{
len = f.read((byte*)buf, RULES_BUFFER_SIZE);
while (f.available()) {
len = f.read((byte *)buf, RULES_BUFFER_SIZE);
for (int x = 0; x < len; x++) {
data = buf[x];
@@ -161,17 +149,12 @@ String rulesProcessingFile(const String& fileName, String& event)
if (data != 10) {
line += char(data);
}
else
{ // if line complete, parse this rule
} else { // if line complete, parse this rule
line.replace("\r", "");
if (line.substring(0, 2) != F("//") && line.length() > 0)
{
parseCompleteNonCommentLine(
line, event, log,
match, codeBlock, isCommand,
condition, ifBranche,
ifBlock, fakeIfBlock);
if (line.substring(0, 2) != F("//") && line.length() > 0) {
parseCompleteNonCommentLine(line, event, log, match, codeBlock,
isCommand, condition, ifBranche, ifBlock,
fakeIfBlock);
backgroundtasks();
}
@@ -180,25 +163,18 @@ String rulesProcessingFile(const String& fileName, String& event)
}
}
delete[] buf;
if (f) f.close();
if (f)
f.close();
nestingLevel--;
checkRAM(F("rulesProcessingFile2"));
return ("");
}
void parseCompleteNonCommentLine(
String& line,
String& event,
String& log,
bool& match,
bool& codeBlock,
bool& isCommand,
bool condition[],
bool ifBranche[],
byte& ifBlock,
byte& fakeIfBlock)
{
void parseCompleteNonCommentLine(String &line, String &event, String &log,
bool &match, bool &codeBlock, bool &isCommand,
bool condition[], bool ifBranche[],
byte &ifBlock, byte &fakeIfBlock) {
isCommand = true;
// Strip comments
@@ -207,31 +183,43 @@ void parseCompleteNonCommentLine(
line = line.substring(0, comment);
if (match || !codeBlock) {
// only parse [xxx#yyy] if we have a matching ruleblock or need to eval the "on" (no codeBlock)
// only parse [xxx#yyy] if we have a matching ruleblock or need to eval the
// "on" (no codeBlock)
// This to avoid waisting CPU time...
if (match && !fakeIfBlock) {
// substitution of %eventvalue% is made here so it can be used on if statement too
if (event.charAt(0) == '!')
{
line.replace(F("%eventvalue%"), event); // substitute %eventvalue% with literal event string if starting with '!'
}
else
{
// substitution of %eventvalue% is made here so it can be used on if
// statement too
if (event.charAt(0) == '!') {
line.replace(F("%eventvalue%"), event); // substitute %eventvalue% with
// literal event string if
// starting with '!'
} else {
int equalsPos = event.indexOf("=");
if (equalsPos > 0)
{
if (equalsPos > 0) {
String tmpString = event.substring(equalsPos + 1);
//line.replace(F("%eventvalue%"), tmpString); // substitute %eventvalue% with the actual value from the event
// line.replace(F("%eventvalue%"), tmpString); // substitute
// %eventvalue% with the actual value from the event
String tmpParam;
if (GetArgv(tmpString.c_str(),tmpParam,1)) {
line.replace(F("%eventvalue%"), tmpParam); // for compatibility issues
line.replace(F("%eventvalue1%"), tmpParam); // substitute %eventvalue1% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(), tmpParam, 1)) {
line.replace(F("%eventvalue%"),
tmpParam); // for compatibility issues
line.replace(F("%eventvalue1%"),
tmpParam); // substitute %eventvalue1% in actions with
// the actual value from the event
}
if (GetArgv(tmpString.c_str(),tmpParam,2)) line.replace(F("%eventvalue2%"), tmpParam); // substitute %eventvalue2% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(),tmpParam,3)) line.replace(F("%eventvalue3%"), tmpParam); // substitute %eventvalue3% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(),tmpParam,4)) line.replace(F("%eventvalue4%"), tmpParam); // substitute %eventvalue4% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(), tmpParam, 2))
line.replace(F("%eventvalue2%"),
tmpParam); // substitute %eventvalue2% in actions with
// the actual value from the event
if (GetArgv(tmpString.c_str(), tmpParam, 3))
line.replace(F("%eventvalue3%"),
tmpParam); // substitute %eventvalue3% in actions with
// the actual value from the event
if (GetArgv(tmpString.c_str(), tmpParam, 4))
line.replace(F("%eventvalue4%"),
tmpParam); // substitute %eventvalue4% in actions with
// the actual value from the event
}
}
}
@@ -240,22 +228,20 @@ void parseCompleteNonCommentLine(
line.trim();
String lineOrg = line; // store original line for future use
line.toLowerCase(); // convert all to lower case to make checks easier
line.toLowerCase(); // convert all to lower case to make checks easier
String eventTrigger = "";
String action = "";
if (!codeBlock) // do not check "on" rules if a block of actions is to be processed
if (!codeBlock) // do not check "on" rules if a block of actions is to be
// processed
{
if (line.startsWith(F("on ")))
{
if (line.startsWith(F("on "))) {
ifBlock = 0;
fakeIfBlock = 0;
line = line.substring(3);
int split = line.indexOf(F(" do"));
if (split != -1)
{
if (split != -1) {
eventTrigger = line.substring(0, split);
action = lineOrg.substring(split + 7);
action.trim();
@@ -268,22 +254,19 @@ void parseCompleteNonCommentLine(
{
isCommand = true;
codeBlock = false;
}
else
{
} else {
isCommand = false;
codeBlock = true;
}
}
}
else
{
} else {
action = lineOrg;
}
String lcAction = action;
lcAction.toLowerCase();
if (lcAction == F("endon")) // Check if action block has ended, then we will wait for a new "on" rule
if (lcAction == F("endon")) // Check if action block has ended, then we will
// wait for a new "on" rule
{
isCommand = false;
codeBlock = false;
@@ -304,84 +287,64 @@ void parseCompleteNonCommentLine(
if (match) // rule matched for one action or a block of actions
{
processMatchedRule(
lcAction, action, event, log,
match, codeBlock, isCommand,
condition, ifBranche,
ifBlock, fakeIfBlock);
processMatchedRule(lcAction, action, event, log, match, codeBlock,
isCommand, condition, ifBranche, ifBlock, fakeIfBlock);
}
}
void processMatchedRule(
String& lcAction, String& action, String& event, String& log,
bool& match,
bool& codeBlock,
bool& isCommand,
bool condition[],
bool ifBranche[],
byte& ifBlock,
byte& fakeIfBlock)
{
void processMatchedRule(String &lcAction, String &action, String &event,
String &log, bool &match, bool &codeBlock,
bool &isCommand, bool condition[], bool ifBranche[],
byte &ifBlock, byte &fakeIfBlock) {
if (fakeIfBlock)
isCommand = false;
else if (ifBlock)
if (condition[ifBlock-1] != ifBranche[ifBlock-1])
if (condition[ifBlock - 1] != ifBranche[ifBlock - 1])
isCommand = false;
int split = lcAction.indexOf(F("elseif ")); // check for optional "elseif" condition
if (split != -1)
{
int split =
lcAction.indexOf(F("elseif ")); // check for optional "elseif" condition
if (split != -1) {
isCommand = false;
if (ifBlock && !fakeIfBlock)
{
if (ifBranche[ifBlock-1])
{
if (condition[ifBlock-1])
ifBranche[ifBlock-1] = false;
else
{
if (ifBlock && !fakeIfBlock) {
if (ifBranche[ifBlock - 1]) {
if (condition[ifBlock - 1])
ifBranche[ifBlock - 1] = false;
else {
String check = lcAction.substring(split + 7);
condition[ifBlock-1] = conditionMatchExtended(check);
condition[ifBlock - 1] = conditionMatchExtended(check);
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
log = F("Lev.");
log += String(ifBlock);
log += F(": [elseif ");
log += check;
log += F("]=");
log += toString(condition[ifBlock-1]);
log += toString(condition[ifBlock - 1]);
addLog(LOG_LEVEL_DEBUG, log);
}
}
}
}
}
else
{
} else {
split = lcAction.indexOf(F("if ")); // check for optional "if" condition
if (split != -1)
{
if (ifBlock < RULES_IF_MAX_NESTING_LEVEL)
{
if (isCommand)
{
if (split != -1) {
if (ifBlock < RULES_IF_MAX_NESTING_LEVEL) {
if (isCommand) {
ifBlock++;
String check = lcAction.substring(split + 3);
condition[ifBlock-1] = conditionMatchExtended(check);
ifBranche[ifBlock-1] = true;
condition[ifBlock - 1] = conditionMatchExtended(check);
ifBranche[ifBlock - 1] = true;
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
log = F("Lev.");
log += String(ifBlock);
log += F(": [if ");
log += check;
log += F("]=");
log += toString(condition[ifBlock-1]);
log += toString(condition[ifBlock - 1]);
addLog(LOG_LEVEL_DEBUG, log);
}
}
else
} else
fakeIfBlock++;
}
else
{
} else {
fakeIfBlock++;
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
log = F("Lev.");
@@ -394,15 +357,17 @@ void processMatchedRule(
}
}
if ((lcAction == F("else")) && !fakeIfBlock) // in case of an "else" block of actions, set ifBranche to false
if ((lcAction == F("else")) && !fakeIfBlock) // in case of an "else" block of
// actions, set ifBranche to
// false
{
ifBranche[ifBlock-1] = false;
ifBranche[ifBlock - 1] = false;
isCommand = false;
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
log = F("Lev.");
log += String(ifBlock);
log += F(": [else]=");
log += toString(condition[ifBlock-1] == ifBranche[ifBlock-1]);
log += toString(condition[ifBlock - 1] == ifBranche[ifBlock - 1]);
addLog(LOG_LEVEL_DEBUG, log);
}
}
@@ -416,29 +381,39 @@ void processMatchedRule(
isCommand = false;
}
// process the action if it's a command and unconditional, or conditional and the condition matches the if or else block.
if (isCommand)
{
if (event.charAt(0) == '!')
{
action.replace(F("%eventvalue%"), event); // substitute %eventvalue% with literal event string if starting with '!'
}
else
{
// process the action if it's a command and unconditional, or conditional and
// the condition matches the if or else block.
if (isCommand) {
if (event.charAt(0) == '!') {
action.replace(F("%eventvalue%"), event); // substitute %eventvalue% with
// literal event string if
// starting with '!'
} else {
int equalsPos = event.indexOf("=");
if (equalsPos > 0)
{
if (equalsPos > 0) {
String tmpString = event.substring(equalsPos + 1);
String tmpParam;
if (GetArgv(tmpString.c_str(),tmpParam,1)) {
action.replace(F("%eventvalue%"), tmpParam); // for compatibility issues
action.replace(F("%eventvalue1%"), tmpParam); // substitute %eventvalue1% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(), tmpParam, 1)) {
action.replace(F("%eventvalue%"),
tmpParam); // for compatibility issues
action.replace(F("%eventvalue1%"),
tmpParam); // substitute %eventvalue1% in actions with
// the actual value from the event
}
if (GetArgv(tmpString.c_str(),tmpParam,2)) action.replace(F("%eventvalue2%"), tmpParam); // substitute %eventvalue2% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(),tmpParam,3)) action.replace(F("%eventvalue3%"), tmpParam); // substitute %eventvalue3% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(),tmpParam,4)) action.replace(F("%eventvalue4%"), tmpParam); // substitute %eventvalue4% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(), tmpParam, 2))
action.replace(F("%eventvalue2%"),
tmpParam); // substitute %eventvalue2% in actions with
// the actual value from the event
if (GetArgv(tmpString.c_str(), tmpParam, 3))
action.replace(F("%eventvalue3%"),
tmpParam); // substitute %eventvalue3% in actions with
// the actual value from the event
if (GetArgv(tmpString.c_str(), tmpParam, 4))
action.replace(F("%eventvalue4%"),
tmpParam); // substitute %eventvalue4% in actions with
// the actual value from the event
}
}
@@ -455,7 +430,8 @@ void processMatchedRule(
// It can't schedule a call to PLUGIN_WRITE.
// Maybe ExecuteCommand can be scheduled?
delay(0);
// Use a tmp string to call PLUGIN_WRITE, since PluginCall may inadvertenly alter the string.
// Use a tmp string to call PLUGIN_WRITE, since PluginCall may inadvertenly
// alter the string.
String tmpAction(action);
if (!PluginCall(PLUGIN_WRITE, &TempEvent, tmpAction)) {
if (!tmpAction.equals(action)) {
@@ -477,35 +453,32 @@ void processMatchedRule(
/********************************************************************************************\
Check if an event matches to a given rule
\*********************************************************************************************/
boolean ruleMatch(String& event, String& rule)
{
boolean ruleMatch(String &event, String &rule) {
checkRAM(F("ruleMatch"));
boolean match = false;
String tmpEvent = event;
String tmpRule = rule;
//Ignore escape char
tmpRule.replace("[","");
tmpRule.replace("]","");
// Ignore escape char
tmpRule.replace("[", "");
tmpRule.replace("]", "");
// Special handling of literal string events, they should start with '!'
if (event.charAt(0) == '!')
{
if (event.charAt(0) == '!') {
int pos = rule.indexOf('*');
if (pos != -1) // a * sign in rule, so use a'wildcard' match on message
{
tmpEvent = event.substring(0, pos - 1);
tmpRule = rule.substring(0, pos - 1);
} else {
pos = rule.indexOf('#');
if (pos ==
-1) // no # sign in rule, use 'wildcard' match on event 'source'
{
tmpEvent = event.substring(0,pos-1);
tmpRule = rule.substring(0,pos-1);
}
else
{
pos = rule.indexOf('#');
if (pos == -1) // no # sign in rule, use 'wildcard' match on event 'source'
{
tmpEvent = event.substring(0,rule.length());
tmpRule = rule;
}
tmpEvent = event.substring(0, rule.length());
tmpRule = rule;
}
}
if (tmpEvent.equalsIgnoreCase(tmpRule))
return true;
@@ -513,18 +486,18 @@ boolean ruleMatch(String& event, String& rule)
return false;
}
if (event.startsWith(F("Clock#Time"))) // clock events need different handling...
if (event.startsWith(
F("Clock#Time"))) // clock events need different handling...
{
int pos1 = event.indexOf("=");
int pos2 = rule.indexOf("=");
if (pos1 > 0 && pos2 > 0)
{
if (pos1 > 0 && pos2 > 0) {
tmpEvent = event.substring(0, pos1);
tmpRule = rule.substring(0, pos2);
tmpRule = rule.substring(0, pos2);
if (tmpRule.equalsIgnoreCase(tmpEvent)) // if this is a clock rule
{
tmpEvent = event.substring(pos1 + 1);
tmpRule = rule.substring(pos2 + 1);
tmpRule = rule.substring(pos2 + 1);
unsigned long clockEvent = string2TimeLong(tmpEvent);
unsigned long clockSet = string2TimeLong(tmpRule);
if (matchClockEvent(clockEvent, clockSet))
@@ -535,12 +508,10 @@ boolean ruleMatch(String& event, String& rule)
}
}
// parse event into verb and value
float value = 0;
int pos = event.indexOf("=");
if (pos)
{
if (pos) {
tmpEvent = event.substring(pos + 1);
value = tmpEvent.toFloat();
tmpEvent = event.substring(0, pos);
@@ -550,22 +521,15 @@ boolean ruleMatch(String& event, String& rule)
int comparePos = 0;
char compare = ' ';
comparePos = rule.indexOf(">");
if (comparePos > 0)
{
if (comparePos > 0) {
compare = '>';
}
else
{
} else {
comparePos = rule.indexOf("<");
if (comparePos > 0)
{
if (comparePos > 0) {
compare = '<';
}
else
{
} else {
comparePos = rule.indexOf("=");
if (comparePos > 0)
{
if (comparePos > 0) {
compare = '=';
}
}
@@ -573,45 +537,42 @@ boolean ruleMatch(String& event, String& rule)
float ruleValue = 0;
if (comparePos > 0)
{
if (comparePos > 0) {
tmpRule = rule.substring(comparePos + 1);
ruleValue = tmpRule.toFloat();
tmpRule = rule.substring(0, comparePos);
}
switch (compare)
{
case '>':
if (tmpRule.equalsIgnoreCase(tmpEvent) && value > ruleValue)
match = true;
break;
switch (compare) {
case '>':
if (tmpRule.equalsIgnoreCase(tmpEvent) && value > ruleValue)
match = true;
break;
case '<':
if (tmpRule.equalsIgnoreCase(tmpEvent) && value < ruleValue)
match = true;
break;
case '<':
if (tmpRule.equalsIgnoreCase(tmpEvent) && value < ruleValue)
match = true;
break;
case '=':
if (tmpRule.equalsIgnoreCase(tmpEvent) && value == ruleValue)
match = true;
break;
case '=':
if (tmpRule.equalsIgnoreCase(tmpEvent) && value == ruleValue)
match = true;
break;
case ' ':
if (tmpRule.equalsIgnoreCase(tmpEvent))
match = true;
break;
case ' ':
if (tmpRule.equalsIgnoreCase(tmpEvent))
match = true;
break;
}
checkRAM(F("ruleMatch2"));
return match;
}
/********************************************************************************************\
Check expression
\*********************************************************************************************/
boolean conditionMatchExtended(String& check) {
boolean conditionMatchExtended(String &check) {
int condAnd = -1;
int condOr = -1;
boolean rightcond = false;
@@ -619,14 +580,15 @@ boolean conditionMatchExtended(String& check) {
do {
condAnd = check.indexOf(F(" and "));
condOr = check.indexOf(F(" or "));
condOr = check.indexOf(F(" or "));
if (condAnd > 0 || condOr > 0) { // we got AND/OR
if (condAnd > 0 && ((condOr < 0 && condOr < condAnd) || (condOr > 0 && condOr > condAnd))) { //AND is first
if (condAnd > 0 && ((condOr < 0 && condOr < condAnd) ||
(condOr > 0 && condOr > condAnd))) { // AND is first
check = check.substring(condAnd + 5);
rightcond = conditionMatch(check);
leftcond = (leftcond && rightcond);
} else { //OR is first
} else { // OR is first
check = check.substring(condOr + 4);
rightcond = conditionMatch(check);
leftcond = (leftcond || rightcond);
@@ -636,83 +598,79 @@ boolean conditionMatchExtended(String& check) {
return leftcond;
}
boolean conditionMatch(const String& check)
{
boolean conditionMatch(const String &check) {
boolean match = false;
char compare = ' ';
char compare = ' ';
int posStart = check.length();
int posEnd = posStart;
int comparePos = 0;
int comparePos = 0;
if ((comparePos = check.indexOf("!="))>0 && comparePos<posStart) {
if ((comparePos = check.indexOf("!=")) > 0 && comparePos < posStart) {
posStart = comparePos;
posEnd = posStart+2;
compare = '!'+'=';
posEnd = posStart + 2;
compare = '!' + '=';
}
if ((comparePos = check.indexOf("<>"))>0 && comparePos<posStart) {
if ((comparePos = check.indexOf("<>")) > 0 && comparePos < posStart) {
posStart = comparePos;
posEnd = posStart+2;
compare = '!'+'=';
posEnd = posStart + 2;
compare = '!' + '=';
}
if ((comparePos = check.indexOf(">="))>0 && comparePos<posStart) {
if ((comparePos = check.indexOf(">=")) > 0 && comparePos < posStart) {
posStart = comparePos;
posEnd = posStart+2;
compare = '>'+'=';
posEnd = posStart + 2;
compare = '>' + '=';
}
if ((comparePos = check.indexOf("<="))>0 && comparePos<posStart) {
if ((comparePos = check.indexOf("<=")) > 0 && comparePos < posStart) {
posStart = comparePos;
posEnd = posStart+2;
compare = '<'+'=';
posEnd = posStart + 2;
compare = '<' + '=';
}
if ((comparePos = check.indexOf("<"))>0 && comparePos<posStart) {
if ((comparePos = check.indexOf("<")) > 0 && comparePos < posStart) {
posStart = comparePos;
posEnd = posStart+1;
posEnd = posStart + 1;
compare = '<';
}
if ((comparePos = check.indexOf(">"))>0 && comparePos<posStart) {
if ((comparePos = check.indexOf(">")) > 0 && comparePos < posStart) {
posStart = comparePos;
posEnd = posStart+1;
posEnd = posStart + 1;
compare = '>';
}
if ((comparePos = check.indexOf("="))>0 && comparePos<posStart) {
if ((comparePos = check.indexOf("=")) > 0 && comparePos < posStart) {
posStart = comparePos;
posEnd = posStart+1;
posEnd = posStart + 1;
compare = '=';
}
float Value1 = 0;
float Value2 = 0;
if (compare > ' ')
{
if (compare > ' ') {
String tmpCheck1 = check.substring(0, posStart);
String tmpCheck2 = check.substring(posEnd);
if (!isFloat(tmpCheck1) || !isFloat(tmpCheck2)) {
Value1 = timeStringToSeconds(tmpCheck1);
Value2 = timeStringToSeconds(tmpCheck2);
Value1 = timeStringToSeconds(tmpCheck1);
Value2 = timeStringToSeconds(tmpCheck2);
} else {
Value1 = tmpCheck1.toFloat();
Value2 = tmpCheck2.toFloat();
Value1 = tmpCheck1.toFloat();
Value2 = tmpCheck2.toFloat();
}
}
else
} else
return false;
switch (compare)
{
case '>'+'=':
switch (compare) {
case '>' + '=':
if (Value1 >= Value2)
match = true;
break;
case '<'+'=':
case '<' + '=':
if (Value1 <= Value2)
match = true;
break;
case '!'+'=':
case '!' + '=':
if (Value1 != Value2)
match = true;
break;
@@ -735,15 +693,13 @@ boolean conditionMatch(const String& check)
return match;
}
/********************************************************************************************\
Check rule timers
\*********************************************************************************************/
void rulesTimers()
{
if (!Settings.UseRules) return;
for (byte x = 0; x < RULES_TIMER_MAX; x++)
{
void rulesTimers() {
if (!Settings.UseRules)
return;
for (byte x = 0; x < RULES_TIMER_MAX; x++) {
if (!RulesTimer[x].paused && RulesTimer[x].timestamp != 0L) // timer active?
{
if (timeOutReached(RulesTimer[x].timestamp)) // timer finished?
@@ -757,27 +713,26 @@ void rulesTimers()
}
}
/********************************************************************************************\
Generate rule events based on task refresh
\*********************************************************************************************/
void createRuleEvents(byte TaskIndex)
{
if (!Settings.UseRules) return;
void createRuleEvents(byte TaskIndex) {
if (!Settings.UseRules)
return;
LoadTaskSettings(TaskIndex);
byte BaseVarIndex = TaskIndex * VARS_PER_TASK;
byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[TaskIndex]);
byte sensorType = Device[DeviceIndex].VType;
for (byte varNr = 0; varNr < Device[DeviceIndex].ValueCount; varNr++)
{
for (byte varNr = 0; varNr < Device[DeviceIndex].ValueCount; varNr++) {
String eventString = getTaskDeviceName(TaskIndex);
eventString += F("#");
eventString += ExtraTaskSettings.TaskDeviceValueNames[varNr];
eventString += F("=");
if (sensorType == SENSOR_TYPE_LONG)
eventString += (unsigned long)UserVar[BaseVarIndex] + ((unsigned long)UserVar[BaseVarIndex + 1] << 16);
eventString += (unsigned long)UserVar[BaseVarIndex] +
((unsigned long)UserVar[BaseVarIndex + 1] << 16);
else
eventString += UserVar[BaseVarIndex + varNr];
+243
View File
@@ -0,0 +1,243 @@
indent_align_string=true
indent_braces=false
indent_braces_no_func=false
indent_brace_parent=false
indent_namespace=false
indent_extern=false
indent_class=true
indent_class_colon=true
indent_else_if=false
indent_func_call_param=false
indent_func_def_param=false
indent_func_proto_param=false
indent_func_class_param=false
indent_func_ctor_var_param=false
indent_template_param=false
indent_func_param_double=false
indent_relative_single_line_comments=false
indent_col1_comment=true
indent_access_spec_body=false
indent_paren_nl=false
indent_comma_paren=false
indent_bool_paren=false
indent_square_nl=false
indent_preserve_sql=false
indent_align_assign=true
sp_balance_nested_parens=false
align_keep_tabs=false
align_with_tabs=false
align_on_tabstop=false
align_func_params=true
align_same_func_call_params=true
align_var_def_colon=true
align_var_def_attribute=true
align_var_def_inline=true
align_right_cmt_mix=false
align_on_operator=true
align_mix_var_proto=false
align_single_line_func=true
align_single_line_brace=true
align_nl_cont=true
align_left_shift=true
nl_collapse_empty_body=true
nl_assign_leave_one_liners=false
nl_class_leave_one_liners=false
nl_enum_leave_one_liners=false
nl_getset_leave_one_liners=false
nl_func_leave_one_liners=false
nl_if_leave_one_liners=false
nl_multi_line_cond=false
nl_multi_line_define=false
nl_before_case=false
nl_after_case=false
nl_after_return=false
nl_after_semicolon=false
nl_after_brace_open=false
nl_after_brace_open_cmt=false
nl_after_vbrace_open=false
nl_after_brace_close=false
nl_define_macro=true
nl_squeeze_ifdef=false
nl_ds_struct_enum_cmt=true
nl_ds_struct_enum_close_brace=true
nl_create_if_one_liner=true
nl_create_for_one_liner=true
nl_create_while_one_liner=true
ls_for_split_full=false
ls_func_split_full=true
nl_after_multiline_comment=true
eat_blanks_after_open_brace=true
eat_blanks_before_close_brace=true
mod_pawn_semicolon=false
mod_full_paren_if_bool=true
mod_remove_extra_semicolon=true
mod_sort_import=false
mod_sort_using=false
mod_sort_include=false
mod_move_case_break=true
mod_remove_empty_return=true
cmt_indent_multi=true
cmt_c_group=false
cmt_c_nl_start=false
cmt_c_nl_end=false
cmt_cpp_group=false
cmt_cpp_nl_start=false
cmt_cpp_nl_end=false
cmt_cpp_to_c=false
cmt_star_cont=false
cmt_multi_check_last=true
cmt_insert_before_preproc=false
pp_indent_at_level=false
pp_region_indent_code=false
pp_if_indent_code=false
pp_define_at_level=false
indent_columns=2
align_var_def_span=1
align_var_def_star_style=2
align_var_def_amp_style=2
align_var_def_thresh=3
align_var_def_gap=1
align_assign_span=1
align_enum_equ_span=1
align_var_struct_span=1
align_struct_init_span=1
align_typedef_span=1
align_typedef_star_style=2
align_typedef_amp_style=2
align_right_cmt_span=4
align_right_cmt_at_col=1
align_func_proto_span=3
nl_end_of_file_min=1
nl_func_var_def_blk=1
code_width=142
nl_max=3
nl_after_func_proto=0
nl_after_func_body=2
nl_after_func_body_one_liner=2
nl_before_block_comment=2
nl_before_c_comment=2
nl_before_cpp_comment=2
nl_before_access_spec=2
nl_after_access_spec=2
nl_comment_func_def=1
nl_after_try_catch_finally=1
mod_full_brace_nl=1
mod_add_long_ifdef_endif_comment=1
mod_add_long_ifdef_else_comment=1
cmt_width=140
newlines=auto
indent_with_tabs=0
sp_arith=add
sp_assign=add
sp_enum_assign=add
sp_pp_concat=add
sp_pp_stringify=add
sp_bool=add
sp_compare=add
sp_inside_paren=remove
sp_paren_paren=remove
sp_paren_brace=add
sp_before_ptr_star=add
sp_before_unnamed_ptr_star=add
sp_between_ptr_star=remove
sp_after_ptr_star=remove
sp_after_ptr_star_func=add
sp_before_ptr_star_func=remove
sp_before_byref=remove
sp_before_unnamed_byref=remove
sp_after_byref=add
sp_after_byref_func=add
sp_before_byref_func=remove
sp_after_type=add
sp_before_angle=remove
sp_inside_angle=remove
sp_after_angle=remove
sp_angle_paren=remove
sp_angle_word=remove
sp_before_sparen=add
sp_inside_sparen=remove
sp_sparen_brace=add
sp_special_semi=remove
sp_before_semi=remove
sp_before_semi_for=remove
sp_before_semi_for_empty=remove
sp_after_semi_for_empty=remove
sp_before_square=remove
sp_before_squares=remove
sp_inside_square=remove
sp_after_comma=add
sp_before_comma=remove
sp_after_class_colon=add
sp_before_class_colon=add
sp_before_case_colon=remove
sp_after_operator=remove
sp_after_operator_sym=remove
sp_after_cast=remove
sp_inside_paren_cast=remove
sp_cpp_cast_paren=remove
sp_sizeof_paren=remove
sp_inside_braces_enum=add
sp_inside_braces_struct=add
sp_inside_braces=add
sp_inside_braces_empty=remove
sp_type_func=add
sp_func_proto_paren=remove
sp_func_def_paren=remove
sp_inside_fparens=remove
sp_inside_fparen=remove
sp_square_fparen=remove
sp_fparen_brace=add
sp_func_call_paren=remove
sp_func_call_user_paren=remove
sp_func_class_paren=remove
sp_return_paren=add
sp_attribute_paren=remove
sp_defined_paren=remove
sp_throw_paren=remove
sp_macro=add
sp_macro_func=remove
sp_else_brace=add
sp_brace_else=add
sp_brace_typedef=add
sp_catch_brace=add
sp_brace_catch=add
sp_finally_brace=add
sp_brace_finally=add
sp_try_brace=add
sp_getset_brace=add
sp_before_dc=remove
sp_after_dc=remove
sp_not=remove
sp_inv=remove
sp_addr=remove
sp_member=remove
sp_deref=remove
sp_sign=remove
sp_incdec=remove
sp_before_nl_cont=remove
sp_after_oc_scope=remove
sp_after_oc_colon=remove
sp_before_oc_colon=remove
sp_after_send_oc_colon=add
sp_before_send_oc_colon=remove
sp_after_oc_type=remove
sp_cond_colon=add
sp_cond_question=add
sp_cmt_cpp_start=add
nl_end_of_file=add
nl_namespace_brace=remove
nl_class_brace=remove
nl_class_init_args=add
nl_func_decl_args=add
nl_before_if=add
nl_before_for=add
nl_before_while=add
nl_before_switch=add
nl_before_do=add
mod_full_brace_do=add
mod_full_brace_for=add
mod_full_brace_if=add
mod_full_brace_while=add
mod_full_brace_if_chain=false
mod_paren_on_return=remove
pp_space=add