252 added delete function in items list

This commit is contained in:
Dmitry Borisenko
2020-10-10 01:44:11 +03:00
parent 8bf136373c
commit 54841d59cf
34 changed files with 142 additions and 273 deletions

7
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"files.associations": {
"functional": "cpp",
"bitset": "cpp",
"algorithm": "cpp"
}
}

View File

@@ -1 +1 @@
analog-adc;id;fillgauge;Сенсоры;Аналоговый;order;gol;map[0,1024,0,100];c[1] 0;analog-adc;id;fillgauge;Сенсоры;Аналоговый;order;gol;map[0,1024,0,100];c[1]

View File

@@ -1 +1 @@
bme280-hum;id;anydataHum;Сенсоры;Влажность;order;addr[0x76];c[1] 0;bme280-hum;id;anydataHum;Сенсоры;Влажность;order;addr[0x76];c[1]

View File

@@ -1 +1 @@
bme280-press;id;anydataPress;Сенсоры;Давление;order;addr[0x76];c[1] 0;bme280-press;id;anydataPress;Сенсоры;Давление;order;addr[0x76];c[1]

View File

@@ -1 +1 @@
bme280-temp;id;anydataTemp;Сенсоры;Температура;order;addr[0x76];c[1] 0;bme280-temp;id;anydataTemp;Сенсоры;Температура;order;addr[0x76];c[1]

View File

@@ -1 +1 @@
bmp280-press;id;anydataPress;Сенсоры;Давление;order;addr[0x76];c[1] 0;bmp280-press;id;anydataPress;Сенсоры;Давление;order;addr[0x76];c[1]

View File

@@ -1 +1 @@
bmp280-temp;id;anydataTemp;Сенсоры;Температура;order;addr[0x76];c[1] 0;bmp280-temp;id;anydataTemp;Сенсоры;Температура;order;addr[0x76];c[1]

View File

@@ -1 +1 @@
button-in;id;toggle;Кнопки;Освещение;order;pin;db[20] 0;button-in;id;toggle;Кнопки;Освещение;order;pin;db[20]

View File

@@ -1 +0,0 @@
button-out;id;toggle;Кнопки;Освещение;order;pin;inv[1];st[1]

View File

@@ -1 +0,0 @@
button-out;id;toggleSunMoon;Кнопки;Освещение;order;st[0]

View File

@@ -1 +0,0 @@
button-out;id;toggle;Кнопки;Освещение;order;pin;st[0]

View File

@@ -0,0 +1 @@
0;button-out;id;toggle;Кнопки;Освещение;order;pin;inv[1];st[1]

View File

@@ -0,0 +1 @@
0;button-out;id;toggleSunMoon;Кнопки;Освещение;order;st[0]

View File

@@ -0,0 +1 @@
0;button-out;id;toggle;Кнопки;Освещение;order;pin;st[0]

View File

@@ -1 +1 @@
dallas-temp;id;anydataTemp;Сенсоры;Температура;order;sal;c[1] 0;dallas-temp;id;anydataTemp;Сенсоры;Температура;order;sal;c[1]

View File

@@ -1 +1 @@
dht-hum;id;anydataHum;Сенсоры;Влажность;order;thd;type[dht11];c[1] 0;dht-hum;id;anydataHum;Сенсоры;Влажность;order;thd;type[dht11];c[1]

View File

@@ -1 +1 @@
dht-temp;id;anydataTemp;Сенсоры;Температура;order;thd;type[dht11];c[1] 0;dht-temp;id;anydataTemp;Сенсоры;Температура;order;thd;type[dht11];c[1]

View File

@@ -1 +1 @@
dht-hum;id;anydataHum;Сенсоры;Влажность;order;thd;type[dht22];c[1] 0;dht-hum;id;anydataHum;Сенсоры;Влажность;order;thd;type[dht22];c[1]

View File

@@ -1 +1 @@
dht-temp;id;anydataTemp;Сенсоры;Температура;order;thd;type[dht22];c[1] 0;dht-temp;id;anydataTemp;Сенсоры;Температура;order;thd;type[dht22];c[1]

View File

@@ -1 +1 @@
input-digit;id;inputDigit;Ввод;Введите#цифру;order;st[60] 0;input-digit;id;inputDigit;Ввод;Введите#цифру;order;st[60]

