Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

606 lines
17 KiB

Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Terminal: change command-line parser (#2247) Change the underlying command line handling: - switch to a custom parser, inspired by redis / sds - update terminalRegisterCommand signature, pass only bare minimum - clean-up `help` & `commands`. update settings `set`, `get` and `del` - allow our custom test suite to run command-line tests - clean-up Stream IO to allow us to print large things into debug stream (for example, `eeprom.dump`) - send parsing errors to the debug log As a proof of concept, introduce `TERMINAL_MQTT_SUPPORT` and `TERMINAL_WEB_API_SUPPORT` - MQTT subscribes to the `<root>/cmd/set` and sends response to the `<root>/cmd`. We can't output too much, as we don't have any large-send API. - Web API listens to the `/api/cmd?apikey=...&line=...` (or PUT, params inside the body). This one is intended as a possible replacement of the `API_SUPPORT`. Internals introduce a 'task' around the AsyncWebServerRequest object that will simulate what WiFiClient does and push data into it continuously, switching between CONT and SYS. Both are experimental. We only accept a single command and not every command is updated to use Print `ctx.output` object. We are also somewhat limited by the Print / Stream overall, perhaps I am overestimating the usefulness of Arduino compatibility to such an extent :) Web API handler can also sometimes show only part of the result, whenever the command tries to yield() by itself waiting for something. Perhaps we would need to create a custom request handler for that specific use-case.
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
Update rpnlib to 0.23.x (#2274) ## [0.23.0] 2020-07-26 ### Added - `p` operator to print the top of the stack via debug function - `&var` syntax to create variable reference in expression - `=` operator for variable assignment in expression - `exists` operator to check for variable existance (only for references) - `deref` operator to convert variable reference into a value (only for references) - Allow to use either float or double as floating type, parse numbers in expressions as specified type - Add boolean type, parse `true` and `false` in expressions - Add null type, parse `null` in expressions - Add string type, parse double-quoted `"string"` in expressions - Add integer and unsigned integer type, used in operators - Allow to configure underlying types from rpnlib\_config.h and -D... flags - Return `rpn_error` from operators, split error types into categories - Create a new stack by using `[` keyword. Move stack contents into the previous stack + size by using `]`. ### Changed - Stack structure no longer holds raw `float`, but internal `rpn_value` type - rpn\_... setter and getter methods use `rpn_value` type - Operator functions return `rpn_error` type, allowing to return both value and operator errors - Variables in expressions are no longer required to exist when using `&var` Expression will automatically create the variable, set it to `null` and push it's reference on the stack - It is possible to create 'reference' stack values - Improve precision of `e` and `pi` ### Fixed - Proper value for `e` constant - Allow to use multiple contexts simultaniously, replace `rpn_error` and `rpn_debug_callback` with the current `rpn_context` members `error` and `debug_callback` respectively
4 years ago
  1. /*
  2. RPN RULES MODULE
  3. Use RPNLib library (https://github.com/xoseperez/rpnlib)
  4. Copyright (C) 2019 by Xose Pérez <xose dot perez at gmail dot com>
  5. */
  6. #include "rpnrules.h"
  7. #if RPN_RULES_SUPPORT
  8. #include "broker.h"
  9. #include "mqtt.h"
  10. #include "ntp.h"
  11. #include "relay.h"
  12. #include "rpc.h"
  13. #include "sensor.h"
  14. #include "terminal.h"
  15. #include "ws.h"
  16. #include <vector>
  17. // -----------------------------------------------------------------------------
  18. // Custom commands
  19. // -----------------------------------------------------------------------------
  20. rpn_context _rpn_ctxt;
  21. bool _rpn_run = false;
  22. unsigned long _rpn_delay = RPN_DELAY;
  23. unsigned long _rpn_last = 0;
  24. struct RpnRunner {
  25. enum class Policy {
  26. OneShot,
  27. Periodic
  28. };
  29. RpnRunner(Policy policy_, uint32_t period_) :
  30. policy(policy_),
  31. period(period_),
  32. last(millis())
  33. {}
  34. Policy policy { Policy::Periodic };
  35. uint32_t period { 0ul };
  36. uint32_t last { 0ul };
  37. bool expired { false };
  38. };
  39. std::vector<RpnRunner> _rpn_runners;
  40. rpn_operator_error _rpnRunnerHandler(rpn_context & ctxt, RpnRunner::Policy policy, uint32_t time) {
  41. for (auto& runner : _rpn_runners) {
  42. if ((policy == runner.policy) && (time == runner.period)) {
  43. return runner.expired
  44. ? rpn_operator_error::Ok
  45. : rpn_operator_error::CannotContinue;
  46. }
  47. }
  48. _rpn_runners.emplace_back(policy, time);
  49. return rpn_operator_error::CannotContinue;
  50. }
  51. // -----------------------------------------------------------------------------
  52. bool _rpnWebSocketOnKeyCheck(const char * key, JsonVariant& value) {
  53. return (strncmp(key, "rpn", 3) == 0);
  54. }
  55. void _rpnWebSocketOnConnected(JsonObject& root) {
  56. root["rpnSticky"] = getSetting("rpnSticky", 1 == RPN_STICKY);
  57. root["rpnDelay"] = getSetting("rpnDelay", RPN_DELAY);
  58. JsonArray& rules = root.createNestedArray("rpnRules");
  59. unsigned char i = 0;
  60. String rule = getSetting({"rpnRule", i});
  61. while (rule.length()) {
  62. rules.add(rule);
  63. rule = getSetting({"rpnRule", ++i});
  64. }
  65. #if MQTT_SUPPORT
  66. i=0;
  67. JsonArray& topics = root.createNestedArray("rpnTopics");
  68. JsonArray& names = root.createNestedArray("rpnNames");
  69. String rpn_topic = getSetting({"rpnTopic", i});
  70. while (rpn_topic.length() > 0) {
  71. String rpn_name = getSetting({"rpnName", i});
  72. topics.add(rpn_topic);
  73. names.add(rpn_name);
  74. rpn_topic = getSetting({"rpnTopic", ++i});
  75. }
  76. #endif
  77. }
  78. #if MQTT_SUPPORT
  79. void _rpnMQTTSubscribe() {
  80. unsigned char i = 0;
  81. String rpn_topic = getSetting({"rpnTopic", i});
  82. while (rpn_topic.length()) {
  83. mqttSubscribeRaw(rpn_topic.c_str());
  84. rpn_topic = getSetting({"rpnTopic", ++i});
  85. }
  86. }
  87. void _rpnMQTTCallback(unsigned int type, const char * topic, const char * payload) {
  88. if (type == MQTT_CONNECT_EVENT) {
  89. _rpnMQTTSubscribe();
  90. }
  91. if (type == MQTT_MESSAGE_EVENT) {
  92. unsigned char i = 0;
  93. String rpn_topic = getSetting({"rpnTopic", i});
  94. while (rpn_topic.length()) {
  95. if (rpn_topic.equals(topic)) {
  96. String rpn_name = getSetting({"rpnName", i});
  97. if (rpn_name.length()) {
  98. rpn_value value { atof(payload) };
  99. rpn_variable_set(_rpn_ctxt, rpn_name, value);
  100. _rpn_run = true;
  101. break;
  102. }
  103. }
  104. rpn_topic = getSetting({"rpnTopic", ++i});
  105. }
  106. }
  107. }
  108. #endif // MQTT_SUPPORT
  109. void _rpnConfigure() {
  110. #if MQTT_SUPPORT
  111. if (mqttConnected()) _rpnMQTTSubscribe();
  112. #endif
  113. _rpn_delay = getSetting("rpnDelay", RPN_DELAY);
  114. }
  115. void _rpnBrokerCallback(const String& topic, unsigned char id, double value, const char*) {
  116. char name[32] = {0};
  117. snprintf(name, sizeof(name), "%s%u", topic.c_str(), id);
  118. if (topic == MQTT_TOPIC_RELAY) {
  119. rpn_variable_set(_rpn_ctxt, name, rpn_value(static_cast<bool>(value)));
  120. } else {
  121. rpn_variable_set(_rpn_ctxt, name, rpn_value(value));
  122. }
  123. _rpn_run = true;
  124. }
  125. void _rpnBrokerStatus(const String& topic, unsigned char id, unsigned int value) {
  126. _rpnBrokerCallback(topic, id, double(value), nullptr);
  127. }
  128. #if NTP_SUPPORT
  129. rpn_error _rpnNtpNow(rpn_context & ctxt) {
  130. if (!ntpSynced()) return rpn_operator_error::CannotContinue;
  131. rpn_value ts { static_cast<rpn_int>(now()) };
  132. rpn_stack_push(ctxt, ts);
  133. return 0;
  134. }
  135. rpn_error _rpnNtpFunc(rpn_context & ctxt, rpn_int (*func)(time_t)) {
  136. rpn_value value;
  137. rpn_stack_pop(ctxt, value);
  138. value = rpn_value(func(value.toInt()));
  139. rpn_stack_push(ctxt, value);
  140. return 0;
  141. }
  142. #endif // NTP_SUPPORT
  143. String _rpnValueToString(const rpn_value& value) {
  144. String out;
  145. if (value.isString()) {
  146. out = value.toString();
  147. } else if (value.isFloat()) {
  148. out = String(value.toFloat(), 10);
  149. } else if (value.isInt()) {
  150. out = String(value.toInt(), 10);
  151. } else if (value.isUint()) {
  152. out = String(value.toUint(), 10);
  153. } else if (value.isBoolean()) {
  154. out = String(value.toBoolean() ? "true" : "false");
  155. } else if (value.isNull()) {
  156. out = F("(null)");
  157. }
  158. return out;
  159. }
  160. char _rpnStackTypeTag(rpn_stack_value::Type type) {
  161. switch (type) {
  162. case rpn_stack_value::Type::None:
  163. return 'N';
  164. case rpn_stack_value::Type::Variable:
  165. return '$';
  166. case rpn_stack_value::Type::Array:
  167. return 'A';
  168. case rpn_stack_value::Type::Value:
  169. default:
  170. return ' ';
  171. }
  172. }
  173. #if RELAY_SUPPORT
  174. rpn_error _rpnRelayStatus(rpn_context & ctxt, bool force) {
  175. rpn_value id;
  176. rpn_value status;
  177. rpn_stack_pop(ctxt, id);
  178. rpn_stack_pop(ctxt, status);
  179. rpn_uint value = status.toUint();
  180. if (value == 2) {
  181. relayToggle(id.toUint());
  182. } else if (relayStatusTarget(id.toUint()) != (value == 1)) {
  183. relayStatus(id.toUint(), value == 1);
  184. }
  185. return 0;
  186. }
  187. #endif // RELAY_SUPPORT
  188. void _rpnShowStack(Print& print) {
  189. print.println(F("Stack:"));
  190. auto index = rpn_stack_size(_rpn_ctxt);
  191. if (!index) {
  192. print.println(F(" (empty)"));
  193. return;
  194. }
  195. rpn_stack_foreach(_rpn_ctxt, [&index, &print](rpn_stack_value::Type type, const rpn_value& value) {
  196. print.printf("%c %02u: %s\n",
  197. _rpnStackTypeTag(type), index--,
  198. _rpnValueToString(value).c_str()
  199. );
  200. });
  201. }
  202. void _rpnInit() {
  203. // Init context
  204. rpn_init(_rpn_ctxt);
  205. // Time functions need NTP support
  206. // TODO: since 1.15.0, timelib+ntpclientlib are no longer used with latest Cores
  207. // `now` is always in UTC, `utc_...` functions to be used instead to convert time
  208. #if NTP_SUPPORT && !NTP_LEGACY_SUPPORT
  209. rpn_operator_set(_rpn_ctxt, "utc", 0, _rpnNtpNow);
  210. rpn_operator_set(_rpn_ctxt, "now", 0, _rpnNtpNow);
  211. rpn_operator_set(_rpn_ctxt, "utc_month", 1, [](rpn_context & ctxt) {
  212. return _rpnNtpFunc(ctxt, utc_month);
  213. });
  214. rpn_operator_set(_rpn_ctxt, "month", 1, [](rpn_context & ctxt) {
  215. return _rpnNtpFunc(ctxt, month);
  216. });
  217. rpn_operator_set(_rpn_ctxt, "utc_day", 1, [](rpn_context & ctxt) {
  218. return _rpnNtpFunc(ctxt, utc_day);
  219. });
  220. rpn_operator_set(_rpn_ctxt, "day", 1, [](rpn_context & ctxt) {
  221. return _rpnNtpFunc(ctxt, day);
  222. });
  223. rpn_operator_set(_rpn_ctxt, "utc_dow", 1, [](rpn_context & ctxt) {
  224. return _rpnNtpFunc(ctxt, utc_weekday);
  225. });
  226. rpn_operator_set(_rpn_ctxt, "dow", 1, [](rpn_context & ctxt) {
  227. return _rpnNtpFunc(ctxt, weekday);
  228. });
  229. rpn_operator_set(_rpn_ctxt, "utc_hour", 1, [](rpn_context & ctxt) {
  230. return _rpnNtpFunc(ctxt, utc_hour);
  231. });
  232. rpn_operator_set(_rpn_ctxt, "hour", 1, [](rpn_context & ctxt) {
  233. return _rpnNtpFunc(ctxt, hour);
  234. });
  235. rpn_operator_set(_rpn_ctxt, "utc_minute", 1, [](rpn_context & ctxt) {
  236. return _rpnNtpFunc(ctxt, utc_minute);
  237. });
  238. rpn_operator_set(_rpn_ctxt, "minute", 1, [](rpn_context & ctxt) {
  239. return _rpnNtpFunc(ctxt, minute);
  240. });
  241. #endif
  242. // TODO: 1.14.0 weekday(...) conversion seemed to have 0..6 range with Monday as 0
  243. // using classic Sunday as first, but instead of 0 it is 1
  244. // Implementation above also uses 1 for Sunday, staying compatible with TimeLib
  245. #if NTP_SUPPORT && NTP_LEGACY_SUPPORT
  246. rpn_operator_set(_rpn_ctxt, "utc", 0, [](rpn_context & ctxt) -> rpn_error {
  247. if (!ntpSynced()) return rpn_operator_error::CannotContinue;
  248. rpn_value ts { static_cast<rpn_int>(ntpLocal2UTC(now())) };
  249. rpn_stack_push(ctxt, ts);
  250. return 0;
  251. });
  252. rpn_operator_set(_rpn_ctxt, "now", 0, _rpnNtpNow);
  253. rpn_operator_set(_rpn_ctxt, "month", 1, [](rpn_context & ctxt) {
  254. return _rpnNtpFunc(ctxt, month);
  255. });
  256. rpn_operator_set(_rpn_ctxt, "day", 1, [](rpn_context & ctxt) {
  257. return _rpnNtpFunc(ctxt, day);
  258. });
  259. rpn_operator_set(_rpn_ctxt, "dow", 1, [](rpn_context & ctxt) {
  260. return _rpnNtpFunc(ctxt, weekday);
  261. });
  262. rpn_operator_set(_rpn_ctxt, "hour", 1, [](rpn_context & ctxt) {
  263. return _rpnNtpFunc(ctxt, hour);
  264. });
  265. rpn_operator_set(_rpn_ctxt, "minute", 1, [](rpn_context & ctxt) {
  266. return _rpnNtpFunc(ctxt, minute);
  267. });
  268. #endif
  269. // Accept relay number and numeric API status value (0, 1 and 2)
  270. #if RELAY_SUPPORT
  271. // apply status and reset timers when called
  272. rpn_operator_set(_rpn_ctxt, "relay_reset", 2, [](rpn_context & ctxt) {
  273. return _rpnRelayStatus(ctxt, true);
  274. });
  275. // only update status when target status differs, keep running timers
  276. rpn_operator_set(_rpn_ctxt, "relay", 2, [](rpn_context & ctxt) {
  277. return _rpnRelayStatus(ctxt, false);
  278. });
  279. #endif // RELAY_SUPPORT == 1
  280. // Channel operators
  281. #if RELAY_PROVIDER == RELAY_PROVIDER_LIGHT
  282. rpn_operator_set(_rpn_ctxt, "update", 0, [](rpn_context & ctxt) -> rpn_error {
  283. lightUpdate(true, true);
  284. return 0;
  285. });
  286. rpn_operator_set(_rpn_ctxt, "black", 0, [](rpn_context & ctxt) -> rpn_error {
  287. lightColor((unsigned long) 0);
  288. return 0;
  289. });
  290. rpn_operator_set(_rpn_ctxt, "channel", 2, [](rpn_context & ctxt) -> rpn_error {
  291. rpn_value value;
  292. rpn_value id;
  293. rpn_stack_pop(ctxt, id);
  294. rpn_stack_pop(ctxt, value);
  295. lightChannel(id.toUint(), id.toInt());
  296. return 0;
  297. });
  298. #endif
  299. #if MQTT_SUPPORT
  300. rpn_operator_set(_rpn_ctxt, "mqtt_send", 2, [](rpn_context & ctxt) -> rpn_error {
  301. rpn_value message;
  302. rpn_stack_pop(ctxt, message);
  303. rpn_value topic;
  304. rpn_stack_pop(ctxt, topic);
  305. return mqttSendRaw(topic.toString().c_str(), message.toString().c_str())
  306. ? rpn_operator_error::Ok
  307. : rpn_operator_error::CannotContinue;
  308. });
  309. #endif
  310. // Some debugging. Dump stack contents
  311. rpn_operator_set(_rpn_ctxt, "showstack", 0, [](rpn_context & ctxt) -> rpn_error {
  312. _rpnShowStack(terminalDefaultStream());
  313. return 0;
  314. });
  315. // And, simple string logging
  316. #if DEBUG_SUPPORT
  317. rpn_operator_set(_rpn_ctxt, "dbgmsg", 1, [](rpn_context & ctxt) -> rpn_error {
  318. rpn_value message;
  319. rpn_stack_pop(ctxt, message);
  320. DEBUG_MSG_P(PSTR("[RPN] %s\n"), message.toString().c_str());
  321. return 0;
  322. });
  323. #endif
  324. rpn_operator_set(_rpn_ctxt, "millis", 0, [](rpn_context & ctxt) -> rpn_error {
  325. rpn_stack_push(ctxt, rpn_value(static_cast<uint32_t>(millis())));
  326. return 0;
  327. });
  328. rpn_operator_set(_rpn_ctxt, "oneshot_ms", 1, [](rpn_context & ctxt) -> rpn_error {
  329. auto every = rpn_stack_pop(ctxt);
  330. return _rpnRunnerHandler(ctxt, RpnRunner::Policy::OneShot, every.toUint());
  331. });
  332. rpn_operator_set(_rpn_ctxt, "every_ms", 1, [](rpn_context & ctxt) -> rpn_error {
  333. auto every = rpn_stack_pop(ctxt);
  334. return _rpnRunnerHandler(ctxt, RpnRunner::Policy::Periodic, every.toUint());
  335. });
  336. }
  337. #if TERMINAL_SUPPORT
  338. void _rpnInitCommands() {
  339. terminalRegisterCommand(F("RPN.RUNNERS"), [](const terminal::CommandContext& ctx) {
  340. if (!_rpn_runners.size()) {
  341. terminalError(ctx, F("No active runners"));
  342. return;
  343. }
  344. for (auto& runner : _rpn_runners) {
  345. char buffer[128] = {0};
  346. snprintf_P(buffer, sizeof(buffer), PSTR("%p %s %u ms, last %u ms"),
  347. &runner, (RpnRunner::Policy::Periodic == runner.policy) ? "every" : "one-shot",
  348. runner.period, runner.last
  349. );
  350. ctx.output.println(buffer);
  351. }
  352. terminalOK(ctx);
  353. });
  354. terminalRegisterCommand(F("RPN.VARS"), [](const terminal::CommandContext& ctx) {
  355. rpn_variables_foreach(_rpn_ctxt, [&ctx](const String& name, const rpn_value& value) {
  356. char buffer[256] = {0};
  357. snprintf_P(buffer, sizeof(buffer), PSTR(" %s: %s"), name.c_str(), _rpnValueToString(value).c_str());
  358. ctx.output.println(buffer);
  359. });
  360. terminalOK(ctx);
  361. });
  362. terminalRegisterCommand(F("RPN.OPS"), [](const terminal::CommandContext& ctx) {
  363. rpn_operators_foreach(_rpn_ctxt, [&ctx](const String& name, size_t argc, rpn_operator::callback_type) {
  364. char buffer[128] = {0};
  365. snprintf_P(buffer, sizeof(buffer), PSTR(" %s (%d)"), name.c_str(), argc);
  366. ctx.output.println(buffer);
  367. });
  368. terminalOK(ctx);
  369. });
  370. terminalRegisterCommand(F("RPN.TEST"), [](const terminal::CommandContext& ctx) {
  371. if (ctx.argc != 2) {
  372. terminalError(F("Wrong arguments"));
  373. return;
  374. }
  375. ctx.output.print(F("Running RPN expression: "));
  376. ctx.output.println(ctx.argv[1].c_str());
  377. if (!rpn_process(_rpn_ctxt, ctx.argv[1].c_str())) {
  378. rpn_stack_clear(_rpn_ctxt);
  379. char buffer[64] = {0};
  380. snprintf_P(buffer, sizeof(buffer), PSTR("position=%u category=%d code=%d"),
  381. _rpn_ctxt.error.position, static_cast<int>(_rpn_ctxt.error.category), _rpn_ctxt.error.code);
  382. terminalError(ctx, buffer);
  383. return;
  384. }
  385. _rpnShowStack(ctx.output);
  386. rpn_stack_clear(_rpn_ctxt);
  387. terminalOK(ctx);
  388. });
  389. }
  390. #endif
  391. // enables us to use rules without any events firing
  392. // notice: requires rpnRun to trigger at least once so that we can install runners
  393. void _rpnRunnersCheck() {
  394. auto ts = millis();
  395. for (auto& runner : _rpn_runners) {
  396. if (ts - runner.last >= runner.period) {
  397. runner.expired = true;
  398. runner.last = ts;
  399. _rpn_run = true;
  400. }
  401. }
  402. }
  403. void _rpnRunnersReset() {
  404. auto old = std::remove_if(_rpn_runners.begin(), _rpn_runners.end(), [](RpnRunner& runner) {
  405. return (RpnRunner::Policy::OneShot == runner.policy) && runner.expired;
  406. });
  407. if (old != _rpn_runners.end()) {
  408. _rpn_runners.erase(old, _rpn_runners.end());
  409. }
  410. for (auto& runner : _rpn_runners) {
  411. runner.expired = false;
  412. }
  413. }
  414. void _rpnRun() {
  415. if (!_rpn_run) {
  416. return;
  417. }
  418. if (millis() - _rpn_last <= _rpn_delay) {
  419. return;
  420. }
  421. _rpn_last = millis();
  422. _rpn_run = false;
  423. String rule;
  424. unsigned char i = 0;
  425. while ((rule = getSetting({"rpnRule", i++})).length()) {
  426. rpn_process(_rpn_ctxt, rule.c_str());
  427. rpn_stack_clear(_rpn_ctxt);
  428. }
  429. if (!getSetting("rpnSticky", 1 == RPN_STICKY)) {
  430. rpn_variables_clear(_rpn_ctxt);
  431. }
  432. }
  433. void _rpnLoop() {
  434. _rpnRunnersCheck();
  435. _rpnRun();
  436. _rpnRunnersReset();
  437. }
  438. void rpnSetup() {
  439. // Init context
  440. _rpnInit();
  441. // Load & cache settings
  442. _rpnConfigure();
  443. // Terminal commands
  444. #if TERMINAL_SUPPORT
  445. _rpnInitCommands();
  446. #endif
  447. // Websockets
  448. #if WEB_SUPPORT
  449. wsRegister()
  450. .onVisible([](JsonObject& root) { root["rpnVisible"] = 1; })
  451. .onConnected(_rpnWebSocketOnConnected)
  452. .onKeyCheck(_rpnWebSocketOnKeyCheck);
  453. #endif
  454. // MQTT
  455. #if MQTT_SUPPORT
  456. mqttRegister(_rpnMQTTCallback);
  457. #endif
  458. #if NTP_SUPPORT
  459. NtpBroker::Register([](const NtpTick tick, time_t timestamp, const String& datetime) {
  460. static const String tick_every_hour(F("tick1h"));
  461. static const String tick_every_minute(F("tick1m"));
  462. const char* ptr =
  463. (tick == NtpTick::EveryMinute) ? tick_every_minute.c_str() :
  464. (tick == NtpTick::EveryHour) ? tick_every_hour.c_str() : nullptr;
  465. if (ptr != nullptr) {
  466. rpn_value value { static_cast<rpn_int>(timestamp) };
  467. rpn_variable_set(_rpn_ctxt, ptr, value);
  468. _rpn_run = true;
  469. }
  470. });
  471. #endif
  472. StatusBroker::Register(_rpnBrokerStatus);
  473. #if SENSOR_SUPPORT
  474. SensorReadBroker::Register(_rpnBrokerCallback);
  475. #endif
  476. espurnaRegisterReload(_rpnConfigure);
  477. espurnaRegisterLoop(_rpnLoop);
  478. _rpn_last = millis();
  479. _rpn_run = true;
  480. }
  481. #endif // RPN_RULES_SUPPORT