mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
Removed max number of 30 backlog entries
This commit is contained in:
parent
db70d9c8cb
commit
c9d0106007
@ -13,8 +13,8 @@ All notable changes to this project will be documented in this file.
|
|||||||
- ESP32 MI BLE support for Xiaomi LYWSD02MMC (#20381)
|
- ESP32 MI BLE support for Xiaomi LYWSD02MMC (#20381)
|
||||||
- LVGL option to add `lv.keyboard` extra widget (#20496)
|
- LVGL option to add `lv.keyboard` extra widget (#20496)
|
||||||
- GUI sensor separators (#20495)
|
- GUI sensor separators (#20495)
|
||||||
- Command ``TimedPower<index> <milliseconds>[,ON|OFF|TOGGLE|BLINK]`` executes ``Power<index> [ON|OFF|TOGGLE|BLINK] `` and after <millisecond> executes ``Power<index> [OFF|ON|TOGGLE|OFF]``
|
- Command ``TimedPower<index> <milliseconds>[,ON|OFF|TOGGLE|BLINK]`` executes ``Power<index> [ON|OFF|TOGGLE|BLINK] `` and after <millisecond> executes ``Power<index> [OFF|ON|TOGGLE|BLINK_OFF]``
|
||||||
- Berry add solidification of strings longer than 255 bytes
|
- Berry solidification of strings longer than 255 bytes (#20529)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
|
|
||||||
@ -30,9 +30,10 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Zigbee ramdom crash in main page (#20481)
|
- Zigbee ramdom crash in main page (#20481)
|
||||||
- Web file upload response on upload error (#20340)
|
- Web file upload response on upload error (#20340)
|
||||||
- ESP32 shutter exception 6 (divide by zero) on ``ShutterMode 4`` (#20524)
|
- ESP32 shutter exception 6 (divide by zero) on ``ShutterMode 4`` (#20524)
|
||||||
|
- GPIOViewer exception 3
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
- Max number of 30 backlog entries
|
||||||
|
|
||||||
## [13.3.0.2] 20240111
|
## [13.3.0.2] 20240111
|
||||||
### Added
|
### Added
|
||||||
|
@ -146,6 +146,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
|||||||
- Berry provide lightweight options for `tasmota.wifi/eth/memory/rtc` [#20448](https://github.com/arendst/Tasmota/issues/20448)
|
- Berry provide lightweight options for `tasmota.wifi/eth/memory/rtc` [#20448](https://github.com/arendst/Tasmota/issues/20448)
|
||||||
- Berry `tasmota.webcolor` [#20454](https://github.com/arendst/Tasmota/issues/20454)
|
- Berry `tasmota.webcolor` [#20454](https://github.com/arendst/Tasmota/issues/20454)
|
||||||
- Berry `debug.caller` [#20470](https://github.com/arendst/Tasmota/issues/20470)
|
- Berry `debug.caller` [#20470](https://github.com/arendst/Tasmota/issues/20470)
|
||||||
|
- Berry solidification of strings longer than 255 bytes [#20529](https://github.com/arendst/Tasmota/issues/20529)
|
||||||
- LVGL `lv.str_arr` [#20480](https://github.com/arendst/Tasmota/issues/20480)
|
- LVGL `lv.str_arr` [#20480](https://github.com/arendst/Tasmota/issues/20480)
|
||||||
- LVGL option to add `lv.keyboard` extra widget [#20496](https://github.com/arendst/Tasmota/issues/20496)
|
- LVGL option to add `lv.keyboard` extra widget [#20496](https://github.com/arendst/Tasmota/issues/20496)
|
||||||
- HASPmota `haspmota.page_show()` to change page [#20333](https://github.com/arendst/Tasmota/issues/20333)
|
- HASPmota `haspmota.page_show()` to change page [#20333](https://github.com/arendst/Tasmota/issues/20333)
|
||||||
@ -180,3 +181,4 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
|||||||
- Matter Contact sensor was not triggering any update [#20232](https://github.com/arendst/Tasmota/issues/20232)
|
- Matter Contact sensor was not triggering any update [#20232](https://github.com/arendst/Tasmota/issues/20232)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
- Max number of 30 backlog entries
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
Created by Ivan Seidel Gomes, March, 2013.
|
Created by Ivan Seidel Gomes, March, 2013.
|
||||||
Released into the public domain.
|
Released into the public domain.
|
||||||
|
|
||||||
|
20240118 - Removed sort functions not used by Tasmota (@arendst)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -39,8 +41,6 @@ protected:
|
|||||||
|
|
||||||
ListNode<T>* getNode(int index);
|
ListNode<T>* getNode(int index);
|
||||||
|
|
||||||
ListNode<T>* findEndOfSortedString(ListNode<T> *p, int (*cmp)(T &, T &));
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LinkedList();
|
LinkedList();
|
||||||
LinkedList(int sizeIndex, T _t); //initiate list size and default value
|
LinkedList(int sizeIndex, T _t); //initiate list size and default value
|
||||||
@ -96,11 +96,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
/*
|
|
||||||
Sort the list, given a comparison function
|
|
||||||
*/
|
|
||||||
virtual void sort(int (*cmp)(T &, T &));
|
|
||||||
|
|
||||||
// add support to array brakets [] operator
|
// add support to array brakets [] operator
|
||||||
inline T& operator[](int index);
|
inline T& operator[](int index);
|
||||||
inline T& operator[](size_t& i) { return this->get(i); }
|
inline T& operator[](size_t& i) { return this->get(i); }
|
||||||
@ -347,73 +342,4 @@ void LinkedList<T>::clear(){
|
|||||||
shift();
|
shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void LinkedList<T>::sort(int (*cmp)(T &, T &)){
|
|
||||||
if(_size < 2) return; // trivial case;
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
|
|
||||||
ListNode<T> **joinPoint = &root;
|
|
||||||
|
|
||||||
while(*joinPoint) {
|
|
||||||
ListNode<T> *a = *joinPoint;
|
|
||||||
ListNode<T> *a_end = findEndOfSortedString(a, cmp);
|
|
||||||
|
|
||||||
if(!a_end->next ) {
|
|
||||||
if(joinPoint == &root) {
|
|
||||||
last = a_end;
|
|
||||||
isCached = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListNode<T> *b = a_end->next;
|
|
||||||
ListNode<T> *b_end = findEndOfSortedString(b, cmp);
|
|
||||||
|
|
||||||
ListNode<T> *tail = b_end->next;
|
|
||||||
|
|
||||||
a_end->next = NULL;
|
|
||||||
b_end->next = NULL;
|
|
||||||
|
|
||||||
while(a && b) {
|
|
||||||
if(cmp(a->data, b->data) <= 0) {
|
|
||||||
*joinPoint = a;
|
|
||||||
joinPoint = &a->next;
|
|
||||||
a = a->next;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*joinPoint = b;
|
|
||||||
joinPoint = &b->next;
|
|
||||||
b = b->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(a) {
|
|
||||||
*joinPoint = a;
|
|
||||||
while(a->next) a = a->next;
|
|
||||||
a->next = tail;
|
|
||||||
joinPoint = &a->next;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*joinPoint = b;
|
|
||||||
while(b->next) b = b->next;
|
|
||||||
b->next = tail;
|
|
||||||
joinPoint = &b->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
ListNode<T>* LinkedList<T>::findEndOfSortedString(ListNode<T> *p, int (*cmp)(T &, T &)) {
|
|
||||||
while(p->next && cmp(p->data, p->next->data) <= 0) {
|
|
||||||
p = p->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
419
lib/default/LinkedList-1.2.3/LinkedList_with_sort.h
Normal file
419
lib/default/LinkedList-1.2.3/LinkedList_with_sort.h
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
/*
|
||||||
|
LinkedList.h - V1.1 - Generic LinkedList implementation
|
||||||
|
Works better with FIFO, because LIFO will need to
|
||||||
|
search the entire List to find the last one;
|
||||||
|
|
||||||
|
For instructions, go to https://github.com/ivanseidel/LinkedList
|
||||||
|
|
||||||
|
Created by Ivan Seidel Gomes, March, 2013.
|
||||||
|
Released into the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LinkedList_h
|
||||||
|
#define LinkedList_h
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct ListNode
|
||||||
|
{
|
||||||
|
T data;
|
||||||
|
ListNode<T> *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class LinkedList{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _size;
|
||||||
|
ListNode<T> *root;
|
||||||
|
ListNode<T> *last;
|
||||||
|
|
||||||
|
// Helps "get" method, by saving last position
|
||||||
|
ListNode<T> *lastNodeGot;
|
||||||
|
int lastIndexGot;
|
||||||
|
// isCached should be set to FALSE
|
||||||
|
// everytime the list suffer changes
|
||||||
|
bool isCached;
|
||||||
|
|
||||||
|
ListNode<T>* getNode(int index);
|
||||||
|
|
||||||
|
ListNode<T>* findEndOfSortedString(ListNode<T> *p, int (*cmp)(T &, T &));
|
||||||
|
|
||||||
|
public:
|
||||||
|
LinkedList();
|
||||||
|
LinkedList(int sizeIndex, T _t); //initiate list size and default value
|
||||||
|
~LinkedList();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns current size of LinkedList
|
||||||
|
*/
|
||||||
|
virtual int size();
|
||||||
|
/*
|
||||||
|
Adds a T object in the specified index;
|
||||||
|
Unlink and link the LinkedList correcly;
|
||||||
|
Increment _size
|
||||||
|
*/
|
||||||
|
virtual bool add(int index, T);
|
||||||
|
/*
|
||||||
|
Adds a T object in the end of the LinkedList;
|
||||||
|
Increment _size;
|
||||||
|
*/
|
||||||
|
virtual bool add(T);
|
||||||
|
/*
|
||||||
|
Adds a T object in the start of the LinkedList;
|
||||||
|
Increment _size;
|
||||||
|
*/
|
||||||
|
virtual bool unshift(T);
|
||||||
|
/*
|
||||||
|
Set the object at index, with T;
|
||||||
|
*/
|
||||||
|
virtual bool set(int index, T);
|
||||||
|
/*
|
||||||
|
Remove object at index;
|
||||||
|
If index is not reachable, returns false;
|
||||||
|
else, decrement _size
|
||||||
|
*/
|
||||||
|
virtual T remove(int index);
|
||||||
|
/*
|
||||||
|
Remove last object;
|
||||||
|
*/
|
||||||
|
virtual T pop();
|
||||||
|
/*
|
||||||
|
Remove first object;
|
||||||
|
*/
|
||||||
|
virtual T shift();
|
||||||
|
/*
|
||||||
|
Get the index'th element on the list;
|
||||||
|
Return Element if accessible,
|
||||||
|
else, return false;
|
||||||
|
*/
|
||||||
|
virtual T get(int index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Clear the entire array
|
||||||
|
*/
|
||||||
|
virtual void clear();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sort the list, given a comparison function
|
||||||
|
*/
|
||||||
|
virtual void sort(int (*cmp)(T &, T &));
|
||||||
|
|
||||||
|
// add support to array brakets [] operator
|
||||||
|
inline T& operator[](int index);
|
||||||
|
inline T& operator[](size_t& i) { return this->get(i); }
|
||||||
|
inline const T& operator[](const size_t& i) const { return this->get(i); }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize LinkedList with false values
|
||||||
|
template<typename T>
|
||||||
|
LinkedList<T>::LinkedList()
|
||||||
|
{
|
||||||
|
root=NULL;
|
||||||
|
last=NULL;
|
||||||
|
_size=0;
|
||||||
|
|
||||||
|
lastNodeGot = root;
|
||||||
|
lastIndexGot = 0;
|
||||||
|
isCached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear Nodes and free Memory
|
||||||
|
template<typename T>
|
||||||
|
LinkedList<T>::~LinkedList()
|
||||||
|
{
|
||||||
|
ListNode<T>* tmp;
|
||||||
|
while(root!=NULL)
|
||||||
|
{
|
||||||
|
tmp=root;
|
||||||
|
root=root->next;
|
||||||
|
delete tmp;
|
||||||
|
}
|
||||||
|
last = NULL;
|
||||||
|
_size=0;
|
||||||
|
isCached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Actualy "logic" coding
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ListNode<T>* LinkedList<T>::getNode(int index){
|
||||||
|
|
||||||
|
int _pos = 0;
|
||||||
|
ListNode<T>* current = root;
|
||||||
|
|
||||||
|
// Check if the node trying to get is
|
||||||
|
// immediatly AFTER the previous got one
|
||||||
|
if(isCached && lastIndexGot <= index){
|
||||||
|
_pos = lastIndexGot;
|
||||||
|
current = lastNodeGot;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(_pos < index && current){
|
||||||
|
current = current->next;
|
||||||
|
|
||||||
|
_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the object index got is the same as the required
|
||||||
|
if(_pos == index){
|
||||||
|
isCached = true;
|
||||||
|
lastIndexGot = index;
|
||||||
|
lastNodeGot = current;
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
int LinkedList<T>::size(){
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
LinkedList<T>::LinkedList(int sizeIndex, T _t){
|
||||||
|
for (int i = 0; i < sizeIndex; i++){
|
||||||
|
add(_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool LinkedList<T>::add(int index, T _t){
|
||||||
|
|
||||||
|
if(index >= _size)
|
||||||
|
return add(_t);
|
||||||
|
|
||||||
|
if(index == 0)
|
||||||
|
return unshift(_t);
|
||||||
|
|
||||||
|
ListNode<T> *tmp = new ListNode<T>(),
|
||||||
|
*_prev = getNode(index-1);
|
||||||
|
tmp->data = _t;
|
||||||
|
tmp->next = _prev->next;
|
||||||
|
_prev->next = tmp;
|
||||||
|
|
||||||
|
_size++;
|
||||||
|
isCached = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool LinkedList<T>::add(T _t){
|
||||||
|
|
||||||
|
ListNode<T> *tmp = new ListNode<T>();
|
||||||
|
tmp->data = _t;
|
||||||
|
tmp->next = NULL;
|
||||||
|
|
||||||
|
if(root){
|
||||||
|
// Already have elements inserted
|
||||||
|
last->next = tmp;
|
||||||
|
last = tmp;
|
||||||
|
}else{
|
||||||
|
// First element being inserted
|
||||||
|
root = tmp;
|
||||||
|
last = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
_size++;
|
||||||
|
isCached = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool LinkedList<T>::unshift(T _t){
|
||||||
|
|
||||||
|
if(_size == 0)
|
||||||
|
return add(_t);
|
||||||
|
|
||||||
|
ListNode<T> *tmp = new ListNode<T>();
|
||||||
|
tmp->next = root;
|
||||||
|
tmp->data = _t;
|
||||||
|
root = tmp;
|
||||||
|
|
||||||
|
_size++;
|
||||||
|
isCached = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T& LinkedList<T>::operator[](int index) {
|
||||||
|
return getNode(index)->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool LinkedList<T>::set(int index, T _t){
|
||||||
|
// Check if index position is in bounds
|
||||||
|
if(index < 0 || index >= _size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
getNode(index)->data = _t;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T LinkedList<T>::pop(){
|
||||||
|
if(_size <= 0)
|
||||||
|
return T();
|
||||||
|
|
||||||
|
isCached = false;
|
||||||
|
|
||||||
|
if(_size >= 2){
|
||||||
|
ListNode<T> *tmp = getNode(_size - 2);
|
||||||
|
T ret = tmp->next->data;
|
||||||
|
delete(tmp->next);
|
||||||
|
tmp->next = NULL;
|
||||||
|
last = tmp;
|
||||||
|
_size--;
|
||||||
|
return ret;
|
||||||
|
}else{
|
||||||
|
// Only one element left on the list
|
||||||
|
T ret = root->data;
|
||||||
|
delete(root);
|
||||||
|
root = NULL;
|
||||||
|
last = NULL;
|
||||||
|
_size = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T LinkedList<T>::shift(){
|
||||||
|
if(_size <= 0)
|
||||||
|
return T();
|
||||||
|
|
||||||
|
if(_size > 1){
|
||||||
|
ListNode<T> *_next = root->next;
|
||||||
|
T ret = root->data;
|
||||||
|
delete(root);
|
||||||
|
root = _next;
|
||||||
|
_size --;
|
||||||
|
isCached = false;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}else{
|
||||||
|
// Only one left, then pop()
|
||||||
|
return pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T LinkedList<T>::remove(int index){
|
||||||
|
if (index < 0 || index >= _size)
|
||||||
|
{
|
||||||
|
return T();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(index == 0)
|
||||||
|
return shift();
|
||||||
|
|
||||||
|
if (index == _size-1)
|
||||||
|
{
|
||||||
|
return pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode<T> *tmp = getNode(index - 1);
|
||||||
|
ListNode<T> *toDelete = tmp->next;
|
||||||
|
T ret = toDelete->data;
|
||||||
|
tmp->next = tmp->next->next;
|
||||||
|
delete(toDelete);
|
||||||
|
_size--;
|
||||||
|
isCached = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T LinkedList<T>::get(int index){
|
||||||
|
ListNode<T> *tmp = getNode(index);
|
||||||
|
|
||||||
|
return (tmp ? tmp->data : T());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void LinkedList<T>::clear(){
|
||||||
|
while(size() > 0)
|
||||||
|
shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void LinkedList<T>::sort(int (*cmp)(T &, T &)){
|
||||||
|
if(_size < 2) return; // trivial case;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
|
||||||
|
ListNode<T> **joinPoint = &root;
|
||||||
|
|
||||||
|
while(*joinPoint) {
|
||||||
|
ListNode<T> *a = *joinPoint;
|
||||||
|
ListNode<T> *a_end = findEndOfSortedString(a, cmp);
|
||||||
|
|
||||||
|
if(!a_end->next ) {
|
||||||
|
if(joinPoint == &root) {
|
||||||
|
last = a_end;
|
||||||
|
isCached = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode<T> *b = a_end->next;
|
||||||
|
ListNode<T> *b_end = findEndOfSortedString(b, cmp);
|
||||||
|
|
||||||
|
ListNode<T> *tail = b_end->next;
|
||||||
|
|
||||||
|
a_end->next = NULL;
|
||||||
|
b_end->next = NULL;
|
||||||
|
|
||||||
|
while(a && b) {
|
||||||
|
if(cmp(a->data, b->data) <= 0) {
|
||||||
|
*joinPoint = a;
|
||||||
|
joinPoint = &a->next;
|
||||||
|
a = a->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*joinPoint = b;
|
||||||
|
joinPoint = &b->next;
|
||||||
|
b = b->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(a) {
|
||||||
|
*joinPoint = a;
|
||||||
|
while(a->next) a = a->next;
|
||||||
|
a->next = tail;
|
||||||
|
joinPoint = &a->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*joinPoint = b;
|
||||||
|
while(b->next) b = b->next;
|
||||||
|
b->next = tail;
|
||||||
|
joinPoint = &b->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ListNode<T>* LinkedList<T>::findEndOfSortedString(ListNode<T> *p, int (*cmp)(T &, T &)) {
|
||||||
|
while(p->next && cmp(p->data, p->next->data) <= 0) {
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -220,7 +220,6 @@ const uint16_t MAX_LOGSZ = 700; // Max number of characters in log l
|
|||||||
|
|
||||||
const uint8_t SENSOR_MAX_MISS = 5; // Max number of missed sensor reads before deciding it's offline
|
const uint8_t SENSOR_MAX_MISS = 5; // Max number of missed sensor reads before deciding it's offline
|
||||||
|
|
||||||
const uint8_t MAX_BACKLOG = 30; // Max number of commands in backlog
|
|
||||||
const uint32_t MIN_BACKLOG_DELAY = 200; // Minimal backlog delay in mSeconds
|
const uint32_t MIN_BACKLOG_DELAY = 200; // Minimal backlog delay in mSeconds
|
||||||
const uint8_t MAX_TIMED_CMND = 16; // Max number of timed commands
|
const uint8_t MAX_TIMED_CMND = 16; // Max number of timed commands
|
||||||
|
|
||||||
|
@ -497,6 +497,7 @@
|
|||||||
// -- Rules or Script ----------------------------
|
// -- Rules or Script ----------------------------
|
||||||
// Select none or only one of the below defines USE_RULES or USE_SCRIPT
|
// Select none or only one of the below defines USE_RULES or USE_SCRIPT
|
||||||
#define USE_RULES // Add support for rules (+8k code)
|
#define USE_RULES // Add support for rules (+8k code)
|
||||||
|
// #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code)
|
||||||
// #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem)
|
// #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem)
|
||||||
// #define SUPPORT_IF_STATEMENT // Add support for IF statement in rules (+4k2 code, -332 bytes mem)
|
// #define SUPPORT_IF_STATEMENT // Add support for IF statement in rules (+4k2 code, -332 bytes mem)
|
||||||
// #define USER_RULE1 "<Any rule1 data>" // Add rule1 data saved at initial firmware load or when command reset is executed
|
// #define USER_RULE1 "<Any rule1 data>" // Add rule1 data saved at initial firmware load or when command reset is executed
|
||||||
|
@ -411,11 +411,6 @@ struct TasmotaGlobal_t {
|
|||||||
uint8_t pwm_dimmer_led_bri; // Adjusted brightness LED level
|
uint8_t pwm_dimmer_led_bri; // Adjusted brightness LED level
|
||||||
#endif // USE_PWM_DIMMER
|
#endif // USE_PWM_DIMMER
|
||||||
|
|
||||||
#ifndef SUPPORT_IF_STATEMENT
|
|
||||||
uint8_t backlog_index; // Command backlog index
|
|
||||||
uint8_t backlog_pointer; // Command backlog pointer
|
|
||||||
String backlog[MAX_BACKLOG]; // Command backlog buffer
|
|
||||||
#endif
|
|
||||||
tTimedCmnd timed_cmnd[MAX_TIMED_CMND]; // Timed command buffer
|
tTimedCmnd timed_cmnd[MAX_TIMED_CMND]; // Timed command buffer
|
||||||
|
|
||||||
#ifdef MQTT_DATA_STRING
|
#ifdef MQTT_DATA_STRING
|
||||||
@ -438,19 +433,15 @@ struct TasmotaGlobal_t {
|
|||||||
#endif // PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED
|
#endif // PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED
|
||||||
|
|
||||||
#ifdef USE_BERRY
|
#ifdef USE_BERRY
|
||||||
bool berry_fast_loop_enabled = false; // is Berry fast loop enabled, i.e. control is passed at each loop iteration
|
bool berry_fast_loop_enabled = false; // is Berry fast loop enabled, i.e. control is passed at each loop iteration
|
||||||
#endif // USE_BERRY
|
#endif // USE_BERRY
|
||||||
} TasmotaGlobal;
|
} TasmotaGlobal;
|
||||||
|
|
||||||
TSettings* Settings = nullptr;
|
TSettings* Settings = nullptr;
|
||||||
|
|
||||||
#ifdef SUPPORT_IF_STATEMENT
|
#include <LinkedList.h>
|
||||||
#include <LinkedList.h>
|
LinkedList<String> backlog; // Command backlog implemented with LinkedList
|
||||||
LinkedList<String> backlog; // Command backlog implemented with LinkedList
|
#define BACKLOG_EMPTY (backlog.size() == 0)
|
||||||
#define BACKLOG_EMPTY (backlog.size() == 0)
|
|
||||||
#else
|
|
||||||
#define BACKLOG_EMPTY (TasmotaGlobal.backlog_pointer == TasmotaGlobal.backlog_index)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Main
|
* Main
|
||||||
@ -794,14 +785,7 @@ void BacklogLoop(void) {
|
|||||||
bool nodelay_detected = false;
|
bool nodelay_detected = false;
|
||||||
String cmd;
|
String cmd;
|
||||||
do {
|
do {
|
||||||
#ifdef SUPPORT_IF_STATEMENT
|
|
||||||
cmd = backlog.shift();
|
cmd = backlog.shift();
|
||||||
#else
|
|
||||||
cmd = TasmotaGlobal.backlog[TasmotaGlobal.backlog_pointer];
|
|
||||||
TasmotaGlobal.backlog[TasmotaGlobal.backlog_pointer] = (const char*) nullptr; // Force deallocation of the String internal memory
|
|
||||||
TasmotaGlobal.backlog_pointer++;
|
|
||||||
if (TasmotaGlobal.backlog_pointer >= MAX_BACKLOG) { TasmotaGlobal.backlog_pointer = 0; }
|
|
||||||
#endif
|
|
||||||
nodelay_detected = !strncasecmp_P(cmd.c_str(), PSTR(D_CMND_NODELAY), strlen(D_CMND_NODELAY));
|
nodelay_detected = !strncasecmp_P(cmd.c_str(), PSTR(D_CMND_NODELAY), strlen(D_CMND_NODELAY));
|
||||||
if (nodelay_detected) { nodelay = true; }
|
if (nodelay_detected) { nodelay = true; }
|
||||||
} while (!BACKLOG_EMPTY && nodelay_detected);
|
} while (!BACKLOG_EMPTY && nodelay_detected);
|
||||||
|
@ -580,14 +580,7 @@ void CmndBacklog(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *blcommand = strtok(XdrvMailbox.data, ";");
|
char *blcommand = strtok(XdrvMailbox.data, ";");
|
||||||
#ifdef SUPPORT_IF_STATEMENT
|
while (blcommand != nullptr) {
|
||||||
while ((blcommand != nullptr) && (backlog.size() < MAX_BACKLOG))
|
|
||||||
#else
|
|
||||||
uint32_t bl_pointer = (!TasmotaGlobal.backlog_pointer) ? MAX_BACKLOG -1 : TasmotaGlobal.backlog_pointer;
|
|
||||||
bl_pointer--;
|
|
||||||
while ((blcommand != nullptr) && (TasmotaGlobal.backlog_index != bl_pointer))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
// Ignore semicolon (; = end of single command) between brackets {}
|
// Ignore semicolon (; = end of single command) between brackets {}
|
||||||
char *next = strchr(blcommand, '\0') +1; // Prepare for next ;
|
char *next = strchr(blcommand, '\0') +1; // Prepare for next ;
|
||||||
while ((next != nullptr) && (ChrCount(blcommand, "{") != ChrCount(blcommand, "}"))) { // Check for valid {} pair
|
while ((next != nullptr) && (ChrCount(blcommand, "{") != ChrCount(blcommand, "}"))) { // Check for valid {} pair
|
||||||
@ -606,17 +599,7 @@ void CmndBacklog(void) {
|
|||||||
}
|
}
|
||||||
// Do not allow command Reset in backlog
|
// Do not allow command Reset in backlog
|
||||||
if ((*blcommand != '\0') && (strncasecmp_P(blcommand, PSTR(D_CMND_RESET), strlen(D_CMND_RESET)) != 0)) {
|
if ((*blcommand != '\0') && (strncasecmp_P(blcommand, PSTR(D_CMND_RESET), strlen(D_CMND_RESET)) != 0)) {
|
||||||
#ifdef SUPPORT_IF_STATEMENT
|
backlog.add(blcommand);
|
||||||
if (backlog.size() < MAX_BACKLOG) {
|
|
||||||
backlog.add(blcommand);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
TasmotaGlobal.backlog[TasmotaGlobal.backlog_index] = blcommand;
|
|
||||||
TasmotaGlobal.backlog_index++;
|
|
||||||
if (TasmotaGlobal.backlog_index >= MAX_BACKLOG) {
|
|
||||||
TasmotaGlobal.backlog_index = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
blcommand = strtok(nullptr, ";");
|
blcommand = strtok(nullptr, ";");
|
||||||
}
|
}
|
||||||
@ -625,11 +608,7 @@ void CmndBacklog(void) {
|
|||||||
TasmotaGlobal.backlog_timer = millis();
|
TasmotaGlobal.backlog_timer = millis();
|
||||||
} else {
|
} else {
|
||||||
bool blflag = BACKLOG_EMPTY;
|
bool blflag = BACKLOG_EMPTY;
|
||||||
#ifdef SUPPORT_IF_STATEMENT
|
|
||||||
backlog.clear();
|
backlog.clear();
|
||||||
#else
|
|
||||||
TasmotaGlobal.backlog_pointer = TasmotaGlobal.backlog_index;
|
|
||||||
#endif
|
|
||||||
ResponseCmndChar(blflag ? PSTR(D_JSON_EMPTY) : PSTR(D_JSON_ABORTED));
|
ResponseCmndChar(blflag ? PSTR(D_JSON_EMPTY) : PSTR(D_JSON_ABORTED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -657,7 +657,7 @@ void DomoticzSaveSettings(void) {
|
|||||||
snprintf_P(arg_idx, sizeof(arg_idx), PSTR("l%d"), i -1);
|
snprintf_P(arg_idx, sizeof(arg_idx), PSTR("l%d"), i -1);
|
||||||
cmnd += AddWebCommand(cmnd2, arg_idx, PSTR("0"));
|
cmnd += AddWebCommand(cmnd2, arg_idx, PSTR("0"));
|
||||||
}
|
}
|
||||||
ExecuteWebCommand((char*)cmnd.c_str()); // Note: beware of max number of commands in backlog currently 30 (MAX_BACKLOG)
|
ExecuteWebCommand((char*)cmnd.c_str());
|
||||||
}
|
}
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
|
|
||||||
|
@ -2066,7 +2066,7 @@ void ExecuteCommandBlock(const char * commands, int len)
|
|||||||
sCurrentCommand.trim();
|
sCurrentCommand.trim();
|
||||||
/*
|
/*
|
||||||
if (sCurrentCommand.length() > 0
|
if (sCurrentCommand.length() > 0
|
||||||
&& backlog.size() < MAX_BACKLOG && !TasmotaGlobal.backlog_mutex)
|
&& !TasmotaGlobal.backlog_mutex)
|
||||||
{
|
{
|
||||||
//Insert into backlog
|
//Insert into backlog
|
||||||
TasmotaGlobal.backlog_mutex = true;
|
TasmotaGlobal.backlog_mutex = true;
|
||||||
@ -2075,7 +2075,7 @@ void ExecuteCommandBlock(const char * commands, int len)
|
|||||||
insertPosition++;
|
insertPosition++;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if ((sCurrentCommand.length() > 0) && (backlog.size() < MAX_BACKLOG)) {
|
if (sCurrentCommand.length() > 0) {
|
||||||
//Insert into backlog
|
//Insert into backlog
|
||||||
backlog.add(insertPosition, sCurrentCommand);
|
backlog.add(insertPosition, sCurrentCommand);
|
||||||
insertPosition++;
|
insertPosition++;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user