mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 04:07:47 +00:00
[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:
+113
-101
@@ -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
@@ -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
@@ -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];
|
||||
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user