View File

@@ -1 +1 @@
input-time;id;inputTime;Ввод;Введите#время;order;st[10-00-00] 0;input-time;id;inputTime;Ввод;Введите#время;order;st[10-00-00]

View File

@@ -1 +1 @@
modbus;id;anydata;Modbus;Регистр;order;addr[1];reg[0];c[1] 0;modbus;id;anydata;Modbus;Регистр;order;addr[1];reg[0];c[1]

View File

@@ -1 +1 @@
output-text;id;anydata;Вывод;Сигнализация;order;st[Обнаружено#движение] 0;output-text;id;anydata;Вывод;Сигнализация;order;st[Обнаружено#движение]

View File

@@ -1 +1 @@
pwm-out;id;range;Ползунки;Яркость;order;pin;st[500] 0;pwm-out;id;range;Ползунки;Яркость;order;pin;st[500]

View File

@@ -1,5 +0,0 @@
{
"more":">",
"less":"<",
"eq":"="
}

View File

@@ -1 +1 @@
ultrasonic-cm;id;anydata;Сенсоры;Расстояние;order;cin;map[0,500,0,100];c[1] 0;ultrasonic-cm;id;anydata;Сенсоры;Расстояние;order;cin;map[0,500,0,100];c[1]

View File

@@ -43,7 +43,7 @@
}, },
{ {
"type": "h4", "type": "h4",
"title": "LittleFS version: 251" "title": "LittleFS version: 252"
}, },
{ {
"type": "hr" "type": "hr"
@@ -55,10 +55,10 @@
"style": "display:inline", "style": "display:inline",
"title": { "title": {
"#": "Выберите элемент из списка<span class=\"caret\"></span>", "#": "Выберите элемент из списка<span class=\"caret\"></span>",
"/set?addItem=button-out-p": "1.Кнопка управляющая пином", "/set?addItem=button-out.pin": "1.Кнопка управляющая пином",
"/set?addItem=button-out-np": "2.Кнопка не привязанная к пину (виртуальная)", "/set?addItem=button-out.npin": "2.Кнопка виртуальная",
"/set?addItem=button-in": "4.Кнопка физическая",
"/set?addItem=pwm-out": "3.Широтно импульсная модуляция (pwm)", "/set?addItem=pwm-out": "3.Широтно импульсная модуляция (pwm)",
"/set?addItem=button-in": "4.Физическая кнопка (чтение состояния пина)",
"/set?addItem=input-digit": "5.Окно ввода цифровых значений", "/set?addItem=input-digit": "5.Окно ввода цифровых значений",
"/set?addItem=input-time": "6.Окно ввода времени", "/set?addItem=input-time": "6.Окно ввода времени",
"/set?addItem=output-text": "7.Окно вывода любого текста, предупреждения, цифры", "/set?addItem=output-text": "7.Окно вывода любого текста, предупреждения, цифры",
@@ -83,6 +83,7 @@
{ {
"type": "csv", "type": "csv",
"title": [ "title": [
"checkbox",
"html", "html",
"text", "text",
"text", "text",
@@ -98,6 +99,12 @@
{ {
"type": "hr" "type": "hr"
}, },
{
"type": "link",
"title": "Удалить выбранные элементы",
"action": "javascript:{send_request(this,'/set?delChoosingItems');setTimeout(function(){location.href='/?set.device' ; }, 1000);}",
"class": "btn btn-block btn-default"
},
{ {
"type": "link", "type": "link",
"title": "Удалить все", "title": "Удалить все",

View File

@@ -1,143 +0,0 @@
{
"configs": [
"/config.setup.json",
"/config.option.json",
"/config.live.json",
"/lang/lang.ru.json"
],
"class": "col-sm-offset-1 col-sm-10",
"content": [
{
"type": "h5",
"title": "{{name}}",
"class": "alert-default"
},
{
"type": "link",
"title": "{{ButMainPage}}",
"action": "/",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h4",
"title": "Device ID: {{chipID}}"
},
{
"type": "h4",
"title": "IP address: {{ip}}"
},
{
"type": "h4",
"title": "Time: {{time}}"
},
{
"type": "h4",
"title": "Uptime: {{uptime}}"
},
{
"type": "h4",
"title": "Build version: {{firmware_version}}"
},
{
"type": "h4",
"title": "LittleFS version: 2.3.5"
},
{
"type": "hr"
},
{
"type": "dropdown",
"name": "help-url",
"class": "btn btn-default",
"style": "display:inline",
"title": {
"#": "{{SetDevPreset}}<span class=\"caret\"></span>",
"/set?preset=001": "1.Вкл. выкл. локального реле",
"/set?preset=002": "2.Вкл. выкл. локального реле в определенное время",
"/set?preset=003": "3.Вкл. выкл. локального реле на определенный период времени",
"/set?preset=004": "4.Вкл. выкл. нескольких локальных реле кнопкой в приложении",
"/set?preset=005": "5.Вкл. выкл. локального реле физической кнопкой и кнопкой в приложении параллельно (для выключателя света)",
"/set?preset=006": "6.Вкл. выкл. нескольких удаленных реле кнопкой в приложении (нужно указать Device ID)",
"/set?preset=007": "7.Вкл. выкл. нескольких удаленных реле физической кнопкой (нужно указать Device ID)",
"/set?preset=008": "8.Широтно импульсная модуляция",
"/set?preset=009": "9.Сенсор DHT11 (темп, влажность) и логгирование",
"/set?preset=010": "10.Сенсор DHT22, DHT33, DHT44, AM2302, RHT03 (темп, влажность) и логгирование",
"/set?preset=011": "11.Аналоговый сенсор и логгирование",
"/set?preset=012": "12.Cенсор bmp280 (темп, давление) и логгирование",
"/set?preset=013": "13.Cенсор bme280 (темп, давление, влажность, высота) и логгирование",
"/set?preset=014": "14.Сенсор DS18B20 (темп) и логгирование",
"/set?preset=015": "15.Термостат на DS18B20 с переключением в ручной режим и логгированием",
"/set?preset=016": "16.Котроль уровня в баке (датчик расстояния) на сенсорах: JSN-SR04T, HC-SR04, HY-SRF05 и логгирование",
"/set?preset=017": "17.Датчик движения включающий свет",
"/set?preset=018": "18.Охранный датчик движения",
"/set?preset=019": "19.Система управления шаговыми двигателями на основе драйвера A4988 (открытие закрытие штор)",
"/set?preset=020": "20.Система управления сервоприводами",
"/set?preset=021": "21.Модуль uart (serial). Двухстороняя связь с устройством через uart. Получение данных и отправка команд",
"/set?preset=100": "22.Настройки по умолчанию"
}
},
{
"type": "h2",
"title": "{{SetDevConf}}"
},
{
"type": "file",
"state": "dev_conf.txt",
"style": "width:100%;height:350px",
"title": "Сохранить",
"action": "/set?devinit",
"class": "btn btn-block btn-default"
},
{
"type": "h2",
"title": "Сценарии"
},
{
"type": "checkbox",
"name": "scen",
"title": "Включить сценарии",
"action": "/set?scen=[[scen]]",
"state": "{{scen}}"
},
{
"type": "file",
"state": "dev_scen.txt",
"style": "width:100%;height:350px",
"title": "Сохранить",
"action": "/set?sceninit",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Инструкция к системе автоматизации",
"action": "https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/wiki/Instruction",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Очистить логи сенсоров",
"action": "/set?cleanlog",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h3",
"name": "my-block",
"style": "position:fixed;top:50%;left:50%;width:400px;margin-left:-200px;text-align:center;",
"class": "hidden"
},
{
"type": "button",
"title": "Обновить прошивку устройства",
"action": "/check",
"response": "[[my-block]]",
"class": "btn btn-block btn-default"
}
]
}

View File

@@ -2,7 +2,7 @@
//=================Firmeare================= //=================Firmeare=================
#define FIRMWARE_NAME "esp8266-iotm" #define FIRMWARE_NAME "esp8266-iotm"
#define FIRMWARE_VERSION 251 #define FIRMWARE_VERSION 252
#define FLASH_4MB true #define FLASH_4MB true
//=================System=================== //=================System===================
@@ -87,6 +87,8 @@ enum notAsincActions {
do_MQTTUDP, do_MQTTUDP,
do_BUSSCAN, do_BUSSCAN,
do_MQTTPARAMSCHANGED, do_MQTTPARAMSCHANGED,
do_deviceInit,
do_delChoosingItems,
do_LAST, do_LAST,
}; };

View File

@@ -3,7 +3,9 @@
#include <Arduino.h> #include <Arduino.h>
#include "Global.h" #include "Global.h"
extern void itemsListInit();
extern void addItem(String name); extern void addItem(String name);
extern void delChoosingItems();
extern void delAllItems(); extern void delAllItems();
extern uint8_t getNewElementNumber(String file); extern uint8_t getNewElementNumber(String file);
extern uint8_t getFreePinAll(); extern uint8_t getFreePinAll();

View File

@@ -18,6 +18,7 @@ void fileCmdExecute(const String &filename) {
} }
void csvCmdExecute(String &cmdStr) { void csvCmdExecute(String &cmdStr) {
cmdStr.replace(";", " "); cmdStr.replace(";", " ");
cmdStr += "\r\n"; cmdStr += "\r\n";
cmdStr.replace("\r\n", "\n"); cmdStr.replace("\r\n", "\n");
@@ -25,6 +26,7 @@ void csvCmdExecute(String &cmdStr) {
int count = 0; int count = 0;
while (cmdStr.length()) { while (cmdStr.length()) {
String buf = selectToMarker(cmdStr, "\n"); String buf = selectToMarker(cmdStr, "\n");
buf = deleteBeforeDelimiter(buf, " "); //отсечка чекбокса
count++; count++;
if (count > 1) sCmd.readStr(buf); if (count > 1) sCmd.readStr(buf);
cmdStr = deleteBeforeDelimiter(cmdStr, "\n"); cmdStr = deleteBeforeDelimiter(cmdStr, "\n");

View File

@@ -1,23 +1,51 @@
#include "ItemsList.h" #include "ItemsList.h"
#include "Class\NotAsinc.h"
#include "Init.h"
#include "Utils\StringUtils.h" #include "Utils\StringUtils.h"
static const char* firstLine PROGMEM = "Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета"; static const char* firstLine PROGMEM = "Удалить;Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета";
void itemsListInit() {
myNotAsincActions->add(
do_deviceInit, [&](void*) {
Device_init();
},
nullptr);
myNotAsincActions->add(
do_delChoosingItems, [&](void*) {
delChoosingItems();
Device_init();
},
nullptr);
}
void addItem(String name) { void addItem(String name) {
String item = readFile("items/" + name + ".txt", 1024); String item = readFile("items/" + name + ".txt", 1024);
name = deleteToMarkerLast(name, "-");
name = deleteToMarkerLast(name, ".");
item.replace("id", name + "-" + String(getNewElementNumber("id.txt"))); item.replace("id", name + "-" + String(getNewElementNumber("id.txt")));
item.replace("order", String(getNewElementNumber("order.txt"))); item.replace("order", String(getNewElementNumber("order.txt")));
if (item.indexOf("pin") != -1) { //all cases (random pins from available) if (item.indexOf("pin") != -1) { //all cases (random pins from available)
item.replace("pin", "pin[" + String(getFreePinAll()) + "]"); item.replace("pin", "pin[" + String(getFreePinAll()) + "]");
} else if (item.indexOf("gol") != -1) { //analog } else
if (item.indexOf("gol") != -1) { //analog
item.replace("gol", "pin[" + String(getFreePinAnalog()) + "]"); item.replace("gol", "pin[" + String(getFreePinAnalog()) + "]");
} else if (item.indexOf("cin") != -1) { //ultrasonic } else
if (item.indexOf("cin") != -1) { //ultrasonic
item.replace("cin", "pin[" + String(getFreePinAll()) + "," + String(getFreePinAll()) + "]"); item.replace("cin", "pin[" + String(getFreePinAll()) + "," + String(getFreePinAll()) + "]");
} else if (item.indexOf("sal") != -1) { //dallas } else
if (item.indexOf("sal") != -1) { //dallas
item.replace("sal", "pin[2]"); item.replace("sal", "pin[2]");
} else if (item.indexOf("thd") != -1) { //dht11/22 } else
if (item.indexOf("thd") != -1) { //dht11/22
item.replace("thd", "pin[2]"); item.replace("thd", "pin[2]");
} }
@@ -65,71 +93,28 @@ uint8_t getFreePinAnalog() {
#endif #endif
} }
//void do_getJsonListFromCsv() { void delChoosingItems() {
// if (getJsonListFromCsvFlag) { File configFile = LittleFS.open("/" + String(DEVICE_CONFIG_FILE), "r");
// getJsonListFromCsvFlag = false; if (!configFile) {
// removeFile("items/items.json"); return;
// addFile("items/items.json", getJsonListFromCsv(DEVICE_CONFIG_FILE, 1)); }
// } configFile.seek(0, SeekSet);
//} String finalConf;
// bool firstLine = true;
//String getJsonListFromCsv(String csvFile, int colum) { while (configFile.position() != configFile.size()) {
// File configFile = LittleFS.open("/" + csvFile, "r"); String item = configFile.readStringUntil('\n');
// if (!configFile) { if (firstLine) {
// return "error"; finalConf += item;
// } } else {
// configFile.seek(0, SeekSet); int checkbox = selectToMarker(item, ";").toInt();
// if (checkbox == 0) {
// String outJson = "{}"; finalConf += "\n" + item;
// }
// int count = -1; }
// firstLine = false;
// while (configFile.position() != configFile.size()) { }
// count++; removeFile(String(DEVICE_CONFIG_FILE));
// String item = configFile.readStringUntil('\n'); addFile(String(DEVICE_CONFIG_FILE), finalConf);
// if (count > 0) { Serial.println(finalConf);
// String line = selectFromMarkerToMarker(item, ";", colum); configFile.close();
// jsonWriteStr(outJson, line, line); }
// }
// }
// configFile.close();
// csvFile = "";
// return outJson;
//}
//
//void do_delElement() {
// if (delElementFlag) {
// delElementFlag = false;
// delElement(itemsFile, itemsLine);
// }
//}
//
//void delElement(String _itemsFile, String _itemsLine) {
// File configFile = LittleFS.open("/" + _itemsFile, "r");
// if (!configFile) {
// return;
// }
// configFile.seek(0, SeekSet);
// String finalConf;
// int count = -1;
// while (configFile.position() != configFile.size()) {
// count++;
// String item = configFile.readStringUntil('\n');
// Serial.print(_itemsLine);
// Serial.print(" ");
// Serial.println(count);
// if (count != _itemsLine.toInt()) {
// if (count == 0) {
// finalConf += item;
// } else {
// finalConf += "\n" + item;
// }
// }
// }
// removeFile(_itemsFile);
// addFile(_itemsFile, finalConf);
// Serial.println(finalConf);
// itemsFile = "";
// itemsLine = "";
// configFile.close();
//}

View File

@@ -14,30 +14,34 @@ bool parseRequestForPreset(AsyncWebServerRequest* request, uint8_t& preset) {
} }
void web_init() { void web_init() {
server.on("/set", HTTP_GET, [](AsyncWebServerRequest* request) { server.on("/set", HTTP_GET, [](AsyncWebServerRequest* request) {
//==============================set.device.json==================================================================================================== //==============================set.device.json====================================================================================================
if (request->hasArg("addItem")) { if (request->hasArg("addItem")) {
String name = request->getParam("addItem")->value(); String name = request->getParam("addItem")->value();
addItem(name); addItem(name);
//Device_init(); myNotAsincActions->make(do_deviceInit);
request->redirect("/?set.device"); request->redirect("/?set.device");
} }
if (request->hasArg("delChoosingItems")) {
myNotAsincActions->make(do_delChoosingItems);
request->send(200);
}
if (request->hasArg("delAllItems")) { if (request->hasArg("delAllItems")) {
delAllItems(); delAllItems();
Device_init(); myNotAsincActions->make(do_deviceInit);
request->redirect("/?set.device"); request->redirect("/?set.device");
} }
if (request->hasArg("saveItems")) { if (request->hasArg("saveItems")) {
Device_init(); myNotAsincActions->make(do_deviceInit);
request->redirect("/?set.device"); request->redirect("/?set.device");
} }
//==============================init==================================================================================================== //==============================init====================================================================================================
if (request->hasArg("devinit")) { if (request->hasArg("devinit")) {
Device_init(); myNotAsincActions->make(do_deviceInit);
request->send(200); request->send(200);
} }
@@ -134,6 +138,13 @@ void web_init() {
request->send(200); request->send(200);
} }
if (request->hasArg("test")) {
if (request->getParam("test")->value() == "ok") {
Serial.println("test pass");
}
request->send(200);
}
//==============================mqtt settings============================================= //==============================mqtt settings=============================================
if (request->hasArg("mqttServer")) { if (request->hasArg("mqttServer")) {

View File

@@ -5,11 +5,11 @@
#include "Class/CallBackTest.h" #include "Class/CallBackTest.h"
#include "Class/NotAsinc.h" #include "Class/NotAsinc.h"
#include "Class/ScenarioClass.h" #include "Class/ScenarioClass.h"
#include "Utils/StatUtils.h"
#include "Cmd.h" #include "Cmd.h"
#include "Global.h" #include "Global.h"
#include "Init.h" #include "Init.h"
#include "ItemsList.h" #include "ItemsList.h"
#include "Utils/StatUtils.h"
#include "Utils/Timings.h" #include "Utils/Timings.h"
#include "Utils\WebUtils.h" #include "Utils\WebUtils.h"
#include "items/ButtonInClass.h" #include "items/ButtonInClass.h"
@@ -18,7 +18,6 @@
void not_async_actions(); void not_async_actions();
Timings metric; Timings metric;
boolean initialized = false; boolean initialized = false;
@@ -36,57 +35,59 @@ void setup() {
myNotAsincActions = new NotAsinc(do_LAST); myNotAsincActions = new NotAsinc(do_LAST);
myScenario = new Scenario(); myScenario = new Scenario();
SerialPrint("I","FS","FS Init"); SerialPrint("I", "FS", "FS Init");
fileSystemInit(); fileSystemInit();
SerialPrint("I","Conf","Config Init"); SerialPrint("I", "Conf", "Config Init");
loadConfig(); loadConfig();
SerialPrint("I","Time","Clock Init"); SerialPrint("I", "Time", "Clock Init");
clock_init(); clock_init();
SerialPrint("I","CMD","Commands Init"); SerialPrint("I", "CMD", "Commands Init");
cmd_init(); cmd_init();
SerialPrint("I","Sensors","Sensors Init"); SerialPrint("I", "Sensors", "Sensors Init");
sensorsInit(); sensorsInit();
SerialPrint("I","Init","Init Init"); SerialPrint("I", "Items", "Items Init");
itemsListInit();
SerialPrint("I", "Init", "Init Init");
all_init(); all_init();
SerialPrint("I","WIFI","Network Init"); SerialPrint("I", "WIFI", "Network Init");
routerConnect(); routerConnect();
SerialPrint("I","Uptime","Uptime Init"); SerialPrint("I", "Uptime", "Uptime Init");
uptime_init(); uptime_init();
SerialPrint("I","Update","Updater Init"); SerialPrint("I", "Update", "Updater Init");
upgradeInit(); upgradeInit();
SerialPrint("I","HTTP","HttpServer Init"); SerialPrint("I", "HTTP", "HttpServer Init");
HttpServer::init(); HttpServer::init();
SerialPrint("I","Web","WebAdmin Init"); SerialPrint("I", "Web", "WebAdmin Init");
web_init(); web_init();
SerialPrint("I","Stat","Stat Init"); SerialPrint("I", "Stat", "Stat Init");
initSt(); initSt();
//SerialPrint("I","UDP","Udp Init"); //SerialPrint("I","UDP","Udp Init");
//asyncUdpInit(); //asyncUdpInit();
SerialPrint("I","Bus","Bus Init"); SerialPrint("I", "Bus", "Bus Init");
busInit(); busInit();
#ifdef SSDP_EN #ifdef SSDP_EN
SerialPrint("I","SSDP","Ssdp Init"); SerialPrint("I", "SSDP", "Ssdp Init");
SsdpInit(); SsdpInit();
#endif #endif
ts.add( ts.add(
TEST, 1000 * 60, [&](void*) { TEST, 1000 * 60, [&](void*) {
SerialPrint("I","System",printMemoryStatus()); SerialPrint("I", "System", printMemoryStatus());
}, },
nullptr, true); nullptr, true);