mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-27 08:17:16 +00:00
Refactored rules USE_EXPRESSION and SUPPORT_IF_STATEMENT replacing LinkedList with arrays
This commit is contained in:
parent
d531583721
commit
a74200d40d
@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Refactored rules ``Subscribe`` using LList allowing full message size and enabled by default
|
- Refactored rules ``Subscribe`` using LList allowing full message size and enabled by default
|
||||||
|
- Refactored rules USE_EXPRESSION and SUPPORT_IF_STATEMENT replacing LinkedList with arrays
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -165,6 +165,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
|||||||
- ESP32 platform update from 2023.11.01 to 2024.01.01 [#20473](https://github.com/arendst/Tasmota/issues/20473)
|
- ESP32 platform update from 2023.11.01 to 2024.01.01 [#20473](https://github.com/arendst/Tasmota/issues/20473)
|
||||||
- Renamed button "Consoles" to "Tools"
|
- Renamed button "Consoles" to "Tools"
|
||||||
- Refactored rule ``Subscribe`` using LList allowing full message size and enabled by default
|
- Refactored rule ``Subscribe`` using LList allowing full message size and enabled by default
|
||||||
|
- Refactored rules USE_EXPRESSION and SUPPORT_IF_STATEMENT replacing LinkedList with arrays
|
||||||
- Support syslog updates every sleep or every second if `#define SYSLOG_UPDATE_SECOND` [#20260](https://github.com/arendst/Tasmota/issues/20260)
|
- Support syslog updates every sleep or every second if `#define SYSLOG_UPDATE_SECOND` [#20260](https://github.com/arendst/Tasmota/issues/20260)
|
||||||
- Web file upload response on upload error [#20340](https://github.com/arendst/Tasmota/issues/20340)
|
- Web file upload response on upload error [#20340](https://github.com/arendst/Tasmota/issues/20340)
|
||||||
- Header `Host` is now collected by Webserver [#20446](https://github.com/arendst/Tasmota/issues/20446)
|
- Header `Host` is now collected by Webserver [#20446](https://github.com/arendst/Tasmota/issues/20446)
|
||||||
|
@ -114,8 +114,6 @@
|
|||||||
const char kCompareOperators[] PROGMEM = "=\0>\0<\0|\0==!=>=<=$>$<$|$!$^";
|
const char kCompareOperators[] PROGMEM = "=\0>\0<\0|\0==!=>=<=$>$<$|$!$^";
|
||||||
|
|
||||||
#ifdef USE_EXPRESSION
|
#ifdef USE_EXPRESSION
|
||||||
#include <LinkedList.h> // Import LinkedList library
|
|
||||||
|
|
||||||
const char kExpressionOperators[] PROGMEM = "+-*/%^\0";
|
const char kExpressionOperators[] PROGMEM = "+-*/%^\0";
|
||||||
#define EXPRESSION_OPERATOR_ADD 0
|
#define EXPRESSION_OPERATOR_ADD 0
|
||||||
#define EXPRESSION_OPERATOR_SUBTRACT 1
|
#define EXPRESSION_OPERATOR_SUBTRACT 1
|
||||||
@ -127,7 +125,6 @@ const char kCompareOperators[] PROGMEM = "=\0>\0<\0|\0==!=>=<=$>$<$|$!$^";
|
|||||||
const uint8_t kExpressionOperatorsPriorities[] PROGMEM = {1, 1, 2, 2, 3, 4};
|
const uint8_t kExpressionOperatorsPriorities[] PROGMEM = {1, 1, 2, 2, 3, 4};
|
||||||
#define MAX_EXPRESSION_OPERATOR_PRIORITY 4
|
#define MAX_EXPRESSION_OPERATOR_PRIORITY 4
|
||||||
|
|
||||||
|
|
||||||
#define LOGIC_OPERATOR_AND 1
|
#define LOGIC_OPERATOR_AND 1
|
||||||
#define LOGIC_OPERATOR_OR 2
|
#define LOGIC_OPERATOR_OR 2
|
||||||
|
|
||||||
@ -1642,53 +1639,92 @@ float calculateTwoValues(float v1, float v2, uint8_t op)
|
|||||||
* 2 + 1
|
* 2 + 1
|
||||||
* 3 / 2
|
* 3 / 2
|
||||||
*/
|
*/
|
||||||
float evaluateExpression(const char * expression, unsigned int len)
|
float evaluateExpression(const char * expression, unsigned int len) {
|
||||||
{
|
|
||||||
char expbuf[len + 1];
|
char expbuf[len + 1];
|
||||||
memcpy(expbuf, expression, len);
|
memcpy(expbuf, expression, len);
|
||||||
expbuf[len] = '\0';
|
expbuf[len] = '\0';
|
||||||
char * scan_pointer = expbuf;
|
char * scan_pointer = expbuf;
|
||||||
|
|
||||||
LinkedList<float> object_values;
|
float object_values[21];
|
||||||
LinkedList<int8_t> operators;
|
int8_t operators[20];
|
||||||
int8_t op;
|
|
||||||
float va;
|
float va;
|
||||||
//Find and add the value of first object
|
//Find and add the value of first object
|
||||||
if (findNextObjectValue(scan_pointer, va)) {
|
if (findNextObjectValue(scan_pointer, va)) {
|
||||||
object_values.add(va);
|
object_values[0] = va;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
while (*scan_pointer)
|
|
||||||
{
|
uint32_t operators_size = 0;
|
||||||
|
uint32_t object_values_size = 1;
|
||||||
|
int8_t op;
|
||||||
|
while (*scan_pointer) {
|
||||||
if (findNextOperator(scan_pointer, op)
|
if (findNextOperator(scan_pointer, op)
|
||||||
&& *scan_pointer
|
&& *scan_pointer
|
||||||
&& findNextObjectValue(scan_pointer, va))
|
&& findNextObjectValue(scan_pointer, va))
|
||||||
{
|
{
|
||||||
operators.add(op);
|
operators[operators_size++] = op;
|
||||||
object_values.add(va);
|
object_values[object_values_size++] = va;
|
||||||
} else {
|
} else {
|
||||||
//No operator followed or no more object after this operator, we done.
|
//No operator followed or no more object after this operator, we done.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (operators_size >= 20) {
|
||||||
|
AddLog(LOG_LEVEL_ERROR, PSTR("RUL: Too many arguments"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Going to evaluate the whole expression
|
// Going to evaluate the whole expression
|
||||||
// Calculate by order of operator priorities. Looking for all operators with specified priority (from High to Low)
|
// Calculate by order of operator priorities. Looking for all operators with specified priority (from High to Low)
|
||||||
for (int32_t priority = MAX_EXPRESSION_OPERATOR_PRIORITY; priority > 0; priority--) {
|
for (int32_t priority = MAX_EXPRESSION_OPERATOR_PRIORITY; priority > 0; priority--) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (index < operators.size()) {
|
while (index < operators_size) {
|
||||||
if (priority == pgm_read_byte(kExpressionOperatorsPriorities + operators.get(index))) { //need to calculate the operator first
|
if (priority == pgm_read_byte(kExpressionOperatorsPriorities + operators[index])) { //need to calculate the operator first
|
||||||
//get current object value and remove the next object with current operator
|
// Get current object value and remove the next object with current operator
|
||||||
va = calculateTwoValues(object_values.get(index), object_values.remove(index + 1), operators.remove(index));
|
va = calculateTwoValues(object_values[index], object_values[index + 1], operators[index]);
|
||||||
|
|
||||||
|
uint32_t i = index;
|
||||||
|
while (i <= operators_size) {
|
||||||
|
operators[i++] = operators[i]; // operators.remove(index)
|
||||||
|
object_values[i] = object_values[i +1]; // object_values.remove(index + 1)
|
||||||
|
}
|
||||||
|
object_values_size--;
|
||||||
|
operators_size--;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint32_t i = index +1;
|
||||||
|
while (i <= object_values_size) {
|
||||||
|
object_values[i++] = object_values[i]; // object_values.remove(index + 1)
|
||||||
|
}
|
||||||
|
object_values_size--;
|
||||||
|
|
||||||
|
i = index;
|
||||||
|
while (i <= operators_size) {
|
||||||
|
operators[i++] = operators[i]; // operators.remove(index)
|
||||||
|
}
|
||||||
|
operators_size--;
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
for (uint32_t i = index +1; i <= object_values_size; i++) {
|
||||||
|
object_values[i] = object_values[i +1]; // object_values.remove(index + 1)
|
||||||
|
}
|
||||||
|
object_values_size--;
|
||||||
|
|
||||||
|
for (uint32_t i = index; i <= operators_size; i++) {
|
||||||
|
operators[i] = operators[i +1]; // operators.remove(index)
|
||||||
|
}
|
||||||
|
operators_size--;
|
||||||
|
*/
|
||||||
//Replace the current value with the result
|
//Replace the current value with the result
|
||||||
object_values.set(index, va);
|
object_values[index] = va;
|
||||||
} else {
|
} else {
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return object_values.get(0);
|
return object_values[0];
|
||||||
}
|
}
|
||||||
#endif // USE_EXPRESSION
|
#endif // USE_EXPRESSION
|
||||||
|
|
||||||
@ -1873,58 +1909,74 @@ bool findNextLogicObjectValue(char * &pointer, bool &value)
|
|||||||
* Return:
|
* Return:
|
||||||
* boolean - the value of logical expression
|
* boolean - the value of logical expression
|
||||||
*/
|
*/
|
||||||
bool evaluateLogicalExpression(const char * expression, int len)
|
bool evaluateLogicalExpression(const char * expression, int len) {
|
||||||
{
|
|
||||||
//Make a copy first
|
//Make a copy first
|
||||||
char expbuff[len + 1];
|
char expbuff[len + 1];
|
||||||
memcpy(expbuff, expression, len);
|
memcpy(expbuff, expression, len);
|
||||||
expbuff[len] = '\0';
|
expbuff[len] = '\0';
|
||||||
|
|
||||||
//AddLog(LOG_LEVEL_DEBUG, PSTR("EvalLogic: |%s|"), expbuff);
|
|
||||||
char * pointer = expbuff;
|
char * pointer = expbuff;
|
||||||
LinkedList<bool> values;
|
|
||||||
LinkedList<int8_t> logicOperators;
|
bool values[21];
|
||||||
|
int8_t logicOperators[20];
|
||||||
|
|
||||||
//Find first comparison expression
|
//Find first comparison expression
|
||||||
bool bValue;
|
bool bValue;
|
||||||
if (findNextLogicObjectValue(pointer, bValue)) {
|
if (findNextLogicObjectValue(pointer, bValue)) {
|
||||||
values.add(bValue);
|
values[0] = bValue;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t logicOperators_size = 0;
|
||||||
|
uint32_t values_size = 1;
|
||||||
int8_t op;
|
int8_t op;
|
||||||
while (*pointer) {
|
while (*pointer) {
|
||||||
if (findNextLogicOperator(pointer, op)
|
if (findNextLogicOperator(pointer, op)
|
||||||
&& (*pointer) && findNextLogicObjectValue(pointer, bValue))
|
&& (*pointer) && findNextLogicObjectValue(pointer, bValue))
|
||||||
{
|
{
|
||||||
logicOperators.add(op);
|
logicOperators[logicOperators_size++] = op;
|
||||||
values.add(bValue);
|
values[values_size++] = bValue;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (logicOperators_size >= 20) {
|
||||||
|
AddLog(LOG_LEVEL_ERROR, PSTR("RUL: Too many arguments"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate all "AND" first
|
// Calculate all "AND" first
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (index < logicOperators.size()) {
|
while (index < logicOperators_size) {
|
||||||
if (logicOperators.get(index) == LOGIC_OPERATOR_AND) {
|
if (logicOperators[index] == LOGIC_OPERATOR_AND) {
|
||||||
values.set(index, values.get(index) && values.get(index+1));
|
values[index] &= values[index +1];
|
||||||
values.remove(index + 1);
|
uint32_t i = index;
|
||||||
logicOperators.remove(index);
|
while (i <= logicOperators_size) {
|
||||||
|
logicOperators[i++] = logicOperators[i]; // logicOperators.remove(index);
|
||||||
|
values[i] = values[i +1]; // values.remove(index + 1);
|
||||||
|
}
|
||||||
|
values_size--;
|
||||||
|
logicOperators_size--;
|
||||||
} else {
|
} else {
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Then, calculate all "OR"
|
// Then, calculate all "OR"
|
||||||
index = 0;
|
index = 0;
|
||||||
while (index < logicOperators.size()) {
|
while (index < logicOperators_size) {
|
||||||
if (logicOperators.get(index) == LOGIC_OPERATOR_OR) {
|
if (logicOperators[index] == LOGIC_OPERATOR_OR) {
|
||||||
values.set(index, values.get(index) || values.get(index+1));
|
values[index] |= values[index+1];
|
||||||
values.remove(index + 1);
|
uint32_t i = index;
|
||||||
logicOperators.remove(index);
|
while (i <= logicOperators_size) {
|
||||||
|
logicOperators[i++] = logicOperators[i]; // logicOperators.remove(index);
|
||||||
|
values[i] = values[i +1]; // values.remove(index + 1);
|
||||||
|
}
|
||||||
|
values_size--;
|
||||||
|
logicOperators_size--;
|
||||||
} else {
|
} else {
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values.get(0);
|
return values[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user