diff --git a/PrepareProject.py b/PrepareProject.py index 46157d96..3e4cb507 100644 --- a/PrepareProject.py +++ b/PrepareProject.py @@ -207,7 +207,7 @@ with open("platformio.ini", 'w') as configFile: config.write(configFile) # сохраняем применяемый профиль в папку data_svelte для загрузки на контроллер и дальнейшего переиспользования -print(f"Сохраняем профиль {profile} в {dataDir}") +print(f"Saving profile {profile} in {dataDir}") shutil.copy(profile, dataDir + "/" + profile) @@ -218,10 +218,10 @@ shutil.copy(profile, dataDir + "/" + profile) # ctypes.windll.user32.MessageBoxW(0, "Профиль " + profile + " применен, можно запускать компиляцию и прошивку.", "Операция завершена.", 0) if update: - print(f"\x1b[1;31;42m Модули профиля " + profile + " обновлены, а сам профиль применен, можно запускать компиляцию и прошивку.\x1b[0m") + print(f"\x1b[1;31;42m Profile modules " + profile + " updated, profile applied, you can run compilation and firmware.\x1b[0m") else: - print(f"\x1b[1;31;42m Профиль ", profile, " применен, можно запускать компиляцию и прошивку.\x1b[0m") + print(f"\x1b[1;31;42m Profile ", profile, " applied, you can run compilation and firmware.\x1b[0m") # print(f"\x1b[1;32;41m Операция завершена. \x1b[0m") diff --git a/bin/esp32bootloader/boot_app0.bin b/bin/esp32bootloader/boot_app0.bin new file mode 100644 index 00000000..13562cab Binary files /dev/null and b/bin/esp32bootloader/boot_app0.bin differ diff --git a/bin/esp32bootloader/bootloader_qio_80m.bin b/bin/esp32bootloader/bootloader_qio_80m.bin new file mode 100644 index 00000000..944f4947 Binary files /dev/null and b/bin/esp32bootloader/bootloader_qio_80m.bin differ diff --git a/data_svelte/items.json b/data_svelte/items.json index b14eb20e..3a180753 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -712,7 +712,7 @@ "type": "Writing", "subtype": "IoTServo", "id": "servo", - "widget": "range", + "widget": "rangeServo", "page": "servo", "descr": "угол", "int": 1, @@ -757,7 +757,7 @@ "id": "impulse", "widget": "anydataDef", "page": "Кнопки", - "descr": "Количество нажаний", + "descr": "Количество нажатий", "needSave": 0, "int": 300, "inv": 1, @@ -820,7 +820,7 @@ "subtype": "Lcd2004", "id": "Lcd", "widget": "inputTxt", - "page": "Экраны", + "page": "screens", "descr": "LCD Экран", "addr": "0x27", "size": "20,4", @@ -836,7 +836,7 @@ "subtype": "Lcd2004", "id": "Lcd", "widget": "inputTxt", - "page": "Экраны", + "page": "screens", "descr": "LCD Экран", "addr": "0x27", "size": "16,2", @@ -845,5 +845,25 @@ "prefix": "", "postfix": "", "num": 55 + }, + { + "global": 0, + "name": "56. 7 сегментный дисплей TM16XX", + "type": "Writing", + "subtype": "TM16XX", + "id": "tm", + "widget": "inputTxt", + "page": "screens", + "descr": "Экран", + "round": 0, + "chip": 1637, + "numDigits": 4, + "DIO": "13", + "CLK": "14", + "STB": "12", + "intensity": "5", + "on": "1", + "id2show": "", + "num": 56 } ] \ No newline at end of file diff --git a/data_svelte/myProfile.json b/data_svelte/myProfile.json index de8ef3fd..d98d0798 100644 --- a/data_svelte/myProfile.json +++ b/data_svelte/myProfile.json @@ -3,8 +3,14 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": "iot", - "routerpass": "hostel3333", + "routerssid": [ + "iot", + "wifi" + ], + "routerpass": [ + "hostel3333", + "pswd" + ], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", @@ -27,13 +33,70 @@ "default_envs": "esp8266_4mb", "comments_default_envs": "choose from: esp8266_4mb or esp32_4mb or esp32s2_4mb or esp8266_1mb or esp8266_1mb_ota or esp8285_1mb or esp8285_1mb_ota", "envs": [ - "esp8266_4mb", - "esp32_4mb", - "esp8266_1mb", - "esp8266_1mb_ota", - "esp8285_1mb", - "esp8285_1mb_ota", - "esp32s2_4mb" + { + "name": "esp8266_4mb", + "firmware": "0x00000", + "littlefs": "0x300000" + }, + { + "name": "esp8266_16mb", + "firmware": "0x00000", + "littlefs": "0x200000" + }, + { + "name": "esp32_4mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x290000" + }, + { + "name": "esp32_16mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x910000" + }, + { + "name": "esp8266_1mb", + "firmware": "0x00000000", + "littlefs": "0x000bb000" + }, + { + "name": "esp8266_1mb_ota", + "firmware": "0x00000000", + "littlefs": "0x000eb000" + }, + { + "name": "esp8266_2mb", + "firmware": "0x00000000", + "littlefs": "0x00100000" + }, + { + "name": "esp8266_2mb_ota", + "firmware": "0x00000000", + "littlefs": "0x001c0000" + }, + { + "name": "esp8285_1mb", + "firmware": "0x00000000", + "littlefs": "0x000bb000" + }, + { + "name": "esp8285_1mb_ota", + "firmware": "0x00000000", + "littlefs": "0x000eb000" + }, + { + "name": "esp32s2_4mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x290000" + } ] } }, @@ -126,11 +189,11 @@ "active": false }, { - "path": "src/modules/sensors/Ds2423", + "path": "src/modules/sensors/Emon", "active": false }, { - "path": "src/modules/sensors/Emon", + "path": "src/modules/sensors/ExampleModule", "active": false }, { @@ -165,6 +228,10 @@ "path": "src/modules/sensors/Ina219", "active": false }, + { + "path": "src/modules/sensors/Ina226", + "active": false + }, { "path": "src/modules/sensors/IoTWiegand", "active": false @@ -314,6 +381,10 @@ { "path": "src/modules/exec/Thermostat", "active": false + }, + { + "path": "src/modules/sensors/Ds2423", + "active": false } ], "screens": [ @@ -329,10 +400,18 @@ "path": "src/modules/display/NextionUpload", "active": false }, + { + "path": "src/modules/display/Oled128", + "active": false + }, { "path": "src/modules/display/Smi2_m", "active": true }, + { + "path": "src/modules/display/TM16XX", + "active": true + }, { "path": "src/modules/display/Ws2812b", "active": false diff --git a/data_svelte/settings.json b/data_svelte/settings.json index 297019c9..376ea5c9 100644 --- a/data_svelte/settings.json +++ b/data_svelte/settings.json @@ -2,8 +2,14 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": "iot", - "routerpass": "hostel3333", + "routerssid": [ + "iot", + "wifi" + ], + "routerpass": [ + "hostel3333", + "pswd" + ], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", diff --git a/data_svelte/widgets.json b/data_svelte/widgets.json index ba91a71f..8a758af7 100644 --- a/data_svelte/widgets.json +++ b/data_svelte/widgets.json @@ -246,11 +246,11 @@ "debounce": 500 }, { - "name": "range", + "name": "rangeServo", "label": "Ползунок (Servo)", "widget": "range", "descrColor": "red", - "after": "%", + "after": "°", "k": 1, "min": 0, "max": 180, diff --git a/data_svelte_lite/items.json b/data_svelte_lite/items.json index b8a7410e..b3894185 100644 --- a/data_svelte_lite/items.json +++ b/data_svelte_lite/items.json @@ -4,7 +4,7 @@ "num": 0 }, { - "header": "Виртуальные элементы" + "header": "virtual_elments" }, { "global": 0, @@ -189,7 +189,7 @@ "num": 12 }, { - "header": "Сенсоры" + "header": "sensors" }, { "name": "13. Acs712 Ток", @@ -197,7 +197,7 @@ "subtype": "Acs712", "id": "amp", "widget": "anydataAmp", - "page": "Сенсоры", + "page": "sensors", "descr": "Ток", "round": 3, "pin": 39, @@ -216,7 +216,7 @@ "subtype": "AnalogAdc", "id": "t", "widget": "anydataTmp", - "page": "Сенсоры", + "page": "sensors", "descr": "Температура", "map": "1,1024,1,100", "plus": 0, @@ -234,7 +234,7 @@ "subtype": "Bme280t", "id": "Tmp3", "widget": "anydataTmp", - "page": "Сенсоры", + "page": "sensors", "descr": "Температура", "int": 15, "addr": "0x77", @@ -248,7 +248,7 @@ "subtype": "Bme280p", "id": "Press3", "widget": "anydataMm", - "page": "Сенсоры", + "page": "sensors", "descr": "Давление", "int": 15, "addr": "0x77", @@ -262,7 +262,7 @@ "subtype": "Bme280h", "id": "Hum3", "widget": "anydataHum", - "page": "Сенсоры", + "page": "sensors", "descr": "Влажность", "int": 15, "addr": "0x77", @@ -276,7 +276,7 @@ "subtype": "Bme280dp", "id": "Dew3", "widget": "anydataTmp", - "page": "Сенсоры", + "page": "sensors", "descr": "Точка росы", "int": 15, "addr": "0x77", @@ -290,7 +290,7 @@ "subtype": "Bmp280t", "id": "tmp3", "widget": "anydataTmp", - "page": "Сенсоры", + "page": "sensors", "descr": "280 Температура", "int": 15, "addr": "0x77", @@ -304,7 +304,7 @@ "subtype": "Bmp280p", "id": "Press3", "widget": "anydataMm", - "page": "Сенсоры", + "page": "sensors", "descr": "280 Давление", "int": 15, "addr": "0x77", @@ -318,7 +318,7 @@ "subtype": "Ds18b20", "id": "dstmp", "widget": "anydataTmp", - "page": "Сенсоры", + "page": "sensors", "descr": "DS Температура", "int": 15, "pin": 2, @@ -471,7 +471,7 @@ "subtype": "Sht20t", "id": "tmp2", "widget": "anydataTmp", - "page": "Сенсоры", + "page": "sensors", "descr": "Температура", "int": 15, "round": 1, @@ -484,7 +484,7 @@ "subtype": "Sht20h", "id": "Hum2", "widget": "anydataHum", - "page": "Сенсоры", + "page": "sensors", "descr": "Влажность", "int": 15, "round": 1, @@ -497,7 +497,7 @@ "subtype": "Sht30t", "id": "tmp30", "widget": "anydataTmp", - "page": "Сенсоры", + "page": "sensors", "descr": "SHT30 Температура", "int": 15, "round": 1, @@ -510,7 +510,7 @@ "subtype": "Sht30h", "id": "Hum30", "widget": "anydataHum", - "page": "Сенсоры", + "page": "sensors", "descr": "SHT30 Влажность", "int": 15, "round": 1, @@ -524,7 +524,7 @@ "subtype": "Sonar", "id": "sonar", "widget": "anydataTmp", - "page": "Сенсоры", + "page": "sensors", "descr": "Расстояние (см)", "pinTrig": 5, "pinEcho": 4, @@ -546,7 +546,7 @@ "num": 36 }, { - "header": "Исполнительные устройства" + "header": "executive_devices" }, { "global": 0, @@ -658,7 +658,7 @@ "num": 43 }, { - "header": "Экраны" + "header": "screens" }, { "global": 0, diff --git a/data_svelte_lite/myProfile.json b/data_svelte_lite/myProfile.json index 24d8a8db..74f9bad7 100644 --- a/data_svelte_lite/myProfile.json +++ b/data_svelte_lite/myProfile.json @@ -29,7 +29,7 @@ } }, "modules": { - "Виртуальные элементы": [ + "virtual_elments": [ { "path": "src/modules/virtual/Cron", "active": true @@ -63,7 +63,7 @@ "active": false } ], - "Сенсоры": [ + "sensors": [ { "path": "src/modules/sensors/Acs712", "active": true @@ -193,7 +193,7 @@ "active": true } ], - "Исполнительные устройства": [ + "executive_devices": [ { "path": "src/modules/exec/ButtonIn", "active": true @@ -267,7 +267,7 @@ "active": false } ], - "Экраны": [ + "screens": [ { "path": "src/modules/display/DwinI", "active": false diff --git a/data_svelte_lite/widgets copy.json b/data_svelte_lite/widgets copy.json deleted file mode 100644 index ba91a71f..00000000 --- a/data_svelte_lite/widgets copy.json +++ /dev/null @@ -1,308 +0,0 @@ -[ - { - "name": "anydataRed", - "label": "Сообщение1", - "widget": "anydata", - "icon": "body", - "color": "red", - "descrColor": "red" - }, - { - "name": "anydataDgr", - "label": "Сообщение2", - "widget": "anydata", - "after": "", - "color": "red", - "icon": "walk" - }, - { - "name": "anydataDef", - "label": "Текст", - "widget": "anydata", - "after": "", - "icon": "" - }, - { - "name": "anydataVlt", - "label": "Вольты", - "widget": "anydata", - "after": "V", - "icon": "speedometer" - }, - { - "name": "anydataAmp", - "label": "Амперы", - "widget": "anydata", - "after": "A", - "icon": "speedometer" - }, - { - "name": "anydataWt", - "label": "Ватты", - "widget": "anydata", - "after": "Wt", - "icon": "speedometer", - "color": [ - { - "level": 0, - "value": "" - }, - { - "level": 200, - "value": "#009933" - }, - { - "level": 2000, - "value": "#FF9900" - }, - { - "level": 4000, - "value": "red" - } - ] - }, - { - "name": "anydataWth", - "label": "Энергия", - "widget": "anydata", - "after": "kWh", - "icon": "speedometer" - }, - { - "name": "anydataHtz", - "label": "Герцы", - "widget": "anydata", - "after": "Hz", - "icon": "speedometer" - }, - { - "name": "anydataTmp", - "label": "Температура", - "widget": "anydata", - "after": "°С", - "icon": "thermometer", - "font": "OCR A Std", - "color": [ - { - "level": -20, - "value": "#0000CC" - }, - { - "level": -10, - "value": "#0000CC" - }, - { - "level": 0, - "value": "#0000CC" - }, - { - "level": 12, - "value": "#3366FF" - }, - { - "level": 16, - "value": "#33CCFF" - }, - { - "level": 18, - "value": "#009933" - }, - { - "level": 30, - "value": "#FF9900" - }, - { - "level": 40, - "value": "red" - } - ] - }, - { - "name": "anydataMm", - "label": "Давление", - "widget": "anydata", - "after": "mm", - "icon": "speedometer" - }, - { - "name": "anydataHum", - "label": "Влажность", - "widget": "anydata", - "after": "%", - "icon": "water", - "color": "#88AADF" - }, - { - "name": "anydataTm", - "label": "Время", - "widget": "anydata", - "after": "", - "icon": "speedometer" - }, - { - "name": "button", - "label": "Кнопка", - "widget": "btn", - "size": "large", - "color": "green", - "send": "test" - }, - { - "name": "toggle", - "label": "Переключатель", - "widget": "toggle", - "icon": "", - "iconOff": "" - }, - { - "name": "chart1", - "label": "График без точек", - "widget": "chart", - "dateFormat": "HH:mm", - "maxCount": 86400, - "pointRadius": 0 - }, - { - "name": "chart2", - "label": "График с точками", - "widget": "chart", - "maxCount": 86400, - "dateFormat": "HH:mm" - }, - { - "name": "chart3", - "label": "График Дневной", - "widget": "chart", - "dateFormat": "DD.MM.YYYY", - "maxCount": 86400, - "type": "bar" - }, - { - "name": "fillgauge", - "label": "Бочка", - "widget": "fillgauge", - "circleColor": "#00FFFF", - "textColor": "#FFFFFF", - "waveTextColor": "#000000", - "waveColor": "#00FFFF" - }, - { - "name": "inputDate", - "label": "Ввод даты", - "widget": "input", - "size": "small", - "color": "orange", - "type": "date" - }, - { - "name": "inputDgt", - "label": "Ввод числа", - "widget": "input", - "color": "blue", - "type": "number" - }, - { - "name": "inputTxt", - "label": "Ввод текста", - "widget": "input", - "size": "small", - "color": "orange", - "type": "text" - }, - { - "name": "inputTm", - "label": "Ввод времени", - "widget": "input", - "color": "blue", - "type": "time" - }, - { - "name": "progressLine", - "label": "Статус линия", - "widget": "progress-line", - "icon": "sunny", - "max": "100", - "stroke": "10" - }, - { - "name": "progressRound", - "label": "Статус круг", - "widget": "progress-round", - "max": "100", - "stroke": "20", - "color": "#45ccce", - "background": "#777", - "semicircle": "1" - }, - { - "name": "range", - "label": "Ползунок", - "widget": "range", - "descrColor": "red", - "after": "%", - "k": 0.0977, - "min": 0, - "max": 100, - "debounce": 500 - }, - { - "name": "range", - "label": "Ползунок (Servo)", - "widget": "range", - "descrColor": "red", - "after": "%", - "k": 1, - "min": 0, - "max": 180, - "debounce": 500 - }, - { - "name": "select", - "label": "Выпадающий", - "widget": "select", - "options": [ - "Выключен", - "Включен" - ], - "status": 0 - }, - { - "name": "anydataPpm", - "label": "PPM", - "widget": "anydata", - "after": "ppm", - "icon": "speedometer" - }, - { - "name": "anydatamAmp", - "label": "миллиАмперы", - "widget": "anydata", - "after": "mAmp", - "icon": "speedometer" - }, - { - "name": "anydatamVlt", - "label": "миллиВольты", - "widget": "anydata", - "after": "mVlt", - "icon": "speedometer" - }, - { - "name": "anydatamWt", - "label": "миллиВатты", - "widget": "anydata", - "after": "mWt", - "icon": "speedometer" - }, - { - "name": "anydataCm", - "label": "Сантиметры", - "widget": "anydata", - "after": "cm", - "icon": "speedometer" - }, - { - "name": "nil", - "label": "Без виджета" - } -] \ No newline at end of file diff --git a/data_svelte_lite/widgets.json b/data_svelte_lite/widgets.json index ba91a71f..8a758af7 100644 --- a/data_svelte_lite/widgets.json +++ b/data_svelte_lite/widgets.json @@ -246,11 +246,11 @@ "debounce": 500 }, { - "name": "range", + "name": "rangeServo", "label": "Ползунок (Servo)", "widget": "range", "descrColor": "red", - "after": "%", + "after": "°", "k": 1, "min": 0, "max": 180, diff --git a/include/Const.h b/include/Const.h index 25af4872..83c349f3 100644 --- a/include/Const.h +++ b/include/Const.h @@ -24,10 +24,18 @@ #define FIRMWARE_NAME "esp8266_4mb" #endif +#ifdef esp8266_16mb +#define FIRMWARE_NAME "esp8266_16mb" +#endif + #ifdef esp32_4mb #define FIRMWARE_NAME "esp32_4mb" #endif +#ifdef esp32_16mb +#define FIRMWARE_NAME "esp32_16mb" +#endif + #ifdef esp32s2_4mb #define FIRMWARE_NAME "esp32s2_4mb" #endif diff --git a/include/MqttClient.h b/include/MqttClient.h index 99ed843f..35827e4e 100644 --- a/include/MqttClient.h +++ b/include/MqttClient.h @@ -14,6 +14,7 @@ boolean mqttConnect(); void mqttReconnect(); void mqttLoop(); void mqttSubscribe(); +bool mqttIsConnect(); boolean publish(const String& topic, const String& data); boolean publishData(const String& topic, const String& data); @@ -21,6 +22,7 @@ boolean publishChartMqtt(const String& topic, const String& data); boolean publishJsonMqtt(const String& topic, const String& json); boolean publishStatusMqtt(const String& topic, const String& data); boolean publishEvent(const String& topic, const String& data); +void mqttSubscribeExternal(String topic, bool usePrefix); bool publishChartFileToMqtt(String path, String id, int maxCount); diff --git a/include/utils/JsonUtils.h b/include/utils/JsonUtils.h index c48fd725..2d03ce8c 100644 --- a/include/utils/JsonUtils.h +++ b/include/utils/JsonUtils.h @@ -15,6 +15,7 @@ extern bool jsonRead(const String& json, String key, float& value, bool e = true extern bool jsonRead(const String& json, String key, String& value, bool e = true); extern bool jsonRead(const String& json, String key, bool& value, bool e = true); extern bool jsonRead(const String& json, String key, int& value, bool e = true); +extern bool jsonReadArray(const String& json, String key, std::vector& jArray, bool e = true); extern String jsonReadStr(const String& json, String name, bool e = true); extern int jsonReadInt(const String& json, String name, bool e = true); diff --git a/include/utils/WiFiUtils.h b/include/utils/WiFiUtils.h index 89bec1f4..c4e43850 100644 --- a/include/utils/WiFiUtils.h +++ b/include/utils/WiFiUtils.h @@ -2,11 +2,11 @@ #include "Global.h" #include "MqttClient.h" - +#include // boolean isNetworkActive(); inline boolean isNetworkActive() {return WiFi.status() == WL_CONNECTED;}; void routerConnect(); bool startAPMode(); -boolean RouterFind(String ssid); +boolean RouterFind(std::vector jArray); uint8_t RSSIquality(); extern void wifiSignalInit(); diff --git a/myProfile.json b/myProfile.json index c5e68598..0170a5e1 100644 --- a/myProfile.json +++ b/myProfile.json @@ -27,13 +27,70 @@ "default_envs": "esp8266_4mb", "comments_default_envs": "choose from: esp8266_4mb or esp32_4mb or esp32s2_4mb or esp8266_1mb or esp8266_1mb_ota or esp8285_1mb or esp8285_1mb_ota", "envs": [ - "esp8266_4mb", - "esp32_4mb", - "esp8266_1mb", - "esp8266_1mb_ota", - "esp8285_1mb", - "esp8285_1mb_ota", - "esp32s2_4mb" + { + "name": "esp8266_4mb", + "firmware": "0x00000", + "littlefs": "0x300000" + }, + { + "name": "esp8266_16mb", + "firmware": "0x00000", + "littlefs": "0x200000" + }, + { + "name": "esp32_4mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x290000" + }, + { + "name": "esp32_16mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x910000" + }, + { + "name": "esp8266_1mb", + "firmware": "0x00000000", + "littlefs": "0x000bb000" + }, + { + "name": "esp8266_1mb_ota", + "firmware": "0x00000000", + "littlefs": "0x000eb000" + }, + { + "name": "esp8266_2mb", + "firmware": "0x00000000", + "littlefs": "0x00100000" + }, + { + "name": "esp8266_2mb_ota", + "firmware": "0x00000000", + "littlefs": "0x001c0000" + }, + { + "name": "esp8285_1mb", + "firmware": "0x00000000", + "littlefs": "0x000bb000" + }, + { + "name": "esp8285_1mb_ota", + "firmware": "0x00000000", + "littlefs": "0x000eb000" + }, + { + "name": "esp32s2_4mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x290000" + } ] } }, @@ -125,10 +182,6 @@ "path": "src/modules/sensors/DS2401", "active": false }, - { - "path": "src/modules/sensors/Ds2423", - "active": false - }, { "path": "src/modules/sensors/Emon", "active": false @@ -322,6 +375,10 @@ { "path": "src/modules/exec/Thermostat", "active": false + }, + { + "path": "src/modules/sensors/Ds2423", + "active": false } ], "screens": [ @@ -337,10 +394,18 @@ "path": "src/modules/display/NextionUpload", "active": false }, + { + "path": "src/modules/display/Oled128", + "active": false + }, { "path": "src/modules/display/Smi2_m", "active": true }, + { + "path": "src/modules/display/TM16XX", + "active": true + }, { "path": "src/modules/display/Ws2812b", "active": false diff --git a/myProfileDef.json b/myProfileDef.json index de8ef3fd..0170a5e1 100644 --- a/myProfileDef.json +++ b/myProfileDef.json @@ -27,13 +27,70 @@ "default_envs": "esp8266_4mb", "comments_default_envs": "choose from: esp8266_4mb or esp32_4mb or esp32s2_4mb or esp8266_1mb or esp8266_1mb_ota or esp8285_1mb or esp8285_1mb_ota", "envs": [ - "esp8266_4mb", - "esp32_4mb", - "esp8266_1mb", - "esp8266_1mb_ota", - "esp8285_1mb", - "esp8285_1mb_ota", - "esp32s2_4mb" + { + "name": "esp8266_4mb", + "firmware": "0x00000", + "littlefs": "0x300000" + }, + { + "name": "esp8266_16mb", + "firmware": "0x00000", + "littlefs": "0x200000" + }, + { + "name": "esp32_4mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x290000" + }, + { + "name": "esp32_16mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x910000" + }, + { + "name": "esp8266_1mb", + "firmware": "0x00000000", + "littlefs": "0x000bb000" + }, + { + "name": "esp8266_1mb_ota", + "firmware": "0x00000000", + "littlefs": "0x000eb000" + }, + { + "name": "esp8266_2mb", + "firmware": "0x00000000", + "littlefs": "0x00100000" + }, + { + "name": "esp8266_2mb_ota", + "firmware": "0x00000000", + "littlefs": "0x001c0000" + }, + { + "name": "esp8285_1mb", + "firmware": "0x00000000", + "littlefs": "0x000bb000" + }, + { + "name": "esp8285_1mb_ota", + "firmware": "0x00000000", + "littlefs": "0x000eb000" + }, + { + "name": "esp32s2_4mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x290000" + } ] } }, @@ -126,11 +183,11 @@ "active": false }, { - "path": "src/modules/sensors/Ds2423", + "path": "src/modules/sensors/Emon", "active": false }, { - "path": "src/modules/sensors/Emon", + "path": "src/modules/sensors/ExampleModule", "active": false }, { @@ -165,6 +222,10 @@ "path": "src/modules/sensors/Ina219", "active": false }, + { + "path": "src/modules/sensors/Ina226", + "active": false + }, { "path": "src/modules/sensors/IoTWiegand", "active": false @@ -314,6 +375,10 @@ { "path": "src/modules/exec/Thermostat", "active": false + }, + { + "path": "src/modules/sensors/Ds2423", + "active": false } ], "screens": [ @@ -329,10 +394,18 @@ "path": "src/modules/display/NextionUpload", "active": false }, + { + "path": "src/modules/display/Oled128", + "active": false + }, { "path": "src/modules/display/Smi2_m", "active": true }, + { + "path": "src/modules/display/TM16XX", + "active": true + }, { "path": "src/modules/display/Ws2812b", "active": false diff --git a/platformio.ini b/platformio.ini index de3940b4..72fb7ea9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -157,6 +157,28 @@ build_src_filter = + ${env:esp8266_4mb_fromitems.build_src_filter} +[env:esp8266_16mb] +extra_scripts = pre:tools/patch8266_16m.py +lib_deps = + ${common_env_data.lib_deps_external} + ${env:esp8266_16mb_fromitems.lib_deps} + ESPAsyncUDP +build_flags = -Desp8266_16mb="esp8266_16mb" +framework = arduino +board = nodemcuv2 +platform = espressif8266 @4.0.1 +board_build.ldscript = eagle.flash.16m14m.ld +monitor_filters = esp8266_exception_decoder +upload_speed = 921600 +monitor_speed = 115200 +board_build.filesystem = littlefs +build_src_filter = + +<*.cpp> + + + + + + + ${env:esp8266_16mb_fromitems.build_src_filter} + [env:esp32_4mb] lib_deps = ${common_env_data.lib_deps_external} @@ -200,6 +222,29 @@ build_src_filter = + ${env:esp32s2_4mb_fromitems.build_src_filter} +[env:esp32_16mb] +lib_deps = + ${common_env_data.lib_deps_external} + ${env:esp32_16mb_fromitems.lib_deps} +build_flags = -Desp32_16mb="esp32_16mb" +framework = arduino +board = esp32dev +platform = espressif32 @5.1.1 +monitor_filters = esp32_exception_decoder +upload_port = COM11 +upload_speed = 921600 +monitor_speed = 115200 +debug_tool = esp-prog +board_build.partitions = tools/large_spiffs_16MB.csv +board_upload.flash_size = 16MB +board_build.filesystem = littlefs +build_src_filter = + +<*.cpp> + + + + + + + ${env:esp32_16mb_fromitems.build_src_filter} + [env:esp8266_1mb_ota_fromitems] lib_deps = adafruit/Adafruit BME280 Library @@ -412,6 +457,9 @@ lib_deps = adafruit/Adafruit BusIO @ ^1.13.2 https://github.com/robotclass/RobotClass_LiquidCrystal_I2C marcoschwartz/LiquidCrystal_I2C@^1.1.4 + https://github.com/maxint-rd/TM16xx + adafruit/Adafruit GFX Library @ ^1.11.5 + adafruit/Adafruit BusIO @ ^1.13.2 build_src_filter = + + @@ -448,6 +496,7 @@ build_src_filter = + + + + + [env:esp32_4mb_fromitems] lib_deps = @@ -461,13 +510,15 @@ lib_deps = WEMOS SHT3x@1.0.0 plerup/EspSoftwareSerial gyverlibs/EncButton @ ^2.0 - https://github.com/RoboticsBrno/ServoESP32 + https://github.com/RoboticsBrno/ServoESP32#v1.0.3 adafruit/Adafruit MCP23017 Arduino Library@^2.1.0 adafruit/Adafruit BusIO @ ^1.13.2 dfrobot/DFRobotDFPlayerMini @ ^1.0.5 adafruit/Adafruit BusIO @ ^1.13.2 https://github.com/robotclass/RobotClass_LiquidCrystal_I2C marcoschwartz/LiquidCrystal_I2C@^1.1.4 + https://github.com/maxint-rd/TM16xx + adafruit/Adafruit GFX Library @ ^1.11.5 build_src_filter = + + @@ -504,7 +555,7 @@ build_src_filter = + + + - + + [env:esp32s2_4mb_fromitems] lib_deps = @@ -521,3 +572,31 @@ build_src_filter = + + +[env:esp8266_16mb_fromitems] +lib_deps = + gyverlibs/EncButton @ ^2.0 +build_src_filter = + + + + + + + + + + + + + + + + + + + + + + + +[env:esp32_16mb_fromitems] +lib_deps = +build_src_filter = + + + + + + + + + + + + + + + + + diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index 4324e7c1..cfc5e8c2 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -95,6 +95,10 @@ void mqttReconnect() { mqttConnect(); } +bool mqttIsConnect(){ + return mqtt.connected(); +} + void getMqttData() { mqttServer = jsonReadStr(settingsFlashJson, F("mqttServer")); mqttPort = jsonReadInt(settingsFlashJson, F("mqttPort")); @@ -116,6 +120,16 @@ void mqttSubscribe() { } } +void mqttSubscribeExternal(String topic, bool usePrefix) { + SerialPrint("i", F("MQTT"), ("subscribed external" + topic).c_str()); + // SerialPrint("i", F("MQTT"), mqttRootDevice); + if (usePrefix) + { + mqtt.subscribe((mqttPrefix + topic).c_str()); + } + mqtt.subscribe(topic.c_str()); +} + void mqttCallback(char* topic, uint8_t* payload, size_t length) { String topicStr = String(topic); // SerialPrint("i", "=>MQTT", topicStr); diff --git a/src/PeriodicTasks.cpp b/src/PeriodicTasks.cpp index 9516a369..05ff1a20 100644 --- a/src/PeriodicTasks.cpp +++ b/src/PeriodicTasks.cpp @@ -101,7 +101,7 @@ String ESP32GetResetReason(uint32_t cpu_no) { } } #endif -#ifdef esp32_4mb +#if defined(esp32_4mb) || defined(esp32_16mb) String ESP_getResetReason(void) { return ESP32GetResetReason(0); // CPU 0 } diff --git a/src/StandWebServer.cpp b/src/StandWebServer.cpp index 5f899613..6a23378f 100644 --- a/src/StandWebServer.cpp +++ b/src/StandWebServer.cpp @@ -7,24 +7,22 @@ String unsupportedFiles = String(); static const char TEXT_PLAIN[] PROGMEM = "text/plain"; static const char FS_INIT_ERROR[] PROGMEM = "FS INIT ERROR"; static const char FILE_NOT_FOUND[] PROGMEM = "FileNotFound"; -//static bool fsOK; -//const char* fsName = "LittleFS"; +// static bool fsOK; +// const char* fsName = "LittleFS"; -void standWebServerInit() -{ +void standWebServerInit() { // Кэшировать файлы для быстрой работы - HTTP.serveStatic("/bundle.js", FileFS, "/", "max-age=31536000"); // кеширование на 1 год - HTTP.serveStatic("/bundle.css", FileFS, "/", "max-age=31536000"); // кеширование на 1 год - HTTP.serveStatic("/bundle.js.gz", FileFS, "/", "max-age=31536000"); // кеширование на 1 год - HTTP.serveStatic("/bundle.css.gz", FileFS, "/", "max-age=31536000"); // кеширование на 1 год - HTTP.serveStatic("/favicon.png", FileFS, "/", "max-age=31536000"); // кеширование на 1 год + // если указана директория то все файлы будут отмечены как Directory Request Handler + // если указан файл то он будет отмечен как File Request Handler + HTTP.serveStatic("/build", FileFS, "/build", "max-age=31536000"); // кеширование на 1 год + HTTP.serveStatic("/favicon.ico", FileFS, "/favicon.ico", "max-age=31536000"); // кеширование на 1 год // HTTP.on("/devicelist.json", HTTP_GET, []() { // HTTP.send(200, "application/json", devListHeapJson); // }); - HTTP.on("/settings.h.json", HTTP_GET, []() { - HTTP.send(200, "application/json", settingsFlashJson); - }); + // HTTP.on("/settings.h.json", HTTP_GET, []() { + // HTTP.send(200, "application/json", settingsFlashJson); + //}); // HTTP.on("/settings.f.json", HTTP_GET, []() { // HTTP.send(200, "application/json", readFile(F("settings.json"), 20000)); // }); @@ -46,21 +44,19 @@ void standWebServerInit() // HTTP.send(200, "text/plain", "ok"); // }); - HTTP.on("/set", HTTP_GET, []() { if (HTTP.hasArg(F("routerssid")) && WiFi.getMode() == WIFI_AP) { - jsonWriteStr(settingsFlashJson, F("routerssid"), HTTP.arg(F("routerssid"))); - syncSettingsFlashJson(); - HTTP.send(200, "text/plain", "ok"); - } + jsonWriteStr(settingsFlashJson, F("routerssid"), HTTP.arg(F("routerssid"))); + syncSettingsFlashJson(); + HTTP.send(200, "text/plain", "ok"); + } if (HTTP.hasArg(F("routerpass")) && WiFi.getMode() == WIFI_AP) { - jsonWriteStr(settingsFlashJson, F("routerpass"), HTTP.arg(F("routerpass"))); - syncSettingsFlashJson(); - HTTP.send(200, "text/plain", "ok"); - } - - }); + jsonWriteStr(settingsFlashJson, F("routerpass"), HTTP.arg(F("routerpass"))); + syncSettingsFlashJson(); + HTTP.send(200, "text/plain", "ok"); + } + }); // Добавляем функцию Update для перезаписи прошивки по WiFi при 1М(256K FileFS) и выше // httpUpdater.setup(&HTTP); @@ -101,39 +97,33 @@ void standWebServerInit() //////////////////////////////// // Utils to return HTTP codes, and determine content-type -void replyOK() -{ +void replyOK() { HTTP.send(200, FPSTR(TEXT_PLAIN), ""); } -void replyOKWithMsg(String msg) -{ +void replyOKWithMsg(String msg) { HTTP.send(200, FPSTR(TEXT_PLAIN), msg); } -void replyNotFound(String msg) -{ +void replyNotFound(String msg) { HTTP.send(404, FPSTR(TEXT_PLAIN), msg); } -void replyBadRequest(String msg) -{ -// DBG_OUTPUT_PORT.println(msg); +void replyBadRequest(String msg) { + // DBG_OUTPUT_PORT.println(msg); HTTP.send(400, FPSTR(TEXT_PLAIN), msg + "\r\n"); } -void replyServerError(String msg) -{ -// DBG_OUTPUT_PORT.println(msg); +void replyServerError(String msg) { + // DBG_OUTPUT_PORT.println(msg); HTTP.send(500, FPSTR(TEXT_PLAIN), msg + "\r\n"); } /* Return the FS type, status and size info */ -void handleStatus() -{ -// DBG_OUTPUT_PORT.println("handleStatus"); +void handleStatus() { + // DBG_OUTPUT_PORT.println("handleStatus"); String json; json.reserve(128); @@ -141,22 +131,22 @@ void handleStatus() json += FS_NAME; json += "\", \"isOk\":"; - #ifdef ESP8266 +#ifdef ESP8266 FSInfo fs_info; - FileFS.info(fs_info); - json += F("\"true\", \"totalBytes\":\""); - json += fs_info.totalBytes; - json += F("\", \"usedBytes\":\""); - json += fs_info.usedBytes; - json += "\""; -#endif + FileFS.info(fs_info); + json += F("\"true\", \"totalBytes\":\""); + json += fs_info.totalBytes; + json += F("\", \"usedBytes\":\""); + json += fs_info.usedBytes; + json += "\""; +#endif #ifdef ESP32 - json += F("\"true\", \"totalBytes\":\""); - json += String(FileFS.totalBytes()); - json += F("\", \"usedBytes\":\""); - json += String(FileFS.usedBytes()); - json += "\""; + json += F("\"true\", \"totalBytes\":\""); + json += String(FileFS.totalBytes()); + json += F("\", \"usedBytes\":\""); + json += String(FileFS.usedBytes()); + json += "\""; #endif json += F(",\"unsupportedFiles\":\""); @@ -168,74 +158,66 @@ void handleStatus() #ifdef ESP32 String getContentType(String filename) { - if (HTTP.hasArg("download")) { - return "application/octet-stream"; - } else if (filename.endsWith(".htm")) { - return "text/html"; - } else if (filename.endsWith(".html")) { - return "text/html"; - } else if (filename.endsWith(".css")) { - return "text/css"; - } else if (filename.endsWith(".js")) { - return "application/javascript"; - } else if (filename.endsWith(".png")) { - return "image/png"; - } else if (filename.endsWith(".gif")) { - return "image/gif"; - } else if (filename.endsWith(".jpg")) { - return "image/jpeg"; - } else if (filename.endsWith(".ico")) { - return "image/x-icon"; - } else if (filename.endsWith(".xml")) { - return "text/xml"; - } else if (filename.endsWith(".pdf")) { - return "application/x-pdf"; - } else if (filename.endsWith(".zip")) { - return "application/x-zip"; - } else if (filename.endsWith(".gz")) { - return "application/x-gzip"; - } - return "text/plain"; + if (HTTP.hasArg("download")) { + return "application/octet-stream"; + } else if (filename.endsWith(".htm")) { + return "text/html"; + } else if (filename.endsWith(".html")) { + return "text/html"; + } else if (filename.endsWith(".css")) { + return "text/css"; + } else if (filename.endsWith(".js")) { + return "application/javascript"; + } else if (filename.endsWith(".png")) { + return "image/png"; + } else if (filename.endsWith(".gif")) { + return "image/gif"; + } else if (filename.endsWith(".jpg")) { + return "image/jpeg"; + } else if (filename.endsWith(".ico")) { + return "image/x-icon"; + } else if (filename.endsWith(".xml")) { + return "text/xml"; + } else if (filename.endsWith(".pdf")) { + return "application/x-pdf"; + } else if (filename.endsWith(".zip")) { + return "application/x-zip"; + } else if (filename.endsWith(".gz")) { + return "application/x-gzip"; + } + return "text/plain"; } #endif /* Read the given file from the filesystem and stream it back to the client */ -bool handleFileRead(String path) -{ -// DBG_OUTPUT_PORT.println(String("handleFileRead: ") + path); - if (path.endsWith("/")) - { +bool handleFileRead(String path) { + // DBG_OUTPUT_PORT.println(String("handleFileRead: ") + path); + if (path.endsWith("/")) { path += "index.html"; } String contentType; - if (HTTP.hasArg("download")) - { + if (HTTP.hasArg("download")) { contentType = F("application/octet-stream"); - } - else - { -#ifdef ESP32 + } else { +#ifdef ESP32 contentType = getContentType(path); #endif #ifdef ESP8266 contentType = mime::getContentType(path); -#endif +#endif } - if (!FileFS.exists(path)) - { + if (!FileFS.exists(path)) { // File not found, try gzip version path = path + ".gz"; } - if (FileFS.exists(path)) - { + if (FileFS.exists(path)) { File file = FileFS.open(path, "r"); - if (HTTP.streamFile(file, contentType) != file.size()) - { - // DBG_OUTPUT_PORT.println("Sent less data than expected!"); + if (HTTP.streamFile(file, contentType) != file.size()) { + // DBG_OUTPUT_PORT.println("Sent less data than expected!"); } file.close(); return true; @@ -248,90 +230,69 @@ bool handleFileRead(String path) As some FS (e.g. LittleFS) delete the parent folder when the last child has been removed, return the path of the closest parent still existing */ -String lastExistingParent(String path) -{ - while (!path.isEmpty() && !FileFS.exists(path)) - { - if (path.lastIndexOf('/') > 0) - { +String lastExistingParent(String path) { + while (!path.isEmpty() && !FileFS.exists(path)) { + if (path.lastIndexOf('/') > 0) { path = path.substring(0, path.lastIndexOf('/')); - } - else - { - path = String(); // No slash => the top folder does not exist + } else { + path = String(); // No slash => the top folder does not exist } } -// DBG_OUTPUT_PORT.println(String("Last existing parent: ") + path); + // DBG_OUTPUT_PORT.println(String("Last existing parent: ") + path); return path; } /* Handle a file upload request */ -void handleFileUpload() -{ - if (HTTP.uri() != "/edit") - { +void handleFileUpload() { + if (HTTP.uri() != "/edit") { return; } HTTPUpload &upload = HTTP.upload(); - if (upload.status == UPLOAD_FILE_START) - { + if (upload.status == UPLOAD_FILE_START) { String filename = upload.filename; // Make sure paths always start with "/" - if (!filename.startsWith("/")) - { + if (!filename.startsWith("/")) { filename = "/" + filename; } -// DBG_OUTPUT_PORT.println(String("handleFileUpload Name: ") + filename); + // DBG_OUTPUT_PORT.println(String("handleFileUpload Name: ") + filename); uploadFile = FileFS.open(filename, "w"); - if (!uploadFile) - { + if (!uploadFile) { return replyServerError(F("CREATE FAILED")); } -// DBG_OUTPUT_PORT.println(String("Upload: START, filename: ") + filename); - } - else if (upload.status == UPLOAD_FILE_WRITE) - { - if (uploadFile) - { + // DBG_OUTPUT_PORT.println(String("Upload: START, filename: ") + filename); + } else if (upload.status == UPLOAD_FILE_WRITE) { + if (uploadFile) { size_t bytesWritten = uploadFile.write(upload.buf, upload.currentSize); - if (bytesWritten != upload.currentSize) - { + if (bytesWritten != upload.currentSize) { return replyServerError(F("WRITE FAILED")); } } -// DBG_OUTPUT_PORT.println(String("Upload: WRITE, Bytes: ") + upload.currentSize); - } - else if (upload.status == UPLOAD_FILE_END) - { - if (uploadFile) - { + // DBG_OUTPUT_PORT.println(String("Upload: WRITE, Bytes: ") + upload.currentSize); + } else if (upload.status == UPLOAD_FILE_END) { + if (uploadFile) { uploadFile.close(); } -// DBG_OUTPUT_PORT.println(String("Upload: END, Size: ") + upload.totalSize); + // DBG_OUTPUT_PORT.println(String("Upload: END, Size: ") + upload.totalSize); } } - #ifdef ESP8266 -void deleteRecursive(String path) -{ +void deleteRecursive(String path) { File file = FileFS.open(path, "r"); bool isDir = file.isDirectory(); file.close(); // If it's a plain file, delete it - if (!isDir) - { + if (!isDir) { FileFS.remove(path); return; } Dir dir = FileFS.openDir(path); - while (dir.next()) - { + while (dir.next()) { deleteRecursive(path + '/' + dir.fileName()); - } + } // Then delete the folder itself FileFS.rmdir(path); @@ -339,41 +300,37 @@ void deleteRecursive(String path) #endif #ifdef ESP32 -struct treename{ - uint8_t type; - char *name; +struct treename { + uint8_t type; + char *name; }; +void deleteRecursive(String path) { + fs::File dir = FileFS.open(path); -void deleteRecursive( String path ){ - fs::File dir = FileFS.open( path ); - - if(!dir.isDirectory()){ - Serial.printf("%s is a file\n", path); - dir.close(); - Serial.printf( "result of removing file %s: %d\n", path, FileFS.remove( path ) ); - return; + if (!dir.isDirectory()) { + Serial.printf("%s is a file\n", path); + dir.close(); + Serial.printf("result of removing file %s: %d\n", path, FileFS.remove(path)); + return; } - + Serial.printf("%s is a directory\n", path); - + fs::File entry, nextentry; - - while ( entry = dir.openNextFile() ){ - -if ( entry.isDirectory() ){ - deleteRecursive( entry.path() ); - } else{ - String tmpname = path+"/"+strdup( entry.name() ); // buffer file name - entry.close(); - Serial.printf( "result of removing file %s: %d\n", tmpname, FileFS.remove( tmpname ) ); - } - + + while (entry = dir.openNextFile()) { + if (entry.isDirectory()) { + deleteRecursive(entry.path()); + } else { + String tmpname = path + "/" + strdup(entry.name()); // buffer file name + entry.close(); + Serial.printf("result of removing file %s: %d\n", tmpname, FileFS.remove(tmpname)); + } } - dir.close(); - Serial.printf( "result of removing directory %s: %d\n", path, FileFS.rmdir( path ) ); - + dir.close(); + Serial.printf("result of removing directory %s: %d\n", path, FileFS.rmdir(path)); } #endif /* @@ -383,23 +340,18 @@ if ( entry.isDirectory() ){ Delete file | parent of deleted file, or remaining ancestor Delete folder | parent of deleted folder, or remaining ancestor */ -void handleFileDelete() -{ +void handleFileDelete() { String path = HTTP.arg(0); - if (path.isEmpty() || path == "/") - { + if (path.isEmpty() || path == "/") { return replyBadRequest("BAD PATH"); } -// DBG_OUTPUT_PORT.println(String("handleFileDelete: ") + path); - if (!FileFS.exists(path)) - { + // DBG_OUTPUT_PORT.println(String("handleFileDelete: ") + path); + if (!FileFS.exists(path)) { return replyNotFound(FPSTR(FILE_NOT_FOUND)); } deleteRecursive(path); - - replyOKWithMsg(lastExistingParent(path)); } @@ -414,93 +366,72 @@ void handleFileDelete() Rename folder | parent of source folder Move folder | parent of source folder, or remaining ancestor */ -void handleFileCreate() -{ +void handleFileCreate() { String path = HTTP.arg("path"); - if (path.isEmpty()) - { + if (path.isEmpty()) { return replyBadRequest(F("PATH ARG MISSING")); } #ifdef USE_SPIFFS - if (checkForUnsupportedPath(path).length() > 0) - { + if (checkForUnsupportedPath(path).length() > 0) { return replyServerError(F("INVALID FILENAME")); } #endif - if (path == "/") - { + if (path == "/") { return replyBadRequest("BAD PATH"); } - if (FileFS.exists(path)) - { + if (FileFS.exists(path)) { return replyBadRequest(F("PATH FILE EXISTS")); } String src = HTTP.arg("src"); - if (src.isEmpty()) - { + if (src.isEmpty()) { // No source specified: creation -// DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path); - if (path.endsWith("/")) - { + // DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path); + if (path.endsWith("/")) { // Create a folder path.remove(path.length() - 1); - if (!FileFS.mkdir(path)) - { + if (!FileFS.mkdir(path)) { return replyServerError(F("MKDIR FAILED")); } - } - else - { + } else { // Create a file File file = FileFS.open(path, "w"); - if (file) - { -#ifdef ESP8266 + if (file) { +#ifdef ESP8266 file.write((const char *)0); #endif #ifdef ESP32 file.write(0); -#endif +#endif file.close(); - } - else - { + } else { return replyServerError(F("CREATE FAILED")); } } - if (path.lastIndexOf('/') > -1) - { + if (path.lastIndexOf('/') > -1) { path = path.substring(0, path.lastIndexOf('/')); } replyOKWithMsg(path); - } - else - { + } else { // Source specified: rename - if (src == "/") - { + if (src == "/") { return replyBadRequest("BAD SRC"); } - if (!FileFS.exists(src)) - { + if (!FileFS.exists(src)) { return replyBadRequest(F("SRC FILE NOT FOUND")); } -// DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path + " from " + src); + // DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path + " from " + src); - if (path.endsWith("/")) - { + if (path.endsWith("/")) { path.remove(path.length() - 1); } - if (src.endsWith("/")) - { + if (src.endsWith("/")) { src.remove(src.length() - 1); } - if (!FileFS.rename(src, path)) - { + if (!FileFS.rename(src, path)) { return replyServerError(F("RENAME FAILED")); } replyOKWithMsg(lastExistingParent(src)); @@ -512,26 +443,22 @@ void handleFileCreate() Also demonstrates the use of chunked responses. */ #ifdef ESP8266 -void handleFileList() -{ - if (!HTTP.hasArg("dir")) - { +void handleFileList() { + if (!HTTP.hasArg("dir")) { return replyBadRequest(F("DIR ARG MISSING")); } String path = HTTP.arg("dir"); - if (path != "/" && !FileFS.exists(path)) - { + if (path != "/" && !FileFS.exists(path)) { return replyBadRequest("BAD PATH"); } -// DBG_OUTPUT_PORT.println(String("handleFileList: ") + path); + // DBG_OUTPUT_PORT.println(String("handleFileList: ") + path); Dir dir = FileFS.openDir(path); path.clear(); // use HTTP/1.1 Chunked response to avoid building a huge temporary string - if (!HTTP.chunkedResponseModeStart(200, "text/json")) - { + if (!HTTP.chunkedResponseModeStart(200, "text/json")) { HTTP.send(505, F("text/html"), F("HTTP1.1 required")); return; } @@ -539,47 +466,36 @@ void handleFileList() // use the same string for every line String output; output.reserve(64); - while (dir.next()) - { + while (dir.next()) { #ifdef USE_SPIFFS String error = checkForUnsupportedPath(dir.fileName()); - if (error.length() > 0) - { -// DBG_OUTPUT_PORT.println(String("Ignoring ") + error + dir.fileName()); + if (error.length() > 0) { + // DBG_OUTPUT_PORT.println(String("Ignoring ") + error + dir.fileName()); continue; } #endif - if (output.length()) - { + if (output.length()) { // send string from previous iteration // as an HTTP chunk HTTP.sendContent(output); output = ','; - } - else - { + } else { output = '['; } output += "{\"type\":\""; - if (dir.isDirectory()) - { + if (dir.isDirectory()) { output += "dir"; - } - else - { + } else { output += F("file\",\"size\":\""); output += dir.fileSize(); } output += F("\",\"name\":\""); // Always return names without leading "/" - if (dir.fileName()[0] == '/') - { + if (dir.fileName()[0] == '/') { output += &(dir.fileName()[1]); - } - else - { + } else { output += dir.fileName(); } @@ -595,65 +511,57 @@ void handleFileList() #ifdef ESP32 void handleFileList() { - if (!HTTP.hasArg("dir")) { - HTTP.send(500, "text/plain", "BAD ARGS"); - return; - } + if (!HTTP.hasArg("dir")) { + HTTP.send(500, "text/plain", "BAD ARGS"); + return; + } - String path = HTTP.arg("dir"); -// DBG_OUTPUT_PORT.println("handleFileList: " + path); + String path = HTTP.arg("dir"); + // DBG_OUTPUT_PORT.println("handleFileList: " + path); + File root = FileFS.open(path); + path = String(); - File root = FileFS.open(path); - path = String(); + String output = "["; + if (root.isDirectory()) { + File file = root.openNextFile(); + while (file) { + if (output != "[") { + output += ','; + } + output += "{\"type\":\""; + // output += (file.isDirectory()) ? "dir" : "file"; + if (file.isDirectory()) { + output += "dir"; + } else { + output += F("file\",\"size\":\""); + output += file.size(); + } - String output = "["; - if(root.isDirectory()){ - File file = root.openNextFile(); - while(file){ - if (output != "[") { - output += ','; - } - output += "{\"type\":\""; - // output += (file.isDirectory()) ? "dir" : "file"; - if (file.isDirectory()) - { - output += "dir"; - } - else - { - output += F("file\",\"size\":\""); - output += file.size(); - } - - output += "\",\"name\":\""; + output += "\",\"name\":\""; output += String(file.name()); - output += "\"}"; - file = root.openNextFile(); - } - } - output += "]"; - HTTP.send(200, "text/json", output); - + output += "\"}"; + file = root.openNextFile(); + } + } + output += "]"; + HTTP.send(200, "text/json", output); } #endif - /* The "Not Found" handler catches all URI not explicitly declared in code First try to find and return the requested file from the filesystem, and if it fails, return a 404 page with debug information */ -void handleNotFound() -{ +void handleNotFound() { #ifdef ESP8266 - String uri = ESP8266WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks + String uri = ESP8266WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks #endif #ifdef ESP32 - String uri = WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks + String uri = WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks #endif - if (handleFileRead(uri)) - { + if (handleFileRead(uri)) { return; } @@ -667,8 +575,7 @@ void handleNotFound() message += F("\nArguments: "); message += HTTP.args(); message += '\n'; - for (uint8_t i = 0; i < HTTP.args(); i++) - { + for (uint8_t i = 0; i < HTTP.args(); i++) { message += F(" NAME:"); message += HTTP.argName(i); message += F("\n VALUE:"); @@ -678,7 +585,7 @@ void handleNotFound() message += "path="; message += HTTP.arg("path"); message += '\n'; -// DBG_OUTPUT_PORT.print(message); + // DBG_OUTPUT_PORT.print(message); return replyNotFound(message); } @@ -689,10 +596,8 @@ void handleNotFound() embedded in the program code. Otherwise, fails with a 404 page with debug information */ -void handleGetEdit() -{ - if (handleFileRead(F("/edit.htm"))) - { +void handleGetEdit() { + if (handleFileRead(F("/edit.htm"))) { return; } diff --git a/src/UpgradeFirm.cpp b/src/UpgradeFirm.cpp index ac0ad9a7..86b119aa 100644 --- a/src/UpgradeFirm.cpp +++ b/src/UpgradeFirm.cpp @@ -74,7 +74,7 @@ bool upgradeBuild() { handleUpdateStatus(true, PATH_ERROR); return ret; } -#if defined(esp8266_4mb) || defined(esp8266_1mb) || defined(esp8266_1mb_ota) || defined(esp8266_2mb) || defined(esp8266_2mb_ota) +#if defined(esp8266_4mb) || defined(esp8266_16mb) || defined(esp8266_1mb) || defined(esp8266_1mb_ota) || defined(esp8266_2mb) || defined(esp8266_2mb_ota) ESPhttpUpdate.rebootOnUpdate(false); t_httpUpdate_return retBuild = ESPhttpUpdate.update(wifiClient, getBinPath("firmware.bin")); #endif diff --git a/src/WsServer.cpp b/src/WsServer.cpp index c8886ab6..b8e07c13 100644 --- a/src/WsServer.cpp +++ b/src/WsServer.cpp @@ -4,441 +4,482 @@ extern IoTScenario iotScen; #ifdef STANDARD_WEB_SOCKETS void standWebSocketsInit() { - standWebSocket.begin(); - standWebSocket.onEvent(webSocketEvent); - SerialPrint("i", "WS", "WS server initialized"); + standWebSocket.begin(); + standWebSocket.onEvent(webSocketEvent); + SerialPrint("i", "WS", "WS server initialized"); } -void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { - switch (type) { - case WStype_ERROR: { - Serial.printf("[%u] Error!\n", num); - } break; +void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, + size_t length) { + switch (type) { + case WStype_ERROR: { + Serial.printf("[%u] Error!\n", num); + } break; - case WStype_DISCONNECTED: { - Serial.printf("[%u] Disconnected!\n", num); - } break; + case WStype_DISCONNECTED: { + Serial.printf("[%u] Disconnected!\n", num); + } break; - case WStype_CONNECTED: { - // IPAddress ip = standWebSocket.remoteIP(num); - SerialPrint("i", "WS " + String(num), "WS client connected"); - if (num >= 3) { - SerialPrint("E", "WS", "Too many clients, connection closed!!!"); - jsonWriteInt(errorsHeapJson, "wse1", 1); - standWebSocket.close(); - standWebSocketsInit(); + case WStype_CONNECTED: { + // IPAddress ip = standWebSocket.remoteIP(num); + SerialPrint("i", "WS " + String(num), "WS client connected"); + if (num >= 3) { + SerialPrint("E", "WS", "Too many clients, connection closed!!!"); + jsonWriteInt(errorsHeapJson, "wse1", 1); + standWebSocket.close(); + standWebSocketsInit(); + } + // Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], + // ip[1], ip[2], ip[3], payload); standWebSocket.sendTXT(num, + // "Connected"); + } break; + + case WStype_TEXT: { + bool endOfHeaderFound = false; + size_t maxAllowedHeaderSize = + 15; // максимальное количество символов заголовка + size_t headerLenth = 0; + String headerStr; + for (size_t i = 0; i <= maxAllowedHeaderSize; i++) { + headerLenth++; + char s = (char)payload[i]; + headerStr += s; + if (s == '|') { + endOfHeaderFound = true; + break; + } + } + if (!endOfHeaderFound) { + SerialPrint("E", "WS " + String(num), "Package without header"); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса dashboard + //----------------------------------------------------------------------// + + // публикация всех виджетов + if (headerStr == "/|") { + sendFileToWsByFrames("/layout.json", "layout", "", num, + WEB_SOCKETS_FRAME_SIZE); + } + + if (headerStr == "/params|") { + // публикация всех статус сообщений при подключении svelte приложения + String params = "{}"; + for (std::list::iterator it = IoTItems.begin(); + it != IoTItems.end(); ++it) { + if ((*it)->getSubtype() != "Loging") { + if ((*it)->getSubtype() != "LogingDaily") { + if ((*it)->iAmLocal) + jsonWriteStr(params, (*it)->getID(), (*it)->getValue()); } - // Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); - // standWebSocket.sendTXT(num, "Connected"); - } break; + } + } + sendStringToWs("params", params, num); - case WStype_TEXT: { - bool endOfHeaderFound = false; - size_t maxAllowedHeaderSize = 15; // максимальное количество символов заголовка - size_t headerLenth = 0; - String headerStr; - for (size_t i = 0; i <= maxAllowedHeaderSize; i++) { - headerLenth++; - char s = (char)payload[i]; - headerStr += s; - if (s == '|') { - endOfHeaderFound = true; - break; - } - } - if (!endOfHeaderFound) { - SerialPrint("E", "WS " + String(num), "Package without header"); - } + // генерация события подключения в модулях + for (std::list::iterator it = IoTItems.begin(); + it != IoTItems.end(); ++it) { + if ((*it)->iAmLocal) (*it)->onMqttWsAppConnectEvent(); + } + } - //----------------------------------------------------------------------// - // Страница веб интерфейса dashboard - //----------------------------------------------------------------------// + // отвечаем на запрос графиков + if (headerStr == "/charts|") { + // обращение к логированию из ядра + // отправка данных графиков только в выбранный сокет + for (std::list::iterator it = IoTItems.begin(); + it != IoTItems.end(); ++it) { + // сбрасываем даты графиков + // if ((*it)->getID().endsWith("-date")) { + // (*it)->setTodayDate(); + // } + if ((*it)->getSubtype() == "Loging" || "LogingDaily") { + (*it)->setPublishDestination(TO_WS, num); + (*it)->publishValue(); + } + } + } - // публикация всех виджетов - if (headerStr == "/|") { - sendFileToWsByFrames("/layout.json", "layout", "", num, WEB_SOCKETS_FRAME_SIZE); - } + //----------------------------------------------------------------------// + // Страница веб интерфейса configutation + //----------------------------------------------------------------------// - if (headerStr == "/params|") { - // публикация всех статус сообщений при подключении svelte приложения - String params = "{}"; - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->getSubtype() != "Loging") { - if ((*it)->getSubtype() != "LogingDaily") { - if ((*it)->iAmLocal) jsonWriteStr(params, (*it)->getID(), (*it)->getValue()); - } - } - } - sendStringToWs("params", params, num); + // отвечаем данными на запрос страницы + if (headerStr == "/config|") { + sendFileToWsByFrames("/items.json", "itemsj", "", num, + WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/widgets.json", "widget", "", num, + WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/config.json", "config", "", num, + WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/scenario.txt", "scenar", "", num, + WEB_SOCKETS_FRAME_SIZE); + sendStringToWs("settin", settingsFlashJson, num); + } - // генерация события подключения в модулях - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->iAmLocal) (*it)->onMqttWsAppConnectEvent(); - } - } + // обработка кнопки сохранить + if (headerStr == "/gifnoc|") { + writeFileUint8tByFrames("config.json", payload, length, headerLenth, + 256); + } + if (headerStr == "/tuoyal|") { + writeFileUint8tByFrames("layout.json", payload, length, headerLenth, + 256); + } + if (headerStr == "/oiranecs|") { + writeFileUint8tByFrames("scenario.txt", payload, length, headerLenth, + 256); + clearConfigure(); + configure("/config.json"); + iotScen.loadScenario("/scenario.txt"); + // создаем событие завершения конфигурирования для возможности + // выполнения блока кода при загрузке + createItemFromNet("onStart", "1", 1); + } - // отвечаем на запрос графиков - if (headerStr == "/charts|") { - // обращение к логированию из ядра - // отправка данных графиков только в выбранный сокет - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - // сбрасываем даты графиков - // if ((*it)->getID().endsWith("-date")) { - // (*it)->setTodayDate(); - // } - if ((*it)->getSubtype() == "Loging" || "LogingDaily") { - (*it)->setPublishDestination(TO_WS, num); - (*it)->publishValue(); - } - } - } + //----------------------------------------------------------------------// + // Страница веб интерфейса connection + //----------------------------------------------------------------------// - //----------------------------------------------------------------------// - // Страница веб интерфейса configutation - //----------------------------------------------------------------------// + // отвечаем данными на запрос страницы + if (headerStr == "/connection|") { + sendStringToWs("settin", settingsFlashJson, num); + sendStringToWs("ssidli", ssidListHeapJson, num); + sendStringToWs("errors", errorsHeapJson, num); + // запуск асинхронного сканирования wifi сетей при переходе на страницу + // соединений RouterFind(jsonReadStr(settingsFlashJson, + // F("routerssid"))); + } - // отвечаем данными на запрос страницы - if (headerStr == "/config|") { - sendFileToWsByFrames("/items.json", "itemsj", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/widgets.json", "widget", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/config.json", "config", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/scenario.txt", "scenar", "", num, WEB_SOCKETS_FRAME_SIZE); - sendStringToWs("settin", settingsFlashJson, num); - } + // обработка кнопки сохранить settings.json + if (headerStr == "/sgnittes|") { + writeUint8tToString(payload, length, headerLenth, settingsFlashJson); + writeFileUint8tByFrames("settings.json", payload, length, headerLenth, + 256); + sendStringToWs("errors", errorsHeapJson, num); + // если не было создано приема данных по udp - то создадим его + addThisDeviceToList(); + } - // обработка кнопки сохранить - if (headerStr == "/gifnoc|") { - writeFileUint8tByFrames("config.json", payload, length, headerLenth, 256); - } - if (headerStr == "/tuoyal|") { - writeFileUint8tByFrames("layout.json", payload, length, headerLenth, 256); - } - if (headerStr == "/oiranecs|") { - writeFileUint8tByFrames("scenario.txt", payload, length, headerLenth, 256); - clearConfigure(); - configure("/config.json"); - iotScen.loadScenario("/scenario.txt"); - // создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке - createItemFromNet("onStart", "1", 1); - } + // обработка кнопки сохранить настройки mqtt + if (headerStr == "/mqtt|") { + sendStringToWs("settin", settingsFlashJson, + num); // отправляем в ответ новые полученные настройки + handleMqttStatus(false, 8); // меняем статус на неопределенный + mqttReconnect(); // начинаем переподключение + sendStringToWs("errors", errorsHeapJson, + num); // отправляем что статус неопределен + sendStringToWs("ssidli", ssidListHeapJson, num); + } - //----------------------------------------------------------------------// - // Страница веб интерфейса connection - //----------------------------------------------------------------------// + // запуск асинхронного сканирования wifi сетей при нажатии выпадающего + // списка + if (headerStr == "/scan|") { + std::vector jArray; + jsonReadArray(settingsFlashJson, "routerssid", jArray); + RouterFind(jArray); + sendStringToWs("ssidli", ssidListHeapJson, num); + } - // отвечаем данными на запрос страницы - if (headerStr == "/connection|") { - sendStringToWs("settin", settingsFlashJson, num); - sendStringToWs("ssidli", ssidListHeapJson, num); - sendStringToWs("errors", errorsHeapJson, num); - // запуск асинхронного сканирования wifi сетей при переходе на страницу соединений - // RouterFind(jsonReadStr(settingsFlashJson, F("routerssid"))); - } + //----------------------------------------------------------------------// + // Страница веб интерфейса list + //----------------------------------------------------------------------// - // обработка кнопки сохранить settings.json - if (headerStr == "/sgnittes|") { - writeUint8tToString(payload, length, headerLenth, settingsFlashJson); - writeFileUint8tByFrames("settings.json", payload, length, headerLenth, 256); - sendStringToWs("errors", errorsHeapJson, num); - // если не было создано приема данных по udp - то создадим его - addThisDeviceToList(); - } + // отвечаем данными на запрос страницы list + if (headerStr == "/list|") { + sendStringToWs("settin", settingsFlashJson, num); + // отправим список устройств в зависимости от того что выбрал user + // sendDeviceList(num); + } - // обработка кнопки сохранить настройки mqtt - if (headerStr == "/mqtt|") { - sendStringToWs("settin", settingsFlashJson, num); // отправляем в ответ новые полученные настройки - handleMqttStatus(false, 8); // меняем статус на неопределенный - mqttReconnect(); // начинаем переподключение - sendStringToWs("errors", errorsHeapJson, num); // отправляем что статус неопределен - sendStringToWs("ssidli", ssidListHeapJson, num); - } + // отвечаем на запрос списка устройств (это отдельный запрос который + // делает приложение при подключении) + if (headerStr == "/devlist|") { + // отправим список устройств в зависимости от того что выбрал user + sendDeviceList(num); + } - // запуск асинхронного сканирования wifi сетей при нажатии выпадающего списка - if (headerStr == "/scan|") { - RouterFind(jsonReadStr(settingsFlashJson, F("routerssid"))); - sendStringToWs("ssidli", ssidListHeapJson, num); - } + // сохраняем данные листа + if (headerStr == "/tsil|") { + writeFileUint8tByFrames("devlist.json", payload, length, headerLenth, + 256); + } - //----------------------------------------------------------------------// - // Страница веб интерфейса list - //----------------------------------------------------------------------// + //----------------------------------------------------------------------// + // Страница веб интерфейса system + //----------------------------------------------------------------------// - // отвечаем данными на запрос страницы list - if (headerStr == "/list|") { - sendStringToWs("settin", settingsFlashJson, num); - // отправим список устройств в зависимости от того что выбрал user - // sendDeviceList(num); - } + // отвечаем данными на запрос страницы + if (headerStr == "/system|") { + sendStringToWs("errors", errorsHeapJson, num); + sendStringToWs("settin", settingsFlashJson, num); + } - // отвечаем на запрос списка устройств (это отдельный запрос который делает приложение при подключении) - if (headerStr == "/devlist|") { - // отправим список устройств в зависимости от того что выбрал user - sendDeviceList(num); - } + //----------------------------------------------------------------------// + // Страница веб интерфейса dev + //----------------------------------------------------------------------// + if (headerStr == "/dev|") { + sendStringToWs("errors", errorsHeapJson, num); + sendStringToWs("settin", settingsFlashJson, num); + sendFileToWsByFrames("/config.json", "config", "", num, + WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/items.json", "itemsj", "", num, + WEB_SOCKETS_FRAME_SIZE); + // sendFileToWsByFrames("/layout.json", "layout", "", num, + // WEB_SOCKETS_FRAME_SIZE); + } - // сохраняем данные листа - if (headerStr == "/tsil|") { - writeFileUint8tByFrames("devlist.json", payload, length, headerLenth, 256); - } + if (headerStr == "/test|") { + } - //----------------------------------------------------------------------// - // Страница веб интерфейса system - //----------------------------------------------------------------------// + //----------------------------------------------------------------------// + // отдельные команды веб интерфейса + //----------------------------------------------------------------------// - // отвечаем данными на запрос страницы - if (headerStr == "/system|") { - sendStringToWs("errors", errorsHeapJson, num); - sendStringToWs("settin", settingsFlashJson, num); - } + // переписать любое поле в errors json + if (headerStr == "/rorre|") { + writeUint8tValueToJsonString(payload, length, headerLenth, + errorsHeapJson); + } - //----------------------------------------------------------------------// - // Страница веб интерфейса dev - //----------------------------------------------------------------------// - if (headerStr == "/dev|") { - sendStringToWs("errors", errorsHeapJson, num); - sendStringToWs("settin", settingsFlashJson, num); - sendFileToWsByFrames("/config.json", "config", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/items.json", "itemsj", "", num, WEB_SOCKETS_FRAME_SIZE); - // sendFileToWsByFrames("/layout.json", "layout", "", num, WEB_SOCKETS_FRAME_SIZE); - } + // команда перезагрузки esp + if (headerStr == "/reboot|") { + ESP.restart(); + } - if (headerStr == "/test|") { - } + // команда очистки всех логов esp + if (headerStr == "/clean|") { + cleanLogs(); + } - //----------------------------------------------------------------------// - // отдельные команды веб интерфейса - //----------------------------------------------------------------------// + // команда обновления прошивки esp + if (headerStr == "/update|") { + upgrade_firmware(3); + } - // переписать любое поле в errors json - if (headerStr == "/rorre|") { - writeUint8tValueToJsonString(payload, length, headerLenth, errorsHeapJson); - } + // Прием команд control c dashboard + if (headerStr == "/control|") { + String msg; + writeUint8tToString(payload, length, headerLenth, msg); + String key = selectFromMarkerToMarker(msg, "/", 0); + String value = selectFromMarkerToMarker(msg, "/", 1); + generateOrder(key, value); + SerialPrint( + "i", F("=>WS"), + "Msg from svelte web, WS No: " + String(num) + ", msg: " + msg); + } - // команда перезагрузки esp - if (headerStr == "/reboot|") { - ESP.restart(); - } + if (headerStr == "/tst|") { + standWebSocket.sendTXT(num, "/tstr|"); + } - // команда очистки всех логов esp - if (headerStr == "/clean|") { - cleanLogs(); - } + // получаем команду посланную из модуля + if (headerStr == "/order|") { + String json; + writeUint8tToString(payload, length, headerLenth, json); - // команда обновления прошивки esp - if (headerStr == "/update|") { - upgrade_firmware(3); - } + String id, key, value; + jsonRead(json, "id", id); + jsonRead(json, "key", key); + jsonRead(json, "value", value); - // Прием команд control c dashboard - if (headerStr == "/control|") { - String msg; - writeUint8tToString(payload, length, headerLenth, msg); - String key = selectFromMarkerToMarker(msg, "/", 0); - String value = selectFromMarkerToMarker(msg, "/", 1); - generateOrder(key, value); - SerialPrint("i", F("=>WS"), "Msg from svelte web, WS No: " + String(num) + ", msg: " + msg); - } + SerialPrint("i", F("=>WS"), "Msg from module, id: " + id); - if (headerStr == "/tst|") { - standWebSocket.sendTXT(num, "/tstr|"); - } + for (std::list::iterator it = IoTItems.begin(); + it != IoTItems.end(); ++it) { + if ((*it)->getID() == id) { + (*it)->onModuleOrder(key, value); + } + } + } - // получаем команду посланную из модуля - if (headerStr == "/order|") { - String json; - writeUint8tToString(payload, length, headerLenth, json); + } break; - String id, key, value; - jsonRead(json, "id", id); - jsonRead(json, "key", key); - jsonRead(json, "value", value); + case WStype_BIN: { + Serial.printf("[%u] get binary length: %u\n", num, length); + // hexdump(payload, length); + // standWebSocket.sendBIN(num, payload, length); + } break; - SerialPrint("i", F("=>WS"), "Msg from module, id: " + id); + case WStype_FRAGMENT_TEXT_START: { + Serial.printf("[%u] fragment test start: %u\n", num, length); + } break; - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->getID() == id) { - (*it)->onModuleOrder(key, value); - } - } - } + case WStype_FRAGMENT_BIN_START: { + Serial.printf("[%u] fragment bin start: %u\n", num, length); + } break; - } break; + case WStype_FRAGMENT: { + Serial.printf("[%u] fragment: %u\n", num, length); + } break; - case WStype_BIN: { - Serial.printf("[%u] get binary length: %u\n", num, length); - // hexdump(payload, length); - // standWebSocket.sendBIN(num, payload, length); - } break; + case WStype_FRAGMENT_FIN: { + Serial.printf("[%u] fragment finish: %u\n", num, length); + } break; - case WStype_FRAGMENT_TEXT_START: { - Serial.printf("[%u] fragment test start: %u\n", num, length); - } break; + case WStype_PING: { + Serial.printf("[%u] ping: %u\n", num, length); + } break; - case WStype_FRAGMENT_BIN_START: { - Serial.printf("[%u] fragment bin start: %u\n", num, length); - } break; + case WStype_PONG: { + Serial.printf("[%u] pong: %u\n", num, length); + } break; - case WStype_FRAGMENT: { - Serial.printf("[%u] fragment: %u\n", num, length); - } break; - - case WStype_FRAGMENT_FIN: { - Serial.printf("[%u] fragment finish: %u\n", num, length); - } break; - - case WStype_PING: { - Serial.printf("[%u] ping: %u\n", num, length); - } break; - - case WStype_PONG: { - Serial.printf("[%u] pong: %u\n", num, length); - } break; - - default: { - Serial.printf("[%u] not recognized: %u\n", num, length); - } break; - } + default: { Serial.printf("[%u] not recognized: %u\n", num, length); } break; + } } -// публикация статус сообщений в ws (недостаток в том что делаем бродкаст всем клиентам поднятым в свелте!!!) +// публикация статус сообщений в ws (недостаток в том что делаем бродкаст всем +// клиентам поднятым в свелте!!!) void publishStatusWs(const String& topic, const String& data) { - String path = mqttRootDevice + "/" + topic; - String json = "{}"; - jsonWriteStr(json, "status", data); - jsonWriteStr(json, "topic", path); - sendStringToWs("status", json, -1); + String path = mqttRootDevice + "/" + topic; + String json = "{}"; + jsonWriteStr(json, "status", data); + jsonWriteStr(json, "topic", path); + sendStringToWs("status", json, -1); } // публикация дополнительных json сообщений в ws void publishJsonWs(const String& topic, String& json) { - String path = mqttRootDevice + "/" + topic; - jsonWriteStr(json, "topic", path); - // TO DO отправка полей в веб - // sendStringToWs("status", json, -1); + String path = mqttRootDevice + "/" + topic; + jsonWriteStr(json, "topic", path); + // TO DO отправка полей в веб + // sendStringToWs("status", json, -1); } // данные которые мы отправляем в сокеты переодически void periodicWsSend() { - sendStringToWs("ssidli", ssidListHeapJson, -1); - sendStringToWs("errors", errorsHeapJson, -1); - // отправляем переодичестки только в авто режиме - if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { - sendStringToWs("devlis", devListHeapJson, -1); - } + sendStringToWs("ssidli", ssidListHeapJson, -1); + sendStringToWs("errors", errorsHeapJson, -1); + // отправляем переодичестки только в авто режиме + if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { + sendStringToWs("devlis", devListHeapJson, -1); + } } #ifdef ESP32 void hexdump(const void* mem, uint32_t len, uint8_t cols = 16) { - const uint8_t* src = (const uint8_t*)mem; - Serial.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); - for (uint32_t i = 0; i < len; i++) { - if (i % cols == 0) { - Serial.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); - } - Serial.printf("%02X ", *src); - src++; + const uint8_t* src = (const uint8_t*)mem; + Serial.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, + len, len); + for (uint32_t i = 0; i < len; i++) { + if (i % cols == 0) { + Serial.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); } - Serial.printf("\n"); + Serial.printf("%02X ", *src); + src++; + } + Serial.printf("\n"); } #endif #endif -void sendFileToWsByFrames(const String& filename, const String& header, const String& json, int client_id, size_t frameSize) { - if (header.length() != 6) { - SerialPrint("E", "FS", F("wrong header size")); - return; +void sendFileToWsByFrames(const String& filename, const String& header, + const String& json, int client_id, size_t frameSize) { + if (header.length() != 6) { + SerialPrint("E", "FS", F("wrong header size")); + return; + } + + auto path = filepath(filename); + auto file = FileFS.open(path, "r"); + if (!file) { + SerialPrint("E", "FS", F("reed file error")); + return; + } + + size_t totalSize = file.size(); + // Serial.println("Send file '" + String(filename) + "', file size: " + + // String(totalSize)); + + char buf[32]; + sprintf(buf, "%04d", json.length() + 12); + String data = header + "|" + String(buf) + "|" + json; + + size_t headerSize = data.length(); + auto frameBuf = new uint8_t[frameSize]; + size_t maxPayloadSize = frameSize - headerSize; + uint8_t* payloadBuf = nullptr; + + int i = 0; + while (file.available()) { + if (i == 0) { + data.toCharArray((char*)frameBuf, frameSize); + payloadBuf = &frameBuf[headerSize]; + } else { + maxPayloadSize = frameSize; + headerSize = 0; + payloadBuf = &frameBuf[0]; } - auto path = filepath(filename); - auto file = FileFS.open(path, "r"); - if (!file) { - SerialPrint("E", "FS", F("reed file error")); - return; + size_t payloadSize = file.read(payloadBuf, maxPayloadSize); + if (payloadSize) { + size_t size = headerSize + payloadSize; + + bool fin = false; + if (size == frameSize) { + fin = false; + } else { + fin = true; + } + + bool continuation = false; + if (i == 0) { + continuation = false; + } else { + continuation = true; + } + + // Serial.println(String(i) + ") " + "ws: " + String(client_id) + " fr sz: + // " + String(size) + " fin: " + String(fin) + " cnt: " + + // String(continuation)); + + if (client_id == -1) { + standWebSocket.broadcastBIN(frameBuf, size, fin, continuation); + + } else { + standWebSocket.sendBIN(client_id, frameBuf, size, fin, continuation); + } } - - size_t totalSize = file.size(); - // Serial.println("Send file '" + String(filename) + "', file size: " + String(totalSize)); - - char buf[32]; - sprintf(buf, "%04d", json.length() + 12); - String data = header + "|" + String(buf) + "|" + json; - - size_t headerSize = data.length(); - auto frameBuf = new uint8_t[frameSize]; - size_t maxPayloadSize = frameSize - headerSize; - uint8_t* payloadBuf = nullptr; - - int i = 0; - while (file.available()) { - if (i == 0) { - data.toCharArray((char*)frameBuf, frameSize); - payloadBuf = &frameBuf[headerSize]; - } else { - maxPayloadSize = frameSize; - headerSize = 0; - payloadBuf = &frameBuf[0]; - } - - size_t payloadSize = file.read(payloadBuf, maxPayloadSize); - if (payloadSize) { - size_t size = headerSize + payloadSize; - - bool fin = false; - if (size == frameSize) { - fin = false; - } else { - fin = true; - } - - bool continuation = false; - if (i == 0) { - continuation = false; - } else { - continuation = true; - } - - // Serial.println(String(i) + ") " + "ws: " + String(client_id) + " fr sz: " + String(size) + " fin: " + String(fin) + " cnt: " + String(continuation)); - - if (client_id == -1) { - standWebSocket.broadcastBIN(frameBuf, size, fin, continuation); - - } else { - standWebSocket.sendBIN(client_id, frameBuf, size, fin, continuation); - } - } - i++; - } - payloadBuf = &frameBuf[0]; - delete[] payloadBuf; - file.close(); + i++; + } + payloadBuf = &frameBuf[0]; + delete[] payloadBuf; + file.close(); } void sendStringToWs(const String& header, String& payload, int client_id) { - if (header.length() != 6) { - SerialPrint("E", "FS", F("wrong header size")); - return; - } + if (!(WiFi.softAPgetStationNum() || isNetworkActive())) { + return; + } - String msg = header + "|0012|" + payload; - size_t totalSize = msg.length(); + if (header.length() != 6) { + SerialPrint("E", "FS", F("wrong header size")); + return; + } - char dataArray[totalSize]; - msg.toCharArray(dataArray, totalSize + 1); - if (client_id == -1) { - standWebSocket.broadcastBIN((uint8_t*)dataArray, totalSize); - } else { - standWebSocket.sendBIN(client_id, (uint8_t*)dataArray, totalSize); - } + String msg = header + "|0012|" + payload; + size_t totalSize = msg.length(); + + char dataArray[totalSize]; + msg.toCharArray(dataArray, totalSize + 1); + if (client_id == -1) { + standWebSocket.broadcastBIN((uint8_t*)dataArray, totalSize); + } else { + standWebSocket.sendBIN(client_id, (uint8_t*)dataArray, totalSize); + } } void sendDeviceList(uint8_t num) { - if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { - // если включен автопоиск то отдаем список из оперативной памяти - SerialPrint("i", "FS", "heap list"); - sendStringToWs("devlis", devListHeapJson, num); - } else { - // если выключен автопоиск то отдаем список из флешь памяти - sendFileToWsByFrames("/devlist.json", "devlis", "", num, WEB_SOCKETS_FRAME_SIZE); - SerialPrint("i", "FS", "flash list"); - } + if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { + // если включен автопоиск то отдаем список из оперативной памяти + SerialPrint("i", "FS", "heap list"); + sendStringToWs("devlis", devListHeapJson, num); + } else { + // если выключен автопоиск то отдаем список из флешь памяти + sendFileToWsByFrames("/devlist.json", "devlis", "", num, + WEB_SOCKETS_FRAME_SIZE); + SerialPrint("i", "FS", "flash list"); + } } diff --git a/src/classes/IoTScenario.cpp b/src/classes/IoTScenario.cpp index b1c7b988..6aa26e77 100644 --- a/src/classes/IoTScenario.cpp +++ b/src/classes/IoTScenario.cpp @@ -341,7 +341,8 @@ enum SysOp { sysop_getRSSI, sysop_getIP, sysop_mqttPub, - sysop_getUptime + sysop_getUptime, + sysop_mqttIsConnect }; IoTValue sysExecute(SysOp command, std::vector ¶m) { @@ -442,6 +443,9 @@ IoTValue sysExecute(SysOp command, std::vector ¶m) { value.valS = jsonReadStr(errorsHeapJson, F("upt")); value.isDecimal = false; break; + case sysop_mqttIsConnect: + value.valD = mqttIsConnect(); + break; } return value; @@ -496,6 +500,8 @@ class SysCallExprAST : public ExprAST { operation = sysop_getTime; else if (Callee == F("getUptime")) operation = sysop_getUptime; + else if (Callee == F("mqttIsConnect")) + operation = sysop_mqttIsConnect; else operation = sysop_notfound; } diff --git a/src/modules/API.cpp b/src/modules/API.cpp index e4f040c1..f40b7c13 100644 --- a/src/modules/API.cpp +++ b/src/modules/API.cpp @@ -35,6 +35,7 @@ void* getAPI_Pcf8574(String subtype, String params); void* getAPI_Pwm8266(String subtype, String params); void* getAPI_TelegramLT(String subtype, String params); void* getAPI_Lcd2004(String subtype, String params); +void* getAPI_TM16XX(String subtype, String params); void* getAPI(String subtype, String params) { void* tmpAPI; @@ -73,5 +74,6 @@ if ((tmpAPI = getAPI_Pcf8574(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Pwm8266(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_TelegramLT(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Lcd2004(subtype, params)) != nullptr) return tmpAPI; +if ((tmpAPI = getAPI_TM16XX(subtype, params)) != nullptr) return tmpAPI; return nullptr; } \ No newline at end of file diff --git a/src/modules/display/DwinI/modinfo.json b/src/modules/display/DwinI/modinfo.json index 116fda53..079ba5ec 100644 --- a/src/modules/display/DwinI/modinfo.json +++ b/src/modules/display/DwinI/modinfo.json @@ -1,23 +1,22 @@ -{ - "menuSection": "Экраны", - - "configItem": [{ - "global": 0, - "name": "LCD Dwin экран", - "type": "Reading", - "subtype": "DwinI", - "id": "dwin", - "widget": "", - "page": "", - "descr": "", - - "int": 15, - "TX": 17, - "RX": 16, - "line": 2, - "speed": 115200 - }], - +{ + "menuSection": "screens", + "configItem": [ + { + "global": 0, + "name": "LCD Dwin экран", + "type": "Reading", + "subtype": "DwinI", + "id": "dwin", + "widget": "", + "page": "", + "descr": "", + "int": 15, + "TX": 17, + "RX": 16, + "line": 2, + "speed": 115200 + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -33,6 +32,7 @@ "propInfo": { "int": "" }, + "title": "Экраны от компании Dwin", "funcInfo": [ { "name": "rrrr", @@ -41,21 +41,13 @@ } ] }, - "defActive": false, - "usedLibs": { - "esp32_4mb": [ - ], - "esp8266_4mb": [ - ], - "esp8266_1mb": [ - ], - "esp8266_1mb_ota": [ - ], - "esp8285_1mb": [ - ], - "esp8285_1mb_ota": [ - ] + "esp32_4mb": [], + "esp8266_4mb": [], + "esp8266_1mb": [], + "esp8266_1mb_ota": [], + "esp8285_1mb": [], + "esp8285_1mb_ota": [] } } \ No newline at end of file diff --git a/src/modules/display/Lcd2004/modinfo.json b/src/modules/display/Lcd2004/modinfo.json index 0cc656ef..ccd53c60 100644 --- a/src/modules/display/Lcd2004/modinfo.json +++ b/src/modules/display/Lcd2004/modinfo.json @@ -1,40 +1,38 @@ -{ - "menuSection": "Экраны", - - "configItem": [{ - "global": 0, - "name": "LCD экран 2004", - "type": "Reading", - "subtype": "Lcd2004", - "id": "Lcd", - "widget": "inputTxt", - "page": "Экраны", - "descr": "LCD Экран", - - "addr": "0x27", - "size": "20,4", - "coord": "0,0", - "id2show": "", - "prefix": "", - "postfix": "" - }, - { - "name": "LCD экран 1602", - "type": "Reading", - "subtype": "Lcd2004", - "id": "Lcd", - "widget": "inputTxt", - "page": "Экраны", - "descr": "LCD Экран", - - "addr": "0x27", - "size": "16,2", - "coord": "0,0", - "id2show": "", - "prefix": "", - "postfix": "" - }], - +{ + "menuSection": "screens", + "configItem": [ + { + "global": 0, + "name": "LCD экран 2004", + "type": "Reading", + "subtype": "Lcd2004", + "id": "Lcd", + "widget": "inputTxt", + "page": "screens", + "descr": "LCD Экран", + "addr": "0x27", + "size": "20,4", + "coord": "0,0", + "id2show": "", + "prefix": "", + "postfix": "" + }, + { + "name": "LCD экран 1602", + "type": "Reading", + "subtype": "Lcd2004", + "id": "Lcd", + "widget": "inputTxt", + "page": "screens", + "descr": "LCD Экран", + "addr": "0x27", + "size": "16,2", + "coord": "0,0", + "id2show": "", + "prefix": "", + "postfix": "" + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -55,6 +53,7 @@ "prefix": "Символы до значения.", "postfix": "Символы после значения." }, + "title": "Символьный дисплей Lcd2004", "funcInfo": [ { "name": "noBacklight", @@ -84,33 +83,41 @@ { "name": "x", "descr": "Устанавливает первую координату", - "params": ["Номер строки первого символа"] + "params": [ + "Номер строки первого символа" + ] }, { "name": "y", "descr": "Устанавливает вторую координату", - "params": ["Номер столбца первого символа"] + "params": [ + "Номер столбца первого символа" + ] }, { "name": "prefix", "descr": "Задает приставку слева от значения", - "params": ["Строка"] + "params": [ + "Строка" + ] }, { "name": "postfix", "descr": "Задает приставку справа от значения", - "params": ["Строка"] + "params": [ + "Строка" + ] }, { "name": "id2show", "descr": "Задает ИД элемента, значение которого хотим отображать на экране", - "params": ["Имя элемента конфигурации"] + "params": [ + "Имя элемента конфигурации" + ] } ] }, - "defActive": true, - "usedLibs": { "esp32_4mb": [ "https://github.com/robotclass/RobotClass_LiquidCrystal_I2C", diff --git a/src/modules/display/NextionUpload/modinfo.json b/src/modules/display/NextionUpload/modinfo.json index a97f2343..a3a7efa5 100644 --- a/src/modules/display/NextionUpload/modinfo.json +++ b/src/modules/display/NextionUpload/modinfo.json @@ -1,6 +1,5 @@ { - "menuSection": "Экраны", - + "menuSection": "screens", "configItem": [ { "global": 0, @@ -17,7 +16,6 @@ "NEXT_RX": 17 } ], - "about": { "authorName": "AVAKS", "authorContact": "https://t.me/@avaks_dev", @@ -36,15 +34,25 @@ "url": "файл прошивки" } }, - "defActive": false, - "usedLibs": { - "esp32_4mb": ["https://github.com/avaksru/ESPNexUpload.git"], - "esp8266_4mb": ["https://github.com/avaksru/ESPNexUpload.git"], - "esp8266_1mb": ["https://github.com/avaksru/ESPNexUpload.git"], - "esp8266_1mb_ota": ["https://github.com/avaksru/ESPNexUpload.git"], - "esp8285_1mb": ["https://github.com/avaksru/ESPNexUpload.git"], - "esp8285_1mb_ota": ["https://github.com/avaksru/ESPNexUpload.git"] + "esp32_4mb": [ + "https://github.com/avaksru/ESPNexUpload.git" + ], + "esp8266_4mb": [ + "https://github.com/avaksru/ESPNexUpload.git" + ], + "esp8266_1mb": [ + "https://github.com/avaksru/ESPNexUpload.git" + ], + "esp8266_1mb_ota": [ + "https://github.com/avaksru/ESPNexUpload.git" + ], + "esp8285_1mb": [ + "https://github.com/avaksru/ESPNexUpload.git" + ], + "esp8285_1mb_ota": [ + "https://github.com/avaksru/ESPNexUpload.git" + ] } -} +} \ No newline at end of file diff --git a/src/modules/display/Oled128/Oled128.cpp b/src/modules/display/Oled128/Oled128.cpp new file mode 100644 index 00000000..91ebee55 --- /dev/null +++ b/src/modules/display/Oled128/Oled128.cpp @@ -0,0 +1,174 @@ +#include "Global.h" +#include "classes/IoTItem.h" + +#include + +GyverOLED oled; + +// GyverOLED oled; +// GyverOLED oled; +// GyverOLED oled; +// GyverOLED oled; +// GyverOLED oled; + +class Oled128 : public IoTItem { + private: + unsigned int _x; + unsigned int _y; + + unsigned int _k; + + int _shrift; + + String _id2show; + String _descr; + String _descr1; + + int _prevStrSize; + + bool _isShow = true; // экран показывает + + public: + Oled128(String parameters) : IoTItem(parameters) { + String addr, size, xy, k; + _prevStrSize = 0; + + jsonRead(parameters, "addr", addr); + if (addr == "") { + // scanI2C(); + return; + } + + jsonRead(parameters, "coord", xy); + _x = selectFromMarkerToMarker(xy, ",", 0).toInt(); + _y = selectFromMarkerToMarker(xy, ",", 1).toInt(); + + jsonRead(parameters, "descr", _descr); + jsonRead(parameters, "id2show", _id2show); + jsonRead(parameters, "descr1", _descr1); + // jsonRead(parameters, "scale", _k); + jsonRead(parameters, "shrift", _shrift); + + // Wire.begin(2,0); // Инициализация шины I2C для модуля E01 + + oled.init(); // инициализация экрана + } + + void doByInterval() { + printBlankStr(_prevStrSize); + + String tmpStr = ""; + + // if (_descr != "none") tmpStr = _descr + " " + getItemValue(_id2show); + if (_descr != "none") + tmpStr = _descr + " " + getItemValue(_id2show) + " " + _descr1; + else + tmpStr = getItemValue(_id2show); + + // oled.setScale(2); + + oled.setScale(_shrift); + + oled.setCursorXY(_x, _y); + + oled.print(tmpStr); + + oled.update(); + + _prevStrSize = tmpStr.length(); + } + + IoTValue execute(String command, std::vector ¶m) { // будет возможным использовать, когда сценарии запустятся + + if (command == "scroll") { + String tmpStr = ""; + oled.clear(); + uint32_t tmr = millis(); + oled.autoPrintln(false); + int val = 128; + for (;;) { + // oled.clear(); // ЗАКОММЕНТИРУЙ, ЕСЛИ ВКЛЮЧЕН БУФЕР + // oled.setScale(2); + + oled.setScale(_shrift); + + oled.setCursor(val, _y); + + oled.print(tmpStr); + oled.update(); + val--; + if (millis() - tmr > 5000) + ; // return; + + _isShow = true; + } + + } + + else if (command == "stopscroll") { + _isShow = true; + // display->backlight(); + // else if (command == "noDisplay") { + // display->noDisplay(); + // _isShow = false; + } else if (command == "display") { + // display.display(); + _isShow = true; + } else if (command == "toggle") { + if (_isShow) { + // display->noDisplay(); + _isShow = false; + } else { + // display.display(); + _isShow = true; + } + } else if (command == "x") { + if (param.size()) { + _x = param[0].valD; + } + } else if (command == "y") { + if (param.size()) { + _y = param[0].valD; + } + } else if (command == "descr") { + if (param.size()) { + _descr = param[0].valS; + } + } else if (command == "descr1") { + if (param.size()) { + _descr1 = param[0].valS; + } + } else if (command == "id2show") { + if (param.size()) { + _id2show = param[0].valS; + } + } + + doByInterval(); + return {}; + } + + // печать пустой строки нужной длинны для затирания предыдущего значения на экране + void printBlankStr(int strSize) { + String tmpStr = ""; + for (int i = 0; i < strSize; i++) tmpStr += " "; + + // oled.setScale(2); + + oled.setScale(_shrift); + + oled.setCursorXY(_x, _y); + + oled.print(tmpStr); + } + + ~Oled128(){}; +}; + +void *getAPI_Oled128(String subtype, String param) { + if (subtype == F("Oled128")) { + return new Oled128(param); + } else { + return nullptr; + } +} \ No newline at end of file diff --git a/src/modules/display/Oled128/modinfo.json b/src/modules/display/Oled128/modinfo.json new file mode 100644 index 00000000..3c3c73ac --- /dev/null +++ b/src/modules/display/Oled128/modinfo.json @@ -0,0 +1,86 @@ +{ + "menuSection": "screens", + "configItem": [ + { + "name": "OLED экран 128*64", + "type": "Reading", + "subtype": "Oled128", + "id": "oled", + "widget": "", + "page": "", + "descr": "T", + "descr1": "C", + "int": 1, + "addr": "0x3C", + "coord": "0,10", + "id2show": "id датчика", + "shrift": "2" + } + ], + "about": { + "authorName": "Serghei Crasnicov", + "authorContact": "https://t.me/Serghei63", + "authorGit": "https://github.com/Serghei63", + "specialThanks": "Ilya Belyakov @Biveraxe", + "moduleName": "Oled128", + "moduleVersion": "1.0", + "moduleDesc": "Позволяет выводить на матричные Oled экраны по указанным позициям значения других элементов конфигурации.", + "usedRam": 15, + "propInfo": { + "int": "Период времени в секундах обновления информации на экране по конкретному элементу.", + "addr": "Адрес устройства на шине, обычно 0x3c.", + "coord": "Координата позиции для вывода данных элемента конфигурации.", + "id2show": "id элемента конфигурации.", + "shrift": "Шрифт текста от 1 до 4 " + }, + "funcInfo": [ + { + "name": "x", + "descr": "Устанавливает первую координату", + "params": [ + "Номер строки первого символа" + ] + }, + { + "name": "y", + "descr": "Устанавливает вторую координату", + "params": [ + "Номер столбца первого символа" + ] + }, + { + "name": "descr", + "descr": "Задает приставку слева от значения, если none значит пусто", + "params": [ + "Строка" + ] + }, + { + "name": "descr1", + "descr": "Задает приставку справа от значения. Если descr none , то не выводится", + "params": [ + "Строка" + ] + }, + { + "name": "id2show", + "descr": "Задает ИД элемента, значение которого хотим отображать на экране", + "params": [ + "Имя элемента конфигурации" + ] + } + ] + }, + "defActive": false, + "usedLibs": { + "esp32_4mb": [ + "gyverlibs/GyverOLED @ 1.4" + ], + "esp32_16mb": [ + "gyverlibs/GyverOLED @ 1.4" + ], + "esp8266_4mb": [ + "gyverlibs/GyverOLED @ 1.4" + ] + } +} \ No newline at end of file diff --git a/src/modules/display/Smi2_m/modinfo.json b/src/modules/display/Smi2_m/modinfo.json index 360e6374..34a1ff2d 100644 --- a/src/modules/display/Smi2_m/modinfo.json +++ b/src/modules/display/Smi2_m/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Экраны", + "menuSection": "screens", "configItem": [ { "global": 0, @@ -32,6 +32,7 @@ "id2show": "id элемента конфигурации.", "baud": "скорость обмена, бит/с" }, + "title": "СМИ2-М трёхцветный Modbus-индикатор", "funcInfo": [ { "name": "descr", diff --git a/src/modules/display/TM16XX/modinfo.json b/src/modules/display/TM16XX/modinfo.json index 9c6461ed..1476107f 100644 --- a/src/modules/display/TM16XX/modinfo.json +++ b/src/modules/display/TM16XX/modinfo.json @@ -1,27 +1,26 @@ -{ - "menuSection": "Экраны", - - "configItem": [{ - "global": 0, - "name": "7 сегментный дисплей TM16XX", - "type": "Writing", - "subtype": "TM16XX", - "id": "tm", - "widget": "inputTxt", - "page": "Экраны", - "descr": "Экран", - "round": 0, - - "chip": 1637, - "numDigits": 4, - "DIO": "13", - "CLK": "14", - "STB": "12", - "intensity": "5", - "on": "1", - "id2show": "" - }], - +{ + "menuSection": "screens", + "configItem": [ + { + "global": 0, + "name": "7 сегментный дисплей TM16XX", + "type": "Writing", + "subtype": "TM16XX", + "id": "tm", + "widget": "inputTxt", + "page": "screens", + "descr": "Экран", + "round": 0, + "chip": 1637, + "numDigits": 4, + "DIO": "13", + "CLK": "14", + "STB": "12", + "intensity": "5", + "on": "1", + "id2show": "" + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -74,60 +73,74 @@ { "name": "x", "descr": "Устанавливает первую координату", - "params": ["Номер строки первого символа"] + "params": [ + "Номер строки первого символа" + ] }, { "name": "y", "descr": "Устанавливает вторую координату", - "params": ["Номер столбца первого символа"] + "params": [ + "Номер столбца первого символа" + ] }, { "name": "descr", "descr": "Задает приставку слева от значения", - "params": ["Строка"] + "params": [ + "Строка" + ] }, { "name": "id2show", "descr": "Задает ИД элемента, значение которого хотим отображать на экране", - "params": ["Имя элемента конфигурации"] + "params": [ + "Имя элемента конфигурации" + ] } ] }, - "defActive": true, - "usedLibs": { "esp32_4mb": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8266_4mb": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8266_1mb": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8266_1mb_ota": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8285_1mb": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8285_1mb_ota": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8266_2mb": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8266_2mb_ota": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ] } } \ No newline at end of file diff --git a/src/modules/display/Ws2812b/modinfo.json b/src/modules/display/Ws2812b/modinfo.json index 6ff7dd56..4b601f4b 100644 --- a/src/modules/display/Ws2812b/modinfo.json +++ b/src/modules/display/Ws2812b/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Экраны", + "menuSection": "screens", "configItem": [ { "global": 0, @@ -40,6 +40,7 @@ "max": "Максимальный порог индикатора на который реагировать.", "idshow": "id элемента конфигурации который нужно повесить индикацию." }, + "title": "Адресная светодиодная матрица", "funcInfo": [ { "name": "noShow", diff --git a/src/modules/exec/ButtonIn/modinfo.json b/src/modules/exec/ButtonIn/modinfo.json index 690ace99..7c185014 100644 --- a/src/modules/exec/ButtonIn/modinfo.json +++ b/src/modules/exec/ButtonIn/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Исполнительные устройства", + "menuSection": "executive_devices", "configItem": [ { "global": 0, @@ -46,7 +46,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], + "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/exec/ButtonOut/modinfo.json b/src/modules/exec/ButtonOut/modinfo.json index 35e4d5c7..c24cd62d 100644 --- a/src/modules/exec/ButtonOut/modinfo.json +++ b/src/modules/exec/ButtonOut/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Исполнительные устройства", + "menuSection": "executive_devices", "configItem": [ { "global": 0, @@ -45,7 +45,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], + "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/exec/Buzzer/modinfo.json b/src/modules/exec/Buzzer/modinfo.json index d3ec13f4..44dcdf97 100644 --- a/src/modules/exec/Buzzer/modinfo.json +++ b/src/modules/exec/Buzzer/modinfo.json @@ -1,29 +1,29 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "Пассивный звуковой извещатель", - "type": "Writing", - "subtype": "Buzzer", - "id": "buzzer", - "widget": "toggle", - "page": "Кнопки", - "descr": "Buzzer", - "int": 4000, - "pin": 14, - "freq": 2000, - "duration": 1000, - "beatLevel": 4, - "tempo": 120, - "tempoCorrection": 1, - "pauseBetween": 0, - "transpose": 0, - "cycle": 0, - "indication": 1, - "val": 0 - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "Пассивный звуковой извещатель", + "type": "Writing", + "subtype": "Buzzer", + "id": "buzzer", + "widget": "toggle", + "page": "Кнопки", + "descr": "Buzzer", + "int": 4000, + "pin": 14, + "freq": 2000, + "duration": 1000, + "beatLevel": 4, + "tempo": 120, + "tempoCorrection": 1, + "pauseBetween": 0, + "transpose": 0, + "cycle": 0, + "indication": 1, + "val": 0 + } + ], "about": { "authorName": "Alex K", "authorContact": "https://t.me/cmche", @@ -43,11 +43,11 @@ "int": "Количество миллисекунд между повторами одиночного сигнала", "pin": "Управляемый пин", "freq": "Частота сигнала, Hz", - "duration": "Длительность сигнала, ms", + "duration": "Длительность сигнала, ms", "beatLevel": "Долей в такте", - "tempo": "Оригинальный темп мелодии, bpm", - "tempoCorrection": "Коррекция темпа мелодии", - "pauseBetween": "Дополнительная пауза между нот, в долях от длительности ноты", + "tempo": "Оригинальный темп мелодии, bpm", + "tempoCorrection": "Коррекция темпа мелодии", + "pauseBetween": "Дополнительная пауза между нот, в долях от длительности ноты", "transpose": "Транспонирование на количество полутонов. +/-12 - для повышения/понижения на октаву", "cycle": "Повтор мелодии/серии сигналов", "indication": "Индикация в виджет, что идет сигнал, играет мелодия", @@ -57,17 +57,30 @@ { "name": "tone", "descr": "Проигрывание одиночного сигнала (без индикации)", - "params": ["Частота", "Длительность (ms)"] + "params": [ + "Частота", + "Длительность (ms)" + ] }, { "name": "tones", "descr": "Проигрывание серии сигналов, до 128", - "params": ["Частота 1-го сигнала", "Длительность 1-го сигнала (ms)","Частота 2-го сигала", "Длительность 2-го сигнала", "....итд"] + "params": [ + "Частота 1-го сигнала", + "Длительность 1-го сигнала (ms)", + "Частота 2-го сигала", + "Длительность 2-го сигнала", + "....итд" + ] }, { "name": "melody", "descr": "Проигрывание мелодии, до 256 нот. Кодировка 'YYX.ZZZ'. Научная нотация: YY - обозначение ноты (C,CS,D,DS,E,F,FS,G,GS,A,AS,B), X - номер октавы (0-9), ZZZ - длительность в тысячных долях такта (0-999). Обязательно в двойных кавычках. 'AS4.50' - Ля# 4-й октавы, 1/2 такта. На Github лежит Excel файл для перекодировки.", - "params": ["Код 1-ой ноты","Код 2-й ноты"," и тд"] + "params": [ + "Код 1-ой ноты", + "Код 2-й ноты", + " и тд" + ] }, { "name": "notone", @@ -76,15 +89,19 @@ }, { "name": "melodySetting", - "descr": "Перенастройка параметров мелодии: Долей в такте - (обычно 4), Оригинальный темп -(40-208 bpm), Коррекция темпа - в k раз быстрее/медленнее, Пауза между нот (стакато) - доля от длительности, Коррекция тональности (транспонирование) - в k раз выше/ниже, Повтор 1/0. Чтобы не изменялось значение вбить любой текст в ковычках ", - "params": ["Долей в такте", "Оригинальный темп", "Коррекция темпа", "Пауза между нот", "Коррекция тональности", "Повтор мелодии/серии сигналов"] + "descr": "Перенастройка параметров мелодии: Долей в такте - (обычно 4), Оригинальный темп -(40-208 bpm), Коррекция темпа - в k раз быстрее/медленнее, Пауза между нот (стакато) - доля от длительности, Коррекция тональности (транспонирование) - в k раз выше/ниже, Повтор 1/0. Чтобы не изменялось значение вбить любой текст в ковычках ", + "params": [ + "Долей в такте", + "Оригинальный темп", + "Коррекция темпа", + "Пауза между нот", + "Коррекция тональности", + "Повтор мелодии/серии сигналов" + ] } - ] }, - "defActive": true, - "usedLibs": { "esp32_4mb": [], "esp8266_4mb": [], @@ -94,5 +111,5 @@ "esp8285_1mb_ota": [], "esp8266_2mb": [], "esp8266_2mb_ota": [] - } -} + } +} \ No newline at end of file diff --git a/src/modules/exec/Enconder/modinfo.json b/src/modules/exec/Enconder/modinfo.json index ce92fb01..1a86b03c 100644 --- a/src/modules/exec/Enconder/modinfo.json +++ b/src/modules/exec/Enconder/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Исполнительные устройства", + "menuSection": "executive_devices", "configItem": [ { "global": 0, @@ -12,8 +12,7 @@ "descr": "Громкость", "needSave": 0, "val": "0", - "round" : 0, - + "round": 0, "step": 1, "stepOnPress": 5, "pins": "4,5,2" @@ -37,7 +36,7 @@ "moduleDesc": "модуль для работы с Энкодером. Кнопочный вариант совместим с модулями Multitouch и ButtonIn", "retInfo": "Значение счетчика", "propInfo": { - "step" : "Размер шага Энкодера, может принимать значение 0.0001 или 1000", + "step": "Размер шага Энкодера, может принимать значение 0.0001 или 1000", "stepOnPress": "Размер шага Энкодера при нажатой кнопке, 0 - отключает учет", "pins": "Подключеные пины (CLK, DT, SW)" } @@ -50,6 +49,9 @@ "esp8266_4mb": [ "gyverlibs/EncButton @ ^2.0" ], + "esp8266_16mb": [ + "gyverlibs/EncButton @ ^2.0" + ], "esp8266_1mb": [ "gyverlibs/EncButton @ ^2.0" ], diff --git a/src/modules/exec/EspCam/modinfo.json b/src/modules/exec/EspCam/modinfo.json index 429beddf..a0e01934 100644 --- a/src/modules/exec/EspCam/modinfo.json +++ b/src/modules/exec/EspCam/modinfo.json @@ -1,22 +1,21 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "Camera OV2640 (ESPcam)", - "type": "Reading", - "subtype": "EspCam", - "id": "EspCam", - "widget": "", - "page": "", - "descr": "", - - "int": 60, - "useLed": 0, - "ticker": 0, - "webTicker": 0 - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "Camera OV2640 (ESPcam)", + "type": "Reading", + "subtype": "EspCam", + "id": "EspCam", + "widget": "", + "page": "", + "descr": "", + "int": 60, + "useLed": 0, + "ticker": 0, + "webTicker": 0 + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -45,7 +44,9 @@ { "name": "ledOn", "descr": "Включить подсветку", - "params": ["Яркость 0-255"] + "params": [ + "Яркость 0-255" + ] }, { "name": "ledOff", @@ -54,9 +55,7 @@ } ] }, - "defActive": false, - "usedLibs": { "esp32_4mb": [ "espressif/esp32-camera @ ^2.0.0" diff --git a/src/modules/exec/Ftp/modinfo.json b/src/modules/exec/Ftp/modinfo.json index 50392527..475a3f1c 100644 --- a/src/modules/exec/Ftp/modinfo.json +++ b/src/modules/exec/Ftp/modinfo.json @@ -1,46 +1,43 @@ { - "menuSection": "Исполнительные устройства", - "configItem": [ - { - "global": 0, - "name": "FTP сервер", - "type": "Reading", - "subtype": "ftp", - "id": "ftp", - "widget": "nil", - "page": "", - "descr": "FTP сервер", - "login": "admin", - "pass": "admin" - - - } - - - ], - "about": { - "authorName": "Bubnov Mikhail", - "authorContact": "https://t.me/Mit4bmw", - "authorGit": "https://github.com/Mit4el", - "specialThanks": "", - "moduleName": "FTPModule", - "moduleVersion": "0.1", - "usedRam": { - "esp32_4mb": 15, - "esp8266_4mb": 15 - }, - "title": "FTP-сервер", - "moduleDesc": "Запускает FTP-сервер на плате esp", - "propInfo": { - "login": "Логин FTP сервера", - "pass": "Пароль FTP сервера" - } - }, - "defActive": false, - "usedLibs": { - "esp32_4mb": [], - "esp32s2_4mb": [], - "esp8266_4mb": [] - } -} - + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "FTP сервер", + "type": "Reading", + "subtype": "ftp", + "id": "ftp", + "widget": "nil", + "page": "", + "descr": "FTP сервер", + "login": "admin", + "pass": "admin" + } + ], + "about": { + "authorName": "Bubnov Mikhail", + "authorContact": "https://t.me/Mit4bmw", + "authorGit": "https://github.com/Mit4el", + "specialThanks": "", + "moduleName": "FTPModule", + "moduleVersion": "0.1", + "usedRam": { + "esp32_4mb": 15, + "esp8266_4mb": 15 + }, + "title": "FTP-сервер", + "moduleDesc": "Запускает FTP-сервер на плате esp", + "propInfo": { + "login": "Логин FTP сервера", + "pass": "Пароль FTP сервера" + } + }, + "defActive": false, + "usedLibs": { + "esp32_4mb": [], + "esp32_16mb": [], + "esp32s2_4mb": [], + "esp8266_4mb": [], + "esp8266_16mb": [] + } +} \ No newline at end of file diff --git a/src/modules/exec/HttpGet/modinfo.json b/src/modules/exec/HttpGet/modinfo.json index 0c97357e..2c483c06 100644 --- a/src/modules/exec/HttpGet/modinfo.json +++ b/src/modules/exec/HttpGet/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Исполнительные устройства", + "menuSection": "executive_devices", "configItem": [ { "global": 0, @@ -41,7 +41,8 @@ "name": "post", "descr": "Отправить http запрос методом POST.", "params": [ - "URL","message" + "URL", + "message" ] } ] diff --git a/src/modules/exec/IoTServo/modinfo.json b/src/modules/exec/IoTServo/modinfo.json index b9a16e1b..1bb4f300 100644 --- a/src/modules/exec/IoTServo/modinfo.json +++ b/src/modules/exec/IoTServo/modinfo.json @@ -1,22 +1,21 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "Сервопривод", - "type": "Writing", - "subtype": "IoTServo", - "id": "servo", - "widget": "range", - "page": "servo", - "descr": "угол", - - "int": 1, - "pin": 12, - "apin": -1, - "amap": "0, 4096, 0, 180" - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "Сервопривод", + "type": "Writing", + "subtype": "IoTServo", + "id": "servo", + "widget": "rangeServo", + "page": "servo", + "descr": "угол", + "int": 1, + "pin": 12, + "apin": -1, + "amap": "0, 4096, 0, 180" + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -41,16 +40,16 @@ { "name": "rotate", "descr": "Повернуть привод на значение", - "params": ["Числовое значение"] + "params": [ + "Числовое значение" + ] } ] }, - "defActive": true, - "usedLibs": { "esp32_4mb": [ - "https://github.com/RoboticsBrno/ServoESP32" + "https://github.com/RoboticsBrno/ServoESP32#v1.0.3" ], "esp8266_4mb": [] } diff --git a/src/modules/exec/Mcp23008/modinfo.json b/src/modules/exec/Mcp23008/modinfo.json index d04c12f7..2f322ce3 100644 --- a/src/modules/exec/Mcp23008/modinfo.json +++ b/src/modules/exec/Mcp23008/modinfo.json @@ -1,21 +1,20 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "Расширитель портов Mcp23008", - "type": "Reading", - "subtype": "Mcp23008", - "id": "Mcp", - "widget": "", - "page": "", - "descr": "", - - "int": "0", - "addr": "0x20", - "index": 1 - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "Расширитель портов Mcp23008", + "type": "Reading", + "subtype": "Mcp23008", + "id": "Mcp", + "widget": "", + "page": "", + "descr": "", + "int": "0", + "addr": "0x20", + "index": 1 + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -35,9 +34,7 @@ "index": "Значения от 1 до 4, где при выборе 1 будет нумерация pin 100-115, при выборе 2 200-215 и т.д." } }, - "defActive": false, - "usedLibs": { "esp32_4mb": [ "adafruit/Adafruit Mcp23017 Arduino Library@^2.1.0", diff --git a/src/modules/exec/Mcp23017/modinfo.json b/src/modules/exec/Mcp23017/modinfo.json index ad20b6ca..88659ccb 100644 --- a/src/modules/exec/Mcp23017/modinfo.json +++ b/src/modules/exec/Mcp23017/modinfo.json @@ -1,21 +1,20 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "Расширитель портов Mcp23017", - "type": "Reading", - "subtype": "Mcp23017", - "id": "Mcp", - "widget": "", - "page": "", - "descr": "", - - "int": "0", - "addr": "0x20", - "index": 1 - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "Расширитель портов Mcp23017", + "type": "Reading", + "subtype": "Mcp23017", + "id": "Mcp", + "widget": "", + "page": "", + "descr": "", + "int": "0", + "addr": "0x20", + "index": 1 + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -35,9 +34,7 @@ "index": "Значения от 1 до 4, где при выборе 1 будет нумерация pin 100-115, при выборе 2 200-215 и т.д." } }, - "defActive": true, - "usedLibs": { "esp32_4mb": [ "adafruit/Adafruit MCP23017 Arduino Library@^2.1.0", diff --git a/src/modules/exec/Mp3/modinfo.json b/src/modules/exec/Mp3/modinfo.json index efd4f6f8..381bd309 100644 --- a/src/modules/exec/Mp3/modinfo.json +++ b/src/modules/exec/Mp3/modinfo.json @@ -1,21 +1,20 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "MP3 плеер", - "type": "Reading", - "subtype": "Mp3", - "id": "mp3", - "widget": "", - "page": "", - "descr": "", - - "int": 1, - "pins": "14,12", - "volume": 20 - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "MP3 плеер", + "type": "Reading", + "subtype": "Mp3", + "id": "mp3", + "widget": "", + "page": "", + "descr": "", + "int": 1, + "pins": "14,12", + "volume": 20 + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -59,12 +58,17 @@ { "name": "volume", "descr": "Установить громкость", - "params": ["Значение громкости"] + "params": [ + "Значение громкости" + ] }, { "name": "playFolder", "descr": "Проиграть файл из папки", - "params": ["Номер папки", "Номер файла"] + "params": [ + "Номер папки", + "Номер файла" + ] }, { "name": "play", @@ -83,9 +87,7 @@ } ] }, - "defActive": true, - "usedLibs": { "esp32_4mb": [ "dfrobot/DFRobotDFPlayerMini @ ^1.0.5" diff --git a/src/modules/exec/Multitouch/modinfo.json b/src/modules/exec/Multitouch/modinfo.json index a9e103d7..d9d2f31a 100644 --- a/src/modules/exec/Multitouch/modinfo.json +++ b/src/modules/exec/Multitouch/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Исполнительные устройства", + "menuSection": "executive_devices", "configItem": [ { "global": 0, @@ -52,4 +52,4 @@ "esp8266_2mb": [], "esp8266_2mb_ota": [] } -} +} \ No newline at end of file diff --git a/src/modules/exec/MySensors/modinfo.json b/src/modules/exec/MySensors/modinfo.json index b611a1d7..252c70d1 100644 --- a/src/modules/exec/MySensors/modinfo.json +++ b/src/modules/exec/MySensors/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Исполнительные устройства", + "menuSection": "executive_devices", "configItem": [ { "global": 0, diff --git a/src/modules/exec/Pcf8574/modinfo.json b/src/modules/exec/Pcf8574/modinfo.json index c3bfd7f4..782a86d6 100644 --- a/src/modules/exec/Pcf8574/modinfo.json +++ b/src/modules/exec/Pcf8574/modinfo.json @@ -1,20 +1,20 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "Расширитель портов Pcf8574", - "type": "Reading", - "subtype": "Pcf8574", - "id": "Pcf", - "widget": "", - "page": "", - "descr": "", - "int": "0", - "addr": "0x20", - "index": 1 - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "Расширитель портов Pcf8574", + "type": "Reading", + "subtype": "Pcf8574", + "id": "Pcf", + "widget": "", + "page": "", + "descr": "", + "int": "0", + "addr": "0x20", + "index": 1 + } + ], "about": { "authorName": "Serghei Crasnicov", "authorContact": "https://t.me/Serghei63", @@ -27,11 +27,10 @@ "int": "Не используется", "addr": "Адрес устройства на шине, обычно 0x20", "index": "Значения от 1 до 4, где при выборе 1 будет нумерация pin 100-115, при выборе 2 200-215 и т.д." - } + }, + "title": "Расширитель портов Pcf8574" }, - "defActive": true, - "usedLibs": { "esp32_4mb": [ "adafruit/Adafruit BusIO @ ^1.13.2" diff --git a/src/modules/exec/Pwm32/modinfo.json b/src/modules/exec/Pwm32/modinfo.json index dda8786b..e8a685b8 100644 --- a/src/modules/exec/Pwm32/modinfo.json +++ b/src/modules/exec/Pwm32/modinfo.json @@ -1,24 +1,24 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "PWM ESP32", - "type": "Writing", - "subtype": "Pwm32", - "id": "pwm", - "widget": "range", - "page": "Кнопки", - "descr": "PWM", - "int": 0, - "pin": 2, - "freq": 5000, - "ledChannel": 2, - "PWM_resolution": 10, - "val": 0, - "apin": -1 - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "PWM ESP32", + "type": "Writing", + "subtype": "Pwm32", + "id": "pwm", + "widget": "range", + "page": "Кнопки", + "descr": "PWM", + "int": 0, + "pin": 2, + "freq": 5000, + "ledChannel": 2, + "PWM_resolution": 10, + "val": 0, + "apin": -1 + } + ], "about": { "authorName": "Avaks", "authorContact": "https://t.me/Avaks", @@ -42,9 +42,7 @@ "freq": "Частота" } }, - "defActive": true, - "usedLibs": { "esp32_4mb": [] } diff --git a/src/modules/exec/Pwm8266/modinfo.json b/src/modules/exec/Pwm8266/modinfo.json index dfd53149..f446db57 100644 --- a/src/modules/exec/Pwm8266/modinfo.json +++ b/src/modules/exec/Pwm8266/modinfo.json @@ -1,22 +1,22 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "PWM ESP8266", - "type": "Writing", - "subtype": "Pwm8266", - "id": "pwm", - "widget": "range", - "page": "Кнопки", - "descr": "PWM", - "int": 0, - "pin": 15, - "freq": 5000, - "val": 0, - "apin": -1 - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "PWM ESP8266", + "type": "Writing", + "subtype": "Pwm8266", + "id": "pwm", + "widget": "range", + "page": "Кнопки", + "descr": "PWM", + "int": 0, + "pin": 15, + "freq": 5000, + "val": 0, + "apin": -1 + } + ], "about": { "authorName": "Avaks", "authorContact": "https://t.me/Avaks", @@ -38,9 +38,7 @@ "freq": "Частота" } }, - "defActive": true, - "usedLibs": { "esp8266_4mb": [], "esp8266_1mb": [], diff --git a/src/modules/exec/SDcard/modinfo.json b/src/modules/exec/SDcard/modinfo.json index ef917963..eea8b9c2 100644 --- a/src/modules/exec/SDcard/modinfo.json +++ b/src/modules/exec/SDcard/modinfo.json @@ -1,19 +1,18 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "SD карта", - "type": "Writing", - "subtype": "SDcard", - "id": "sd", - "widget": "", - "page": "", - "descr": "", - - "int": 1 - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "SD карта", + "type": "Writing", + "subtype": "SDcard", + "id": "sd", + "widget": "", + "page": "", + "descr": "", + "int": 1 + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -31,9 +30,7 @@ "int": "Не используется." } }, - "defActive": false, - "usedLibs": { "esp32_4mb": [ "espressif/esp32-camera @ ^2.0.0" diff --git a/src/modules/exec/SysExt/modinfo.json b/src/modules/exec/SysExt/modinfo.json index 3f4313dc..bb978bff 100644 --- a/src/modules/exec/SysExt/modinfo.json +++ b/src/modules/exec/SysExt/modinfo.json @@ -1,18 +1,18 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "Доп. функции системы", - "type": "Reading", - "subtype": "SysExt", - "id": "SysExt", - "widget": "", - "page": "", - "descr": "", - "int": 15 - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "Доп. функции системы", + "type": "Reading", + "subtype": "SysExt", + "id": "SysExt", + "widget": "", + "page": "", + "descr": "", + "int": 15 + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -30,9 +30,7 @@ "int": "Не используется" } }, - "defActive": false, - "usedLibs": { "esp32_4mb": [], "esp8266_4mb": [] diff --git a/src/modules/exec/Telegram/modinfo.json b/src/modules/exec/Telegram/modinfo.json index b28a2478..9e073cea 100644 --- a/src/modules/exec/Telegram/modinfo.json +++ b/src/modules/exec/Telegram/modinfo.json @@ -1,23 +1,22 @@ -{ - "menuSection": "Исполнительные устройства", - - "configItem": [{ - "global": 0, - "name": "Телеграм-Бот", - "type": "Writing", - "subtype": "Telegram", - "id": "tg", - "widget": "", - "page": "", - "descr": "", - "int": 10, - - "token": "", - "autos": 1, - "receiveMsg": 0, - "chatID": "" - }], - +{ + "menuSection": "executive_devices", + "configItem": [ + { + "global": 0, + "name": "Телеграм-Бот", + "type": "Writing", + "subtype": "Telegram", + "id": "tg", + "widget": "", + "page": "", + "descr": "", + "int": 10, + "token": "", + "autos": 1, + "receiveMsg": 0, + "chatID": "" + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", @@ -38,25 +37,30 @@ "chatID": "ИД диалога с контактом. Необходим для отправки сообщений именно вам." }, "funcInfo": [ - { + { "name": "sendMsg", "descr": "Отправить сообщение без повторений.", - "params": ["Сообщение, может быть строкой, числом или ИД другого элемента для получения значения"] + "params": [ + "Сообщение, может быть строкой, числом или ИД другого элемента для получения значения" + ] }, - { + { "name": "sendOftenMsg", "descr": "Отправить сообщение в любом случае, даж если отправляли такое ранее.", - "params": ["Сообщение, может быть строкой, числом или ИД другого элемента для получения значения"] + "params": [ + "Сообщение, может быть строкой, числом или ИД другого элемента для получения значения" + ] } - ] + ] }, - "defActive": false, - "usedLibs": { "esp32_4mb": [ "CTBot @2.1.9" ], + "esp32_16mb": [ + "CTBot @2.1.9" + ], "esp8266_4mb": [ "CTBot @2.1.9" ] diff --git a/src/modules/exec/TelegramLT/modinfo.json b/src/modules/exec/TelegramLT/modinfo.json index 49c44966..3edf2da6 100644 --- a/src/modules/exec/TelegramLT/modinfo.json +++ b/src/modules/exec/TelegramLT/modinfo.json @@ -1,6 +1,5 @@ { - "menuSection": "Исполнительные устройства", - + "menuSection": "executive_devices", "configItem": [ { "global": 0, @@ -15,7 +14,6 @@ "chatID": "" } ], - "about": { "authorName": "AVAKS", "authorContact": "https://t.me/@avaks_dev", @@ -51,13 +49,13 @@ } ] }, - "defActive": true, - "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], @@ -65,4 +63,4 @@ "esp8266_2mb": [], "esp8266_2mb_ota": [] } -} +} \ No newline at end of file diff --git a/src/modules/exec/Thermostat/modinfo.json b/src/modules/exec/Thermostat/modinfo.json index 9c356ea3..925e0df3 100644 --- a/src/modules/exec/Thermostat/modinfo.json +++ b/src/modules/exec/Thermostat/modinfo.json @@ -1,6 +1,5 @@ { - "menuSection": "Исполнительные устройства", - + "menuSection": "executive_devices", "configItem": [ { "global": 0, @@ -73,7 +72,6 @@ "outside_id": "" } ], - "about": { "authorName": "AVAKS", "authorContact": "https://t.me/@avaks_dev", @@ -106,28 +104,34 @@ { "name": "enable", "descr": "включить / выключить термостатирование (режим AUTO) применим к PID и Гистере́зис ", - "params": ["thermostat.enable(1) - вкл, thermostat.enable(0) - выкл, "] + "params": [ + "thermostat.enable(1) - вкл, thermostat.enable(0) - выкл, " + ] }, { "name": "KP", "descr": "Пропорциональный коэффициент PID .", - "params": ["thermostat.KP(1) - задает значение коэффициента"] + "params": [ + "thermostat.KP(1) - задает значение коэффициента" + ] }, { "name": "KI", "descr": "Интегральный коэффициент PID .", - "params": ["thermostat.KI(1) - задает значение коэффициента"] + "params": [ + "thermostat.KI(1) - задает значение коэффициента" + ] }, { "name": "KD", "descr": "Дифференциальный коэффициент PID .", - "params": ["thermostat.KD(1) - задает значение коэффициента"] + "params": [ + "thermostat.KD(1) - задает значение коэффициента" + ] } ] }, - "defActive": false, - "usedLibs": { "esp32_4mb": [], "esp8266_4mb": [], @@ -138,4 +142,4 @@ "esp8266_2mb": [], "esp8266_2mb_ota": [] } -} +} \ No newline at end of file diff --git a/src/modules/sceninfo.json b/src/modules/sceninfo.json index fb472e38..551f6d0e 100644 --- a/src/modules/sceninfo.json +++ b/src/modules/sceninfo.json @@ -69,6 +69,11 @@ "descr": "Отправить значение в топик MQTT", "params": ["Топик", "Значение"] }, + { + "name": "mqttIsConnect", + "descr": "Получить состояние подключения к MQTT", + "params": [] + }, { "name": "getHours", "descr": "Получить текущее число часов. Если время не получено из сети Интернет или внешнего RTC, то условие пропускается", diff --git a/src/modules/sensors/A02Distance/modinfo.json b/src/modules/sensors/A02Distance/modinfo.json index bc6a494a..3ce35fc3 100644 --- a/src/modules/sensors/A02Distance/modinfo.json +++ b/src/modules/sensors/A02Distance/modinfo.json @@ -1,9 +1,9 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "name": "A02 Дальность", - "type": "Reading", + "type": "Reading", "subtype": "A02Distance", "id": "dist", "widget": "anydataCm", @@ -21,10 +21,11 @@ "specialThanks": "", "moduleName": "A02Distance", "moduleVersion": "0.1", - "moduleDesc": "A0221AU, A02YYUW Ультразвуковой датчик. Позволяет получить дальность с ультрозвуковых датчиков A0221AU, A02YYUW", + "moduleDesc": "Позволяет получить дальность с ультрозвуковых датчиков A0221AU, A02YYUW", "propInfo": { "int": "Количество секунд между опросами датчика." - } + }, + "title": "A0221AU, A02YYUW Ультразвуковой датчик дальности" }, "defActive": true, "usedLibs": { diff --git a/src/modules/sensors/Acs712/modinfo.json b/src/modules/sensors/Acs712/modinfo.json index ec03c837..4ee63507 100644 --- a/src/modules/sensors/Acs712/modinfo.json +++ b/src/modules/sensors/Acs712/modinfo.json @@ -1,9 +1,9 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "name": "Acs712 Ток", - "type": "Reading", + "type": "Reading", "subtype": "Acs712", "id": "amp", "widget": "anydataAmp", @@ -13,10 +13,10 @@ "pin": 39, "int": 5, "rms": 1, - "vref": 5000, + "vref": 5000, "sens": 100, - "adczero" : 512, - "btn-setZero": "nil" + "adczero": 512, + "btn-setZero": "nil" } ], "about": { @@ -34,14 +34,15 @@ "rms": "1 - подсчет средне-квадратического тока (переменный), 0 - подсчет средне-арифмитического тока (постоянный)", "vref": "Vref (мВ) - Опороное наряжение питания Acs712, по умолчанию = 5000мВ", "sens": "Чувствительность датчика тока: 5A = 185mВ/A , 20A = 100mВ/A , 30A = 66mВ/A ", - "adczero" : "Переменная калибровки нулевого значения отсчетов АЦП при нулевой нагрузке. Для ESP8266 - 512, Для ESP32 -2048, это 2.5В = 0А (1,65 с делителем) для Acs712 20A и 30A при стабильном токе 5В", - "btn-setZero": "Кнопка калибровки нулевого значения отсчетов АЦП при нулевой нагрузке. Нагрузка в момент калибровки должна быть отключена! После перезагрузки будет установлено в значение по умолчанию adczero. Для сохранение смотрим лог, и изменияем adczero" - } + "adczero": "Переменная калибровки нулевого значения отсчетов АЦП при нулевой нагрузке. Для ESP8266 - 512, Для ESP32 -2048, это 2.5В = 0А (1,65 с делителем) для Acs712 20A и 30A при стабильном токе 5В", + "btn-setZero": "Кнопка калибровки нулевого значения отсчетов АЦП при нулевой нагрузке. Нагрузка в момент калибровки должна быть отключена! После перезагрузки будет установлено в значение по умолчанию adczero. Для сохранение смотрим лог, и изменияем adczero" + }, + "title": "Acs712 Датчик тока" }, "defActive": true, "usedLibs": { "esp32_4mb": [], - "esp32s2_4mb": [], + "esp32s2_4mb": [], "esp8266_4mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], diff --git a/src/modules/sensors/Ads1115/modinfo.json b/src/modules/sensors/Ads1115/modinfo.json index 6395fbff..d859db77 100644 --- a/src/modules/sensors/Ads1115/modinfo.json +++ b/src/modules/sensors/Ads1115/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/AhtXX/modinfo.json b/src/modules/sensors/AhtXX/modinfo.json index 7b180bec..ef05d3a7 100644 --- a/src/modules/sensors/AhtXX/modinfo.json +++ b/src/modules/sensors/AhtXX/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, @@ -12,7 +12,7 @@ "descr": "AHTXX Температура", "int": 15, "addr": "0x38", - "shtType":1, + "shtType": 1, "round": 1 }, { @@ -26,7 +26,7 @@ "descr": "AHTXX Влажность", "int": 15, "addr": "0x38", - "shtType":1, + "shtType": 1, "round": 1 } ], @@ -61,6 +61,18 @@ ], "esp8266_4mb": [ "https://github.com/enjoyneering/AHTxx.git" + ], + "esp8266_1mb": [ + "https://github.com/enjoyneering/AHTxx.git" + ], + "esp8266_1mb_ota": [ + "https://github.com/enjoyneering/AHTxx.git" + ], + "esp8285_1mb": [ + "https://github.com/enjoyneering/AHTxx.git" + ], + "esp8285_1mb_ota": [ + "https://github.com/enjoyneering/AHTxx.git" ] } } \ No newline at end of file diff --git a/src/modules/sensors/AnalogAdc/modinfo.json b/src/modules/sensors/AnalogAdc/modinfo.json index a9a55c17..a28e901a 100644 --- a/src/modules/sensors/AnalogAdc/modinfo.json +++ b/src/modules/sensors/AnalogAdc/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/BH_1750/modinfo.json b/src/modules/sensors/BH_1750/modinfo.json index 832e4c5c..0843f2e7 100644 --- a/src/modules/sensors/BH_1750/modinfo.json +++ b/src/modules/sensors/BH_1750/modinfo.json @@ -1,19 +1,19 @@ -{ - "menuSection": "Сенсоры", - - "configItem": [{ - "global": 0, - "name": "Cенсор освещенность Bh1750", - "type": "Reading", - "subtype": "Bh1750", - "id": "Bh1750", - "widget": "anydata", - "page": "Сенсоры", - "descr": "Освещённость", - "round": 1, - "int": 15 - }], - +{ + "menuSection": "sensors", + "configItem": [ + { + "global": 0, + "name": "Cенсор освещенность Bh1750", + "type": "Reading", + "subtype": "Bh1750", + "id": "Bh1750", + "widget": "anydata", + "page": "Сенсоры", + "descr": "Освещённость", + "round": 1, + "int": 15 + } + ], "about": { "authorName": "Ilya Belyakov", "authorContact": "https://t.me/Biveraxe", diff --git a/src/modules/sensors/Ble/modinfo.json b/src/modules/sensors/Ble/modinfo.json index fda2ea7a..0a231625 100644 --- a/src/modules/sensors/Ble/modinfo.json +++ b/src/modules/sensors/Ble/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "name": "bluetooth сканер", @@ -42,7 +42,10 @@ "esp32_4mb": 1261449, "esp8266_4mb": 0 }, - "subTypes": ["BleSens", "BleScan"], + "subTypes": [ + "BleSens", + "BleScan" + ], "title": "Сканер Bluetooth", "moduleDesc": "Позволяет получить данные с Bluetooth часов и термометров Mijia, Xiaomi, Cleargrass, ...", "propInfo": { @@ -61,4 +64,4 @@ "https://github.com/avaksru/decoder.git" ] } -} +} \ No newline at end of file diff --git a/src/modules/sensors/Bme280/modinfo.json b/src/modules/sensors/Bme280/modinfo.json index 5bb6f9b2..4f11d152 100644 --- a/src/modules/sensors/Bme280/modinfo.json +++ b/src/modules/sensors/Bme280/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Bmp280/modinfo.json b/src/modules/sensors/Bmp280/modinfo.json index ddbf7079..608d5c18 100644 --- a/src/modules/sensors/Bmp280/modinfo.json +++ b/src/modules/sensors/Bmp280/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/DS2401/modinfo.json b/src/modules/sensors/DS2401/modinfo.json index 8364b4f0..a7db4500 100644 --- a/src/modules/sensors/DS2401/modinfo.json +++ b/src/modules/sensors/DS2401/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Dht1122/modinfo.json b/src/modules/sensors/Dht1122/modinfo.json index 7e5dc5be..604c0a2c 100644 --- a/src/modules/sensors/Dht1122/modinfo.json +++ b/src/modules/sensors/Dht1122/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Ds18b20/modinfo.json b/src/modules/sensors/Ds18b20/modinfo.json index 9a4519a4..a5423121 100644 --- a/src/modules/sensors/Ds18b20/modinfo.json +++ b/src/modules/sensors/Ds18b20/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Ds2423/modinfo.json b/src/modules/sensors/Ds2423/modinfo.json index e5cd9f75..866af40a 100644 --- a/src/modules/sensors/Ds2423/modinfo.json +++ b/src/modules/sensors/Ds2423/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "executive_devices", "configItem": [ { "global": 0, @@ -14,7 +14,7 @@ "multiply": 1, "pin": 4, "index": 0, - "addr": "", + "addr": "", "int": 10, "round": 0, "needSave": 0 diff --git a/src/modules/sensors/Emon/modinfo.json b/src/modules/sensors/Emon/modinfo.json index e254359f..03b1f832 100644 --- a/src/modules/sensors/Emon/modinfo.json +++ b/src/modules/sensors/Emon/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/ExampleModule/ExampleModule.cpp b/src/modules/sensors/ExampleModule/ExampleModule.cpp index 871fe1e7..15fedb1f 100644 --- a/src/modules/sensors/ExampleModule/ExampleModule.cpp +++ b/src/modules/sensors/ExampleModule/ExampleModule.cpp @@ -7,16 +7,16 @@ #include "Global.h" #include "classes/IoTItem.h" -//!Здесь подключаем стороннюю библиотеку при необходимости (ExternalLibrary заменить) -//#include -#include "ExternalLibrary.h" //удалить, только для примера. Внешние библиотеки правильно в <> +//! Здесь подключаем стороннюю библиотеку при необходимости (ExternalLibrary заменить) +// #include +#include "ExternalLibrary.h" //удалить, только для примера. Внешние библиотеки правильно в <> -//! Объяевляем класс IoTGpio для работы с GPIO +//! Объяевляем класс IoTGpio для работы с GPIO extern IoTGpio IoTgpio; //========================================================================================================= //========================================================================================================= -// Объявление сторонней библиотекит с использованием глобавльных объектов +// Объявление сторонней библиотекит с использованием глобавльных объектов //======================================================================================================= //! Объявляем стороннюю библиотеку при необходимости (ExternalLibrary заменить) // !!! ЗДЕСЬ И ДАЛЕЕ libXX НАЗВАТЬ уникальным именем) @@ -25,9 +25,15 @@ ExternalLibrary *libXX = nullptr; // Функция инициализации библиотечного класса, возвращает Единстрвенный указать на библиотеку // instanceLibXX НАЗВАТЬ по наименованию модуля (instanceДатчикХ) // ПРИ НЕОБХДИМОСТИ передаем любые нужные параметры для инициализации библиотеки (в данном случае PIN) -// !!! ВЫзвать данную функцию нужно хотябы один раз, +// +// !!! ВЫзвать данную функцию нужно хотябы один раз, // но в каждом конструкторе класса модуля ExampleModule_A, ExampleModule_B и т.д. // или можно вывывать постоянно при обращении к библиотеке, типа: instanceLibXX().READ_LIB_DATA_OTHER(); +// +// !!!!!! В деструкторах ~ExampleModule_B() и ~ExampleModule_A() надо УДАЛЯТЬ объект libXX, ЕСЛИ в функцию instanceLibXX чтото передается. +// Удаляем класс библиотеки, а то при переконфигурации в нем не поменяются PIN и дугие параметры передаваемые в библиотеку. +// P.S. Не для всех, если используется map или vector то лучше не надо. + ExternalLibrary *instanceLibXX(int pin) { if (!libXX) @@ -39,7 +45,6 @@ ExternalLibrary *instanceLibXX(int pin) return libXX; } - //========================================================================================================= //========================================================================================================= // Первый класс модуля для определения 1-го элемента (параметра) @@ -69,7 +74,7 @@ public: // jsonReadStr, jsonReadBool, jsonReadInt ExampleModule_A(String parameters) : IoTItem(parameters) { - //Читаем пользовательскую переменную PIN, должна быть объявлена в в modeinfo.json + // Читаем пользовательскую переменную PIN, должна быть объявлена в в modeinfo.json _pin = jsonReadInt(parameters, "pin"); // другой вариант чтения парметров модуля jsonRead(parameters, F("int"), _interval, false); @@ -111,7 +116,12 @@ public: } } - ~ExampleModule_A(){}; + ~ExampleModule_A() + { + // Удаляем класс библиотеки, а то при переконфигурации в нем не поменяются PIN и дугие параметры передаваемые в библиотеку. + delete libXX; + libXX = nullptr; + }; }; //========================================================================================================= @@ -126,14 +136,15 @@ public: class ExampleModule_B : public IoTItem { private: -//Пользовательские переменные + // Пользовательские переменные unsigned int _pin; + public: ExampleModule_B(String parameters) : IoTItem(parameters) { - //Читаем пользовательскую переменную PIN, должна быть объявлена в в modeinfo.json + // Читаем пользовательскую переменную PIN, должна быть объявлена в в modeinfo.json _pin = jsonReadInt(parameters, "pin"); - //Можно инициализировать библиотеку один раз, а потом используем указатель + // Можно инициализировать библиотеку один раз, а потом используем указатель instanceLibXX(_pin); libXX->READ_LIB_DATA_OTHER(); } @@ -146,7 +157,7 @@ public: regEvent(value.valD, "ExampleModule"); // обязательный вызов хотяб один для регистрации события в ядре IoTM } -//================ обработка кнопок из конфигурации =================== + //================ обработка кнопок из конфигурации =================== // Хук (переопределение виртуальной функции) для обработки кнопки (в value будут данные с собственной панели ввода) // Что бы кнопка была без поля ввода, нужно в modeinfo.json указать "btn-Example": nil void onModuleOrder(String &key, String &value) @@ -158,7 +169,7 @@ public: } } -//================ обработка команд из сценария=================== + //================ обработка команд из сценария=================== // Хук (переопределение виртуальной функции) для обработки команды из сценария (в param будут даныые переданные в функции в сценарии) IoTValue execute(String command, std::vector ¶m) { @@ -204,10 +215,14 @@ public: // Прсото пример кокой-то функции } - ~ExampleModule_B(){}; + ~ExampleModule_B() + { + // Удаляем класс библиотеки, а то при переконфигурации в нем не поменяются PIN и дугие параметры передаваемые в библиотеку. + delete libXX; + libXX = nullptr; + }; }; - //========================================================================================================= //========================================================================================================= // Функция для связи модуля с ядром IoTM diff --git a/src/modules/sensors/ExampleModule/modinfo.json b/src/modules/sensors/ExampleModule/modinfo.json index 083b37a3..e605d2fa 100644 --- a/src/modules/sensors/ExampleModule/modinfo.json +++ b/src/modules/sensors/ExampleModule/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, @@ -24,9 +24,9 @@ "page": "Сенсоры", "descr": "Давление", "int": 15, - "pin": "32", + "pin": "32", "round": 1, - "btn-Example": 100 + "btn-Example": 100 } ], "about": { @@ -46,31 +46,37 @@ "propInfo": { "pin": "Аналоговый GPIO номер, к которому подключен датчик.", "int": "Количество секунд между опросами датчика", - "btn-Example": "Кнопка Example. В поле указать ......" + "btn-Example": "Кнопка Example. В поле указать ......" }, "funcInfo": [ { "name": "expampleFunc", "descr": "Пример функции вызываемой из сценария. Принимает Id другого модуля и смотрит его значение", - "params": ["ID стороннего модуля"] + "params": [ + "ID стороннего модуля" + ] }, { "name": "expample2", "descr": "Второй Пример функции вызываемой из сценария.", - "params": ["Описание педедаваемого параметра", - "параметр 2"] + "params": [ + "Описание педедаваемого параметра", + "параметр 2" + ] }, { "name": "expampleAny", "descr": "Третий Пример функции вызываемой из сценария. С неограниченным числом параметров", - "params": ["Описание педедаваемых параметров"] + "params": [ + "Описание педедаваемых параметров" + ] } - ] + ] }, "defActive": false, "usedLibs": { "esp32_4mb": [], - "esp32s2_4mb": [], + "esp32s2_4mb": [], "esp8266_4mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], diff --git a/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp b/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp index 3ad82a54..91da0b9c 100644 --- a/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp +++ b/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp @@ -13,16 +13,24 @@ private: int red = 0; int offline = 0; bool dataFromNode = false; + String _topic = ""; + bool _isJson; + bool _addPrefix; + bool _debug; public: ExternalMQTT(String parameters) : IoTItem(parameters) { - _MAC = jsonReadStr(parameters, "MAC"); _sensor = jsonReadStr(parameters, "sensor"); jsonRead(parameters, F("orange"), orange); jsonRead(parameters, F("red"), red); jsonRead(parameters, F("offline"), offline); + _topic = jsonReadStr(parameters, "topic"); + _isJson = jsonReadBool(parameters, "isJson"); + _addPrefix = jsonReadBool(parameters, "addPrefix"); + _debug = jsonReadBool(parameters, "debug"); dataFromNode = false; + mqttSubscribeExternal(_topic, _addPrefix); } char *TimeToString(unsigned long t) { @@ -38,38 +46,58 @@ public: { if (msg.indexOf("HELLO") == -1) { - - // SerialPrint("i", "onMqttRecive", "Прилетело " + topic); - // SerialPrint("i", "onMqttRecive", "Прилетело " + msg); + if (_debug) + { + SerialPrint("i", "onMqttRecive", "Прилетело " + topic + " msg: " + msg); + // SerialPrint("i", "onMqttRecive", "Прилетело " + msg); + } String dev = selectToMarkerLast(topic, "/"); dev.toUpperCase(); dev.replace(":", ""); - if (_MAC == "") + if (_topic != topic) { - SerialPrint("i", "onMqttRecive", dev + " --> " + msg); + return; } - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, msg); - if (error) + if (_isJson) { - SerialPrint("E", F("onMqttRecive"), error.f_str()); - } - JsonObject jsonObject = doc.as(); - - for (JsonPair kv : jsonObject) - { - String key = kv.key().c_str(); - String val = kv.value(); - if (_MAC == dev && _sensor == key) + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, msg); + if (error) { - dataFromNode = true; - _minutesPassed = 0; - setValue(val); - // setNewWidgetAttributes(); + SerialPrint("E", F("onMqttRecive"), error.f_str()); } + JsonObject jsonObject = doc.as(); - // Serial.println("Key: " + key); - // Serial.println("Value: " + val); + for (JsonPair kv : jsonObject) + { + String key = kv.key().c_str(); + String val = kv.value(); + if (_debug) + { + SerialPrint("i", "onMqttRecive", "Прилетело MAC: " + dev + " key=" + key + " val=" + val); + } + if (_sensor == key) + { + dataFromNode = true; + _minutesPassed = 0; + setValue(val); + // setNewWidgetAttributes(); + } + + // Serial.println("Key: " + key); + // Serial.println("Value: " + val); + } + } + else + { + if (_debug) + { + SerialPrint("i", "onMqttRecive", "Прилетело MAC: " + dev + " val=" + msg); + } + dataFromNode = true; + _minutesPassed = 0; + setValue(msg); + // setNewWidgetAttributes(); } } } @@ -116,7 +144,22 @@ public: } sendSubWidgetsValues(_id, json); } - + /* + IoTValue execute(String command, std::vector ¶m) + { + if (command == "mqttSubscribe") + { + if (param.size() == 2) + { + if (!param[0].isDecimal && param[1].isDecimal) + { + mqttSubscribeExternal(param[0].valS, (bool)param[0].valD); + } + } + } + return {}; + } + */ ~ExternalMQTT(){}; }; diff --git a/src/modules/sensors/ExternalMQTT/modinfo.json b/src/modules/sensors/ExternalMQTT/modinfo.json index 02c41fb3..70825798 100644 --- a/src/modules/sensors/ExternalMQTT/modinfo.json +++ b/src/modules/sensors/ExternalMQTT/modinfo.json @@ -1,6 +1,5 @@ { - "menuSection": "Сенсоры", - + "menuSection": "sensors", "configItem": [ { "global": 0, @@ -11,23 +10,25 @@ "widget": "", "page": "", "descr": "", - "MAC": "", "sensor": "", + "topic": "", + "addPrefix": 0, + "isJson": 1, "round": "", "orange": 60, "red": 120, "offline": 180, - "int": 60 + "int": 60, + "debug": 0 } ], - "about": { "authorName": "AVAKS", "authorContact": "https://t.me/@avaks_dev", "authorGit": "https://github.com/avaksru", "specialThanks": "", "moduleName": "ExternalMQTT", - "moduleVersion": "1", + "moduleVersion": "1.2", "usedRam": { "esp32_4mb": 15, "esp8266_4mb": 15 @@ -40,15 +41,18 @@ "orange": "количество минут после которого окрасить виджет в оранжевый цвет", "red": "количество минут после которого окрасить виджет в красный цвет", "offline": "количество минут после которого отобразить что устройство offline, если все три orange red и offline поставить в ноль - то функция окраски выключится", - "MAC": "MAC адрес беспроводного датчика", - "sensor": "Тип сенсора: температура / влажность / время / ... " + "sensor": "Тип сенсора: температура / влажность / время / ... Он же ключ в json пакете ", + "topic":"Подписаться на произвольный топик (полный путь), в модуле данный топик буде проверяться с отправителем, например homed/fd/zigbee/temp", + "addPrefix":"1 (число), будет добавлен стандартный префикс из настроек, 0 - не добавлять префикс", + "isJson":"1 - ожидаем в топике json, 0 - в топике просто значение (при 0 поле sensor заполнять не требуется)", + "debug":"1 - выводить дополнительный лог в сериал" } + }, - "defActive": false, - "usedLibs": { "esp32_4mb": [], + "esp32s2_4mb": [], "esp8266_4mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], @@ -57,4 +61,4 @@ "esp8266_2mb": [], "esp8266_2mb_ota": [] } -} +} \ No newline at end of file diff --git a/src/modules/sensors/FreqMeter/modinfo.json b/src/modules/sensors/FreqMeter/modinfo.json index 91eb8c82..b1680a47 100644 --- a/src/modules/sensors/FreqMeter/modinfo.json +++ b/src/modules/sensors/FreqMeter/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/GY21/modinfo.json b/src/modules/sensors/GY21/modinfo.json index affd1e44..12928240 100644 --- a/src/modules/sensors/GY21/modinfo.json +++ b/src/modules/sensors/GY21/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Hdc1080/modinfo.json b/src/modules/sensors/Hdc1080/modinfo.json index 5b27c795..b9154665 100644 --- a/src/modules/sensors/Hdc1080/modinfo.json +++ b/src/modules/sensors/Hdc1080/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Hx710/modinfo.json b/src/modules/sensors/Hx710/modinfo.json index 985c4457..c6a9ca16 100644 --- a/src/modules/sensors/Hx710/modinfo.json +++ b/src/modules/sensors/Hx710/modinfo.json @@ -1,22 +1,22 @@ -{ - "menuSection": "Сенсоры", - - "configItem": [{ - "name": "HX710 Cенсор давления", - "type": "Reading", - "subtype": "Hx710", - "id": "hxp", - "widget": "anydataDef", - "page": "Давление", - "descr": "HX press", - "int": 15, - "plus": 0, - "multiply": 1, - "round": 1, - "data": 14, - "clock": 15 - }], - +{ + "menuSection": "sensors", + "configItem": [ + { + "name": "HX710 Cенсор давления", + "type": "Reading", + "subtype": "Hx710", + "id": "hxp", + "widget": "anydataDef", + "page": "Давление", + "descr": "HX press", + "int": 15, + "plus": 0, + "multiply": 1, + "round": 1, + "data": 14, + "clock": 15 + } + ], "about": { "authorName": "Serghei Crasnicov", "authorContact": "https://t.me/Serghei63", @@ -44,9 +44,7 @@ } ] }, - "defActive": false, - "usedLibs": { "esp32_4mb": [ "https://github.com/kurimawxx00/hx710B_pressure_sensor" diff --git a/src/modules/sensors/Hx711/modinfo.json b/src/modules/sensors/Hx711/modinfo.json index 4627711a..43e4b7fd 100644 --- a/src/modules/sensors/Hx711/modinfo.json +++ b/src/modules/sensors/Hx711/modinfo.json @@ -1,24 +1,24 @@ -{ - "menuSection": "Сенсоры", - - "configItem": [{ - "name": "HX711 Cенсор весов", - "type": "Reading", - "subtype": "Hx711", - "id": "hx", - "widget": "anydataDef", - "page": "Весы", - "descr": "HX вес", - "int": 15, - "map": "1024,1024,1,100", - "plus": 0, - "multiply": 1, - "round": 1, - "data": 3, - "clock": 2, - "chan": 2 - }], - +{ + "menuSection": "sensors", + "configItem": [ + { + "name": "HX711 Cенсор весов", + "type": "Reading", + "subtype": "Hx711", + "id": "hx", + "widget": "anydataDef", + "page": "Весы", + "descr": "HX вес", + "int": 15, + "map": "1024,1024,1,100", + "plus": 0, + "multiply": 1, + "round": 1, + "data": 3, + "clock": 2, + "chan": 2 + } + ], "about": { "authorName": "Serghei Crasnicov", "authorContact": "https://t.me/Serghei63", @@ -48,7 +48,9 @@ { "name": "sleepMode", "descr": "Перевести в режим сна", - "params": ["=1 режим сна, =0 проснуться"] + "params": [ + "=1 режим сна, =0 проснуться" + ] }, { "name": "read", @@ -57,9 +59,7 @@ } ] }, - "defActive": false, - "usedLibs": { "esp32_4mb": [ "GyverHX711@1.2" diff --git a/src/modules/sensors/Impulse/modinfo.json b/src/modules/sensors/Impulse/modinfo.json index e35ecf29..ee92191f 100644 --- a/src/modules/sensors/Impulse/modinfo.json +++ b/src/modules/sensors/Impulse/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Ina219/modinfo.json b/src/modules/sensors/Ina219/modinfo.json index c89e95b2..7e35d23e 100644 --- a/src/modules/sensors/Ina219/modinfo.json +++ b/src/modules/sensors/Ina219/modinfo.json @@ -1,139 +1,135 @@ { - "menuSection": "Сенсоры", - - "configItem": [{ - "global": 0, - "name": "INA219 Tок", - "type": "Reading", - "subtype": "Ina219curr", - "id": "ina219_A", - "widget": "anydataAmp", - "page": "INA 219", - "descr": "Сила тока", - "addr": "0x40", - "plus": 0, - "multiply": 1, - "round": 3, - "int": 10 - }, - { - "global": 0, - "name": "INA219 Напряжение", - "type": "Reading", - "subtype": "Ina219voltage", - "id": "ina219_V", - "widget": "anydataVlt", - "page": "INA 219", - "descr": "Напряжения", - "addr": "0x40", - "plus": 0, - "multiply": 1, - "round": 3, - "int": 10 - }, - { - "global": 0, - "name": "INA219 Мощность", - "type": "Reading", - "subtype": "Ina219power", - "id": "ina219_W", - "widget": "anydataWt", - "page": "INA 219", - "descr": "Мощность", - "addr": "0x40", - "plus": 0, - "multiply": 1, - "round": 3, - "int": 10 - }, - { - "global": 0, - "name": "INA219 Шунт", - "type": "Reading", - "subtype": "Ina219shuntvoltage", - "id": "ina219_Vsh", - "widget": "anydataVlt", - "page": "INA 219", - "descr": "Напряжение шунта", - "addr": "0x40", - "plus": 0, - "multiply": 1, - "round": 3, - "int": 10 - }, - { - "global": 0, - "name": "INA219 Настройки", - "type": "Reading", - "subtype": "Ina219setting", - "id": "ina219_set", - "widget": "nil", - "page": "", - "descr": "", - "addr": "0x40", - "shunt": 0.1, - "maxV": 3.2, - "adjClbr": 0, - "resol": 4, - "btn-getClbr":"nil" - }], - - "about": { - "authorName": "Serghei Crasnicov", - "authorContact": "https://t.me/Serghei63", - "authorGit": "https://github.com/Serghei63", - "specialThanks": "Дмитрий, Serg, v2.0 - Mitchel @Mit4bmw", - "moduleName": "Ina219", - "moduleVersion": "2.0", - "usedRam": { - "esp32_4mb": 15, - "esp8266_4mb": 15 - }, - "subTypes": [ - "Ina219curr", - "Ina219voltage", - "Ina219power", - "Ina219shuntvoltage", - "Ina219setting" - ], - "title": "Милливатметр постоянного тока", - "moduleDesc": "Измеряет постоянный ток до 3.2 ампера, напряжение до 26 вольт и мощность на нагрузке. Модуль INA219 Настройки - для изменении настроек нужен постоянно в конфигурации, должен стоять перед рдугими модулями с тем же адресом, без него работает на значенях по умолчанию", - "propInfo": { - "int": "Количество секунд между опросами датчика.", - "addr": "Адрес датчика на шине, обычно 0x40. Если оставить поле пустым, то запуститься сканер I2C и подключение к адресу 0x40", - "shunt": "Сопротивление шунта, штатно 0.1Ом. Изменить если его перепаяли", - "maxV": "Максимальный ожидаемый ток, штатно 3.2А, для указаного шунта", - "adjClbr": "Задать смещение (подкрутить) калибровочное значение на указанное значение. -20 = Уменьшить калибровочное значение на 20", - "resol": "Установка режима усреднения для измерения напряжения и тока, рекомендуется для повышения стабильности показаний на шумной нагрузке. Варианты 1(без усреднения),2,4,8,16,32,64,128", - "btn-getClbr": "Кнопка запроса текущей калибровки, выводится в лог" - }, - "funcInfo": [ - { - "name": "sleep", - "descr": "INA219 Настройки. Установка / снятие режима сна датчика INA219", - "params": ["1- вкл сна/ 0-выкл сна"] - } - ] + "menuSection": "sensors", + "configItem": [ + { + "global": 0, + "name": "INA219 Tок", + "type": "Reading", + "subtype": "Ina219curr", + "id": "ina219_A", + "widget": "anydataAmp", + "page": "INA 219", + "descr": "Сила тока", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 }, - - "defActive": false, - - "usedLibs": { - "esp32_4mb": [ - "https://github.com/GyverLibs/GyverINA" - ], - "esp32s2_4mb": [ - "https://github.com/GyverLibs/GyverINA" - ], - - "esp8266_4mb": [ - "https://github.com/GyverLibs/GyverINA" - ], - "esp8266_16mb": [ - "https://github.com/GyverLibs/GyverINA" - ] + { + "global": 0, + "name": "INA219 Напряжение", + "type": "Reading", + "subtype": "Ina219voltage", + "id": "ina219_V", + "widget": "anydataVlt", + "page": "INA 219", + "descr": "Напряжения", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 + }, + { + "global": 0, + "name": "INA219 Мощность", + "type": "Reading", + "subtype": "Ina219power", + "id": "ina219_W", + "widget": "anydataWt", + "page": "INA 219", + "descr": "Мощность", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 + }, + { + "global": 0, + "name": "INA219 Шунт", + "type": "Reading", + "subtype": "Ina219shuntvoltage", + "id": "ina219_Vsh", + "widget": "anydataVlt", + "page": "INA 219", + "descr": "Напряжение шунта", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 + }, + { + "global": 0, + "name": "INA219 Настройки", + "type": "Reading", + "subtype": "Ina219setting", + "id": "ina219_set", + "widget": "nil", + "page": "", + "descr": "", + "addr": "0x40", + "shunt": 0.1, + "maxV": 3.2, + "adjClbr": 0, + "resol": 4, + "btn-getClbr": "nil" } - - } - - \ No newline at end of file + ], + "about": { + "authorName": "Serghei Crasnicov", + "authorContact": "https://t.me/Serghei63", + "authorGit": "https://github.com/Serghei63", + "specialThanks": "Дмитрий, Serg, v2.0 - Mitchel @Mit4bmw", + "moduleName": "Ina219", + "moduleVersion": "2.0", + "usedRam": { + "esp32_4mb": 15, + "esp8266_4mb": 15 + }, + "subTypes": [ + "Ina219curr", + "Ina219voltage", + "Ina219power", + "Ina219shuntvoltage", + "Ina219setting" + ], + "title": "Милливатметр постоянного тока", + "moduleDesc": "Измеряет постоянный ток до 3.2 ампера, напряжение до 26 вольт и мощность на нагрузке. Модуль INA219 Настройки - для изменении настроек нужен постоянно в конфигурации, должен стоять перед рдугими модулями с тем же адресом, без него работает на значенях по умолчанию", + "propInfo": { + "int": "Количество секунд между опросами датчика.", + "addr": "Адрес датчика на шине, обычно 0x40. Если оставить поле пустым, то запуститься сканер I2C и подключение к адресу 0x40", + "shunt": "Сопротивление шунта, штатно 0.1Ом. Изменить если его перепаяли", + "maxV": "Максимальный ожидаемый ток, штатно 3.2А, для указаного шунта", + "adjClbr": "Задать смещение (подкрутить) калибровочное значение на указанное значение. -20 = Уменьшить калибровочное значение на 20", + "resol": "Установка режима усреднения для измерения напряжения и тока, рекомендуется для повышения стабильности показаний на шумной нагрузке. Варианты 1(без усреднения),2,4,8,16,32,64,128", + "btn-getClbr": "Кнопка запроса текущей калибровки, выводится в лог" + }, + "funcInfo": [ + { + "name": "sleep", + "descr": "INA219 Настройки. Установка / снятие режима сна датчика INA219", + "params": [ + "1- вкл сна/ 0-выкл сна" + ] + } + ] + }, + "defActive": false, + "usedLibs": { + "esp32_4mb": [ + "https://github.com/GyverLibs/GyverINA" + ], + "esp32s2_4mb": [ + "https://github.com/GyverLibs/GyverINA" + ], + "esp8266_4mb": [ + "https://github.com/GyverLibs/GyverINA" + ], + "esp8266_16mb": [ + "https://github.com/GyverLibs/GyverINA" + ] + } +} \ No newline at end of file diff --git a/src/modules/sensors/Ina226/modinfo.json b/src/modules/sensors/Ina226/modinfo.json index a2f00e1c..98b68d5e 100644 --- a/src/modules/sensors/Ina226/modinfo.json +++ b/src/modules/sensors/Ina226/modinfo.json @@ -1,139 +1,135 @@ { - "menuSection": "Сенсоры", - - "configItem": [{ - "global": 0, - "name": "INA226 Tок", - "type": "Reading", - "subtype": "Ina226curr", - "id": "ina226_A", - "widget": "anydataAmp", - "page": "INA 226", - "descr": "Сила тока", - "addr": "0x40", - "plus": 0, - "multiply": 1, - "round": 3, - "int": 10 - }, - { - "global": 0, - "name": "INA226 Напряжение", - "type": "Reading", - "subtype": "Ina226voltage", - "id": "ina226_V", - "widget": "anydataVlt", - "page": "INA 226", - "descr": "Напряжения", - "addr": "0x40", - "plus": 0, - "multiply": 1, - "round": 3, - "int": 10 - }, - { - "global": 0, - "name": "INA226 Мощность", - "type": "Reading", - "subtype": "Ina226power", - "id": "ina226_W", - "widget": "anydataWt", - "page": "INA 226", - "descr": "Мощность", - "addr": "0x40", - "plus": 0, - "multiply": 1, - "round": 3, - "int": 10 - }, - { - "global": 0, - "name": "INA226 Шунт", - "type": "Reading", - "subtype": "Ina226shuntvoltage", - "id": "ina226_Vsh", - "widget": "anydataVlt", - "page": "INA 226", - "descr": "Напряжение шунта", - "addr": "0x40", - "plus": 0, - "multiply": 1, - "round": 3, - "int": 10 - }, - { - "global": 0, - "name": "INA226 Настройки", - "type": "Reading", - "subtype": "Ina226setting", - "id": "ina226_set", - "widget": "nil", - "page": "", - "descr": "", - "addr": "0x40", - "shunt": 0.1, - "maxV": 3.2, - "adjClbr": 0, - "resol": 4, - "btn-getClbr":"nil" - }], - - "about": { - "authorName": "Serghei Crasnicov", - "authorContact": "https://t.me/Serghei63", - "authorGit": "https://github.com/Serghei63", - "specialThanks": "v2.0 - Mitchel @Mit4bmw", - "moduleName": "Ina226", - "moduleVersion": "2.0", - "usedRam": { - "esp32_4mb": 15, - "esp8266_4mb": 15 - }, - "subTypes": [ - "Ina226curr", - "Ina226voltage", - "Ina226power", - "Ina226shuntvoltage", - "Ina226setting" - ], - "title": "Милливатметр постоянного тока", - "moduleDesc": "Стандартные значения для модуля INA226 (Сопротивление шунта - 0.1 Ом, Максимальный ожидаемый ток - 0.8 А, Адрес на шине I2c - 0x40). Модуль INA226 Настройки - для изменении настроек нужен постоянно в конфигурации, должен стоять перед рдугими модулями с тем же адресом, без него работает на значенях по умолчанию", - "propInfo": { - "int": "Количество секунд между опросами датчика.", - "addr": "Адрес датчика на шине, обычно 0x40. Если оставить поле пустым, то запуститься сканер I2C и подключение к адресу 0x40", - "shunt": "Сопротивление шунта, штатно 0.1Ом. Изменить если его перепаяли", - "maxV": "Максимальный ожидаемый ток, штатно 0.8А, для указаного шунта", - "adjClbr": "Задать смещение (подкрутить) калибровочное значение на указанное значение. -20 = Уменьшить калибровочное значение на 20", - "resol": "Установка режима усреднения (колическва замеров) для измерения напряжения и тока, рекомендуется для повышения стабильности показаний на шумной нагрузке. Пропорционально увеличивает время оцифровки. Варианты 0(без усреднения), от 1 до 7 - соответстввует 4,16,64,128,256,512,1024", - "btn-getClbr": "Кнопка запроса текущей калибровки, выводится в лог" - }, - "funcInfo": [ - { - "name": "sleep", - "descr": "INA226 Настройки. Установка / снятие режима сна датчика INA226", - "params": ["1- вкл сна/ 0-выкл сна"] - } - ] + "menuSection": "sensors", + "configItem": [ + { + "global": 0, + "name": "INA226 Tок", + "type": "Reading", + "subtype": "Ina226curr", + "id": "ina226_A", + "widget": "anydataAmp", + "page": "INA 226", + "descr": "Сила тока", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 }, - - "defActive": false, - - "usedLibs": { - "esp32_4mb": [ - "https://github.com/GyverLibs/GyverINA" - ], - "esp32s2_4mb": [ - "https://github.com/GyverLibs/GyverINA" - ], - - "esp8266_4mb": [ - "https://github.com/GyverLibs/GyverINA" - ], - "esp8266_16mb": [ - "https://github.com/GyverLibs/GyverINA" - ] + { + "global": 0, + "name": "INA226 Напряжение", + "type": "Reading", + "subtype": "Ina226voltage", + "id": "ina226_V", + "widget": "anydataVlt", + "page": "INA 226", + "descr": "Напряжения", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 + }, + { + "global": 0, + "name": "INA226 Мощность", + "type": "Reading", + "subtype": "Ina226power", + "id": "ina226_W", + "widget": "anydataWt", + "page": "INA 226", + "descr": "Мощность", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 + }, + { + "global": 0, + "name": "INA226 Шунт", + "type": "Reading", + "subtype": "Ina226shuntvoltage", + "id": "ina226_Vsh", + "widget": "anydataVlt", + "page": "INA 226", + "descr": "Напряжение шунта", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 + }, + { + "global": 0, + "name": "INA226 Настройки", + "type": "Reading", + "subtype": "Ina226setting", + "id": "ina226_set", + "widget": "nil", + "page": "", + "descr": "", + "addr": "0x40", + "shunt": 0.1, + "maxV": 3.2, + "adjClbr": 0, + "resol": 4, + "btn-getClbr": "nil" } - - } - - \ No newline at end of file + ], + "about": { + "authorName": "Serghei Crasnicov", + "authorContact": "https://t.me/Serghei63", + "authorGit": "https://github.com/Serghei63", + "specialThanks": "v2.0 - Mitchel @Mit4bmw", + "moduleName": "Ina226", + "moduleVersion": "2.0", + "usedRam": { + "esp32_4mb": 15, + "esp8266_4mb": 15 + }, + "subTypes": [ + "Ina226curr", + "Ina226voltage", + "Ina226power", + "Ina226shuntvoltage", + "Ina226setting" + ], + "title": "Милливатметр постоянного тока", + "moduleDesc": "Стандартные значения для модуля INA226 (Сопротивление шунта - 0.1 Ом, Максимальный ожидаемый ток - 0.8 А, Адрес на шине I2c - 0x40). Модуль INA226 Настройки - для изменении настроек нужен постоянно в конфигурации, должен стоять перед рдугими модулями с тем же адресом, без него работает на значенях по умолчанию", + "propInfo": { + "int": "Количество секунд между опросами датчика.", + "addr": "Адрес датчика на шине, обычно 0x40. Если оставить поле пустым, то запуститься сканер I2C и подключение к адресу 0x40", + "shunt": "Сопротивление шунта, штатно 0.1Ом. Изменить если его перепаяли", + "maxV": "Максимальный ожидаемый ток, штатно 0.8А, для указаного шунта", + "adjClbr": "Задать смещение (подкрутить) калибровочное значение на указанное значение. -20 = Уменьшить калибровочное значение на 20", + "resol": "Установка режима усреднения (колическва замеров) для измерения напряжения и тока, рекомендуется для повышения стабильности показаний на шумной нагрузке. Пропорционально увеличивает время оцифровки. Варианты 0(без усреднения), от 1 до 7 - соответстввует 4,16,64,128,256,512,1024", + "btn-getClbr": "Кнопка запроса текущей калибровки, выводится в лог" + }, + "funcInfo": [ + { + "name": "sleep", + "descr": "INA226 Настройки. Установка / снятие режима сна датчика INA226", + "params": [ + "1- вкл сна/ 0-выкл сна" + ] + } + ] + }, + "defActive": false, + "usedLibs": { + "esp32_4mb": [ + "https://github.com/GyverLibs/GyverINA" + ], + "esp32s2_4mb": [ + "https://github.com/GyverLibs/GyverINA" + ], + "esp8266_4mb": [ + "https://github.com/GyverLibs/GyverINA" + ], + "esp8266_16mb": [ + "https://github.com/GyverLibs/GyverINA" + ] + } +} \ No newline at end of file diff --git a/src/modules/sensors/IoTWiegand/modinfo.json b/src/modules/sensors/IoTWiegand/modinfo.json index ff7457e2..9b592590 100644 --- a/src/modules/sensors/IoTWiegand/modinfo.json +++ b/src/modules/sensors/IoTWiegand/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Max6675/modinfo.json b/src/modules/sensors/Max6675/modinfo.json index 69a61a32..d99c587d 100644 --- a/src/modules/sensors/Max6675/modinfo.json +++ b/src/modules/sensors/Max6675/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Mhz19/modinfo.json b/src/modules/sensors/Mhz19/modinfo.json index dc2ca89e..d65d7466 100644 --- a/src/modules/sensors/Mhz19/modinfo.json +++ b/src/modules/sensors/Mhz19/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, @@ -73,12 +73,15 @@ "ABC": "Автокалибровка. По умолчанию включена. Раз в сутки на 20 мин. надо выставлять на свежий воздух.", "pin": "пин получения значений по ШИМ. Esp8266: GPIO 15 - D8, ESP32: GPIO 21, > MHZ19: PWM желтый провод", "maxRetriesNotAvailable": "Максимальное количество попыток опроса сенсора по ШИМ. (может задерживать контроллер)" - } + }, + "title": "Mhz19 Датчик уровеня концентрации CO2" }, "defActive": false, "usedLibs": { "esp32_4mb": [], - "esp32s2_4mb": ["plerup/EspSoftwareSerial"], + "esp32s2_4mb": [ + "plerup/EspSoftwareSerial" + ], "esp8266_4mb": [] } } \ No newline at end of file diff --git a/src/modules/sensors/Ntc/modinfo.json b/src/modules/sensors/Ntc/modinfo.json index 3237fc97..c2730bf6 100644 --- a/src/modules/sensors/Ntc/modinfo.json +++ b/src/modules/sensors/Ntc/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, @@ -13,17 +13,14 @@ "needSave": 0, "val": "0", "int": 15, - "pin": "35", - "R1":"10000", - "R0":"10000", - "Beta":"3950.0", - "T0":"25", - "Vs":"3.3", - "round" : 1 - + "pin": "35", + "R1": "10000", + "R0": "10000", + "Beta": "3950.0", + "T0": "25", + "Vs": "3.3", + "round": 1 } - - ], "about": { "authorName": "Serghei Crasnicov", @@ -44,11 +41,11 @@ "retInfo": "", "propInfo": { "pin": "Аналоговый пин (для esp8266 = 0, для esp32 алаоговый gpio, например 35)", - "R1":"Сопротивление подтягивающего резистора, должен быть равен сопротивлению термистера", - "Vs":"Напряжение питания датчика, Для точности измерить и ввести своё, по умолчанию 3.3В", - "R0":"Сопротивление термистора при температуре То, например 10 КОм при 25С", - "T0":"Базовая температура, температура измерения сопротивление термистора (Rterm), обычно 25С", - "Beta":"Beta термистора" + "R1": "Сопротивление подтягивающего резистора, должен быть равен сопротивлению термистера", + "Vs": "Напряжение питания датчика, Для точности измерить и ввести своё, по умолчанию 3.3В", + "R0": "Сопротивление термистора при температуре То, например 10 КОм при 25С", + "T0": "Базовая температура, температура измерения сопротивление термистора (Rterm), обычно 25С", + "Beta": "Beta термистора" } }, "defActive": false, @@ -62,4 +59,4 @@ "esp8266_2mb": [], "esp8266_2mb_ota": [] } -} +} \ No newline at end of file diff --git a/src/modules/sensors/Pzem004t/modinfo.json b/src/modules/sensors/Pzem004t/modinfo.json index 697015f9..e8a71705 100644 --- a/src/modules/sensors/Pzem004t/modinfo.json +++ b/src/modules/sensors/Pzem004t/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, @@ -115,8 +115,8 @@ "Pzem004pf", "Pzem004cmd" ], - "title": "Счетчик электроэнергии PZEM 004 t версии 3.0 (с модбасом). Возможно подключение трех счетчиков к одной esp для трехфазных сетей. Для этого нужно настроить разные адреса modbus в платах pzem", - "moduleDesc": "Считает потраченную электроэнергию, измеряет напряжение, частоту, силу тока и прочие параметры", + "title": "Счетчик электроэнергии PZEM 004 t версии 3.0 (с модбасом)", + "moduleDesc": "Считает потраченную электроэнергию, измеряет напряжение, частоту, силу тока и прочие параметры. Возможно подключение трех счетчиков к одной esp для трехфазных сетей. Для этого нужно настроить разные адреса modbus в платах pzem", "propInfo": { "addr": "Адрес modbus", "int": "Количество секунд между опросами датчика. Желателно устанавливать одинаковые интервалы для параметров (для одного адреса Pzem) что опрос происходил один раз, остальные из 500мс буфера.", diff --git a/src/modules/sensors/RCswitch/modinfo.json b/src/modules/sensors/RCswitch/modinfo.json index dae2a245..ed549042 100644 --- a/src/modules/sensors/RCswitch/modinfo.json +++ b/src/modules/sensors/RCswitch/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/RTC/modinfo.json b/src/modules/sensors/RTC/modinfo.json index 3ecef7f7..67c40768 100644 --- a/src/modules/sensors/RTC/modinfo.json +++ b/src/modules/sensors/RTC/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, @@ -18,7 +18,7 @@ "ticker": 0, "int": 5, "btn-setUTime": "0", - "btn-setSysTime": "nil" + "btn-setSysTime": "nil" } ], "about": { @@ -51,19 +51,37 @@ { "name": "getTime", "descr": "Получить строковое значение времени по указанному формату.", - "params": ["Формат как у функции date() в PHP"] + "params": [ + "Формат как у функции date() в PHP" + ] } ] }, "defActive": true, "usedLibs": { - "esp32_4mb": ["https://github.com/tremaru/iarduino_RTC"], - "esp8266_4mb": ["https://github.com/tremaru/iarduino_RTC"], - "esp8266_1mb": ["https://github.com/tremaru/iarduino_RTC"], - "esp8266_1mb_ota": ["https://github.com/tremaru/iarduino_RTC"], - "esp8285_1mb": ["https://github.com/tremaru/iarduino_RTC"], - "esp8285_1mb_ota": ["https://github.com/tremaru/iarduino_RTC"], - "esp8266_2mb": ["https://github.com/tremaru/iarduino_RTC"], - "esp8266_2mb_ota": ["https://github.com/tremaru/iarduino_RTC"] + "esp32_4mb": [ + "https://github.com/tremaru/iarduino_RTC" + ], + "esp8266_4mb": [ + "https://github.com/tremaru/iarduino_RTC" + ], + "esp8266_1mb": [ + "https://github.com/tremaru/iarduino_RTC" + ], + "esp8266_1mb_ota": [ + "https://github.com/tremaru/iarduino_RTC" + ], + "esp8285_1mb": [ + "https://github.com/tremaru/iarduino_RTC" + ], + "esp8285_1mb_ota": [ + "https://github.com/tremaru/iarduino_RTC" + ], + "esp8266_2mb": [ + "https://github.com/tremaru/iarduino_RTC" + ], + "esp8266_2mb_ota": [ + "https://github.com/tremaru/iarduino_RTC" + ] } } \ No newline at end of file diff --git a/src/modules/sensors/S8/modinfo.json b/src/modules/sensors/S8/modinfo.json index 6f702b87..55dbe2fe 100644 --- a/src/modules/sensors/S8/modinfo.json +++ b/src/modules/sensors/S8/modinfo.json @@ -1,19 +1,19 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { - "name": "(S8) Cенсор качества воздуха", - "num": 3, - "type": "Reading", - "subtype": "S8co", - "id": "s8co", - "widget": "anydataPpm", - "page": "Сенсоры", - "descr": "S8_CO2", - "int": 15, - "round": 1, - "rxPin": 13, - "txPin": 15 + "name": "(S8) Cенсор качества воздуха", + "num": 3, + "type": "Reading", + "subtype": "S8co", + "id": "s8co", + "widget": "anydataPpm", + "page": "Сенсоры", + "descr": "S8_CO2", + "int": 15, + "round": 1, + "rxPin": 13, + "txPin": 15 } ], "about": { @@ -35,9 +35,7 @@ }, "defActive": true, "usedLibs": { - "esp32_4mb": [ - ], - "esp8266_4mb": [ - ] + "esp32_4mb": [], + "esp8266_4mb": [] } } \ No newline at end of file diff --git a/src/modules/sensors/Scd40/modinfo.json b/src/modules/sensors/Scd40/modinfo.json index 4ccceeac..601723b0 100644 --- a/src/modules/sensors/Scd40/modinfo.json +++ b/src/modules/sensors/Scd40/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, @@ -14,7 +14,7 @@ "round": 0, "lowPeriodic": 1, "autoCalibration": 1, - "btn-Recalibration": 0 + "btn-Recalibration": 0 }, { "global": 0, @@ -61,13 +61,11 @@ "title": "Датчик температуры и влажности Scd40", "moduleDesc": "Позволяет получить значения температуры и влажности с Scd40.", "propInfo": { - "int": "Количество секунд между опросами библиотеки (датчик опрашивается библиотекой по своему таймеру, см. lowPeriodic).", "offset": "Смещение температуры представляет собой разницу между температурой, измеренной SCD4x, и фактической температурой окружающей среды температура. По умолчанию смещение температуры в библиотеке/датчике установлено на 4°C.", "lowPeriodic": "Медленные режим опроса датчика библиотекой. 0-каждые 5сек, 1-каждые 30сек", "autoCalibration": "Автоматическая калибровка, по умолчанию включена AutomaticSelfCalibration, 0 - выключена", - "btn-Recalibration": "Кнопка принудительной калибровки. В поле указать Целевая концентрация CO₂ в миллионных долях. Перед калибровкой необходимо находтся в течение > 3 минут в среде с однородной и постоянной концентрацией CO₂. Выдает в лог Значение коррекции FRC в co₂ ppm" - + "btn-Recalibration": "Кнопка принудительной калибровки. В поле указать Целевая концентрация CO₂ в миллионных долях. Перед калибровкой необходимо находтся в течение > 3 минут в среде с однородной и постоянной концентрацией CO₂. Выдает в лог Значение коррекции FRC в co₂ ppm" } }, "defActive": false, diff --git a/src/modules/sensors/Sds011/modinfo.json b/src/modules/sensors/Sds011/modinfo.json index 8fd8eb80..78f053e8 100644 --- a/src/modules/sensors/Sds011/modinfo.json +++ b/src/modules/sensors/Sds011/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, @@ -61,7 +61,8 @@ "continuousMode": "1 - Непрерывный режим, 0 - Режим с остановкой (щедящий)", "maxRetriesNotAvailable": "Количество попыток ожидания ответа сенсора при опросе (не нужно менять)", "retryDelayMs": "Задержка между попытками, миллисекунды (не нужно менять)" - } + }, + "title": "Sds011 Датчик концентрации пыли в воздухе" }, "defActive": false, "usedLibs": { diff --git a/src/modules/sensors/Sgp30/modinfo.json b/src/modules/sensors/Sgp30/modinfo.json index 94c59309..0857dc39 100644 --- a/src/modules/sensors/Sgp30/modinfo.json +++ b/src/modules/sensors/Sgp30/modinfo.json @@ -1,31 +1,31 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { - "global": 0, - "name": "SGP30 Cенсор качества воздуха", - "num": 3, - "type": "Reading", - "subtype": "Sgp30t", - "id": "sgp30t", - "widget": "anydatappm", - "page": "Сенсоры", - "descr": "TVOC", - "int": 30, - "round": 1 + "global": 0, + "name": "SGP30 Cенсор качества воздуха", + "num": 3, + "type": "Reading", + "subtype": "Sgp30t", + "id": "sgp30t", + "widget": "anydatappm", + "page": "Сенсоры", + "descr": "TVOC", + "int": 30, + "round": 1 }, { - "global": 0, - "name": "SGP30 Cенсор газа", - "num": 4, - "type": "Reading", - "subtype": "Sgp30e", - "id": "sgp30e", - "widget": "anydatappm", - "page": "Сенсоры", - "descr": "eCO2", - "int": 30, - "round": 1 + "global": 0, + "name": "SGP30 Cенсор газа", + "num": 4, + "type": "Reading", + "subtype": "Sgp30e", + "id": "sgp30e", + "widget": "anydatappm", + "page": "Сенсоры", + "descr": "eCO2", + "int": 30, + "round": 1 } ], "about": { diff --git a/src/modules/sensors/Sht20/modinfo.json b/src/modules/sensors/Sht20/modinfo.json index 39b07e6d..5051007c 100644 --- a/src/modules/sensors/Sht20/modinfo.json +++ b/src/modules/sensors/Sht20/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Sht30/modinfo.json b/src/modules/sensors/Sht30/modinfo.json index 47e42933..9c065c41 100644 --- a/src/modules/sensors/Sht30/modinfo.json +++ b/src/modules/sensors/Sht30/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/Sonar/modinfo.json b/src/modules/sensors/Sonar/modinfo.json index 8c79734a..0e02af75 100644 --- a/src/modules/sensors/Sonar/modinfo.json +++ b/src/modules/sensors/Sonar/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/sensors/UART/modinfo.json b/src/modules/sensors/UART/modinfo.json index 1e63b4e1..b7c5e5b3 100644 --- a/src/modules/sensors/UART/modinfo.json +++ b/src/modules/sensors/UART/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "name": "UART", @@ -44,22 +44,31 @@ { "name": "println", "descr": "Отправить в UART строку текста и признак завершения строки (перевод строки).", - "params": ["Строка текста"] + "params": [ + "Строка текста" + ] }, { "name": "print", "descr": "Отправить в UART строку текста.", - "params": ["Строка текста"] + "params": [ + "Строка текста" + ] }, { "name": "printHex", "descr": "Отправить в UART HEX-строку.", - "params": ["HEX-строка."] + "params": [ + "HEX-строка." + ] }, { "name": "printFFF", "descr": "Отправить в UART текстовую строку и hex метку 3 байта 0xFF0xFF0xFF.", - "params": ["Строка текста", "1 - обернуть строку в кавычки, 0 - отправить без кавычек"] + "params": [ + "Строка текста", + "1 - обернуть строку в кавычки, 0 - отправить без кавычек" + ] } ] }, diff --git a/src/modules/sensors/ld2410/ld2410.cpp b/src/modules/sensors/ld2410/ld2410.cpp index 330c9953..c17c5751 100644 --- a/src/modules/sensors/ld2410/ld2410.cpp +++ b/src/modules/sensors/ld2410/ld2410.cpp @@ -235,7 +235,11 @@ public: } } } - ~ld2410m(){}; + ~ld2410m() + { + delete ld2410; + radar = nullptr; + }; }; //--------------------------------------------------------------------------- @@ -291,7 +295,11 @@ public: } } - ~ld2410t(){}; + ~ld2410t() + { + delete ld2410; + radar = nullptr; + }; }; //--------------------------------------------------------------------------- @@ -346,7 +354,11 @@ public: } } } - ~ld2410d(){}; + ~ld2410d() + { + delete ld2410; + radar = nullptr; + }; }; //--------------------------------------------------------------------------- @@ -404,7 +416,11 @@ public: } } } - ~ld2410e(){}; + ~ld2410e() + { + delete ld2410; + radar = nullptr; + }; }; //--------------------------------------------------------------------------- void *getAPI_ld2410(String subtype, String param) diff --git a/src/modules/sensors/ld2410/modinfo.json b/src/modules/sensors/ld2410/modinfo.json index 78b06bc4..f9e4a314 100644 --- a/src/modules/sensors/ld2410/modinfo.json +++ b/src/modules/sensors/ld2410/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Сенсоры", + "menuSection": "sensors", "configItem": [ { "global": 0, diff --git a/src/modules/virtual/Cron/modinfo.json b/src/modules/virtual/Cron/modinfo.json index f6a3f89f..7bb1fc78 100644 --- a/src/modules/virtual/Cron/modinfo.json +++ b/src/modules/virtual/Cron/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Виртуальные элементы", + "menuSection": "virtual_elments", "configItem": [ { "global": 0, @@ -50,8 +50,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/GoogleSheet/modinfo.json b/src/modules/virtual/GoogleSheet/modinfo.json index 8a8f47ee..4c046fdb 100644 --- a/src/modules/virtual/GoogleSheet/modinfo.json +++ b/src/modules/virtual/GoogleSheet/modinfo.json @@ -1,19 +1,19 @@ { - "menuSection": "Виртуальные элементы", + "menuSection": "virtual_elments", "configItem": [ { - "global": 0, + "global": 0, "name": "GoogleSheet", - "type": "Reading", + "type": "Reading", "subtype": "GoogleSheet", "id": "sheet", "widget": "nil", "page": "", "descr": "", "int": 5, - "logid": "", - "scid": "", - "shname": "Logger" + "logid": "", + "scid": "", + "shname": "Logger" } ], "about": { @@ -33,8 +33,8 @@ "propInfo": { "int": "Интервал логирования в минутах", "logid": "ID величины которую будем логировать", - "scid": "Идентификатор развертывания Google Apps (script id)", - "shname": "Наименование листа в таблице (sheet name)" + "scid": "Идентификатор развертывания Google Apps (script id)", + "shname": "Наименование листа в таблице (sheet name)" }, "retInfo": "", "funcInfo": [ @@ -43,7 +43,7 @@ "descr": "Использовать не чаще раз в минуту! Логирование элементов в GoogleSheet, ID элементов указывать через запятую, от одного до N (проверено на 16шт). В данной функции поиск элементов идет по их значению, если несколько элементов с одинаковым значение, может быть не правильно указан его id в Таблице.", "params": [ "id Идентификатор 1-го элеменета", - "id Идентификатор N-го элеменета" + "id Идентификатор N-го элеменета" ] }, { diff --git a/src/modules/virtual/Loging/modinfo.json b/src/modules/virtual/Loging/modinfo.json index e39018e3..c9c9ceb4 100644 --- a/src/modules/virtual/Loging/modinfo.json +++ b/src/modules/virtual/Loging/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Виртуальные элементы", + "menuSection": "virtual_elments", "configItem": [ { "global": 0, @@ -51,8 +51,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/LogingDaily/modinfo.json b/src/modules/virtual/LogingDaily/modinfo.json index 9c17af4b..c34ee78f 100644 --- a/src/modules/virtual/LogingDaily/modinfo.json +++ b/src/modules/virtual/LogingDaily/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Виртуальные элементы", + "menuSection": "virtual_elments", "configItem": [ { "global": 0, @@ -44,8 +44,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/Timer/modinfo.json b/src/modules/virtual/Timer/modinfo.json index be4abb02..f65b2c54 100644 --- a/src/modules/virtual/Timer/modinfo.json +++ b/src/modules/virtual/Timer/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Виртуальные элементы", + "menuSection": "virtual_elments", "configItem": [ { "global": 0, @@ -58,20 +58,26 @@ { "name": "int", "descr": "Можно изменить шаг тиков.", - "params": ["Число в секундах"] + "params": [ + "Число в секундах" + ] }, { "name": "setInitCountDown", "descr": "Меняем начальное значение счетчика, устанавливаемое после сброса.", - "params": ["Число в секундах"] + "params": [ + "Число в секундах" + ] } ] }, "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/VButton/modinfo.json b/src/modules/virtual/VButton/modinfo.json index ab78d4d0..9c6b6488 100644 --- a/src/modules/virtual/VButton/modinfo.json +++ b/src/modules/virtual/VButton/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Виртуальные элементы", + "menuSection": "virtual_elments", "configItem": [ { "global": 0, @@ -36,8 +36,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/Variable/modinfo.json b/src/modules/virtual/Variable/modinfo.json index feb0370a..55b11e20 100644 --- a/src/modules/virtual/Variable/modinfo.json +++ b/src/modules/virtual/Variable/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Виртуальные элементы", + "menuSection": "virtual_elments", "configItem": [ { "global": 0, @@ -96,8 +96,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/VariableColor/modinfo.json b/src/modules/virtual/VariableColor/modinfo.json index 59fd429b..4ff78661 100644 --- a/src/modules/virtual/VariableColor/modinfo.json +++ b/src/modules/virtual/VariableColor/modinfo.json @@ -1,49 +1,49 @@ { - "menuSection": "Виртуальные элементы", - "configItem": [ - { - "global": 0, - "name": "Цветной текст", - "type": "Reading", - "subtype": "VariableColor", - "id": "color", - "needSave": 0, - "widget": "anydataDef", - "page": "Вывод", - "descr": "Цветной текст", - "val": "...", - "round": 0 - } - ], - "about": { - "authorName": "AVAKS", - "authorContact": "https://t.me/@avaks_dev", - "authorGit": "https://github.com/avaksru", - "specialThanks": "", - "moduleName": "VariableColor", - "moduleVersion": "1", - "usedRam": { - "esp32_4mb": 15, - "esp8266_4mb": 15 - }, - "title": "Цветной текст", - "moduleDesc": "Текст с возможностью динамического изменения цвета", - "propInfo": { - "val": "Значение при старте" - } - }, - - "defActive": true, - - "usedLibs": { - "esp32_4mb": [], - "esp32s2_4mb": [], - "esp8266_4mb": [], - "esp8266_1mb": [], - "esp8266_1mb_ota": [], - "esp8285_1mb": [], - "esp8285_1mb_ota": [], - "esp8266_2mb": [], - "esp8266_2mb_ota": [] - } + "menuSection": "virtual_elments", + "configItem": [ + { + "global": 0, + "name": "Цветной текст", + "type": "Reading", + "subtype": "VariableColor", + "id": "color", + "needSave": 0, + "widget": "anydataDef", + "page": "Вывод", + "descr": "Цветной текст", + "val": "...", + "round": 0 + } + ], + "about": { + "authorName": "AVAKS", + "authorContact": "https://t.me/@avaks_dev", + "authorGit": "https://github.com/avaksru", + "specialThanks": "", + "moduleName": "VariableColor", + "moduleVersion": "1", + "usedRam": { + "esp32_4mb": 15, + "esp8266_4mb": 15 + }, + "title": "Цветной текст", + "moduleDesc": "Текст с возможностью динамического изменения цвета", + "propInfo": { + "val": "Значение при старте" + } + }, + "defActive": true, + "usedLibs": { + "esp32_4mb": [], + "esp32_16mb": [], + "esp32s2_4mb": [], + "esp8266_4mb": [], + "esp8266_16mb": [], + "esp8266_1mb": [], + "esp8266_1mb_ota": [], + "esp8285_1mb": [], + "esp8285_1mb_ota": [], + "esp8266_2mb": [], + "esp8266_2mb_ota": [] + } } \ No newline at end of file diff --git a/src/modules/virtual/Weather/modinfo.json b/src/modules/virtual/Weather/modinfo.json index 9b315192..bd0acc77 100644 --- a/src/modules/virtual/Weather/modinfo.json +++ b/src/modules/virtual/Weather/modinfo.json @@ -1,6 +1,5 @@ { - "menuSection": "Виртуальные элементы", - + "menuSection": "virtual_elments", "configItem": [ { "global": 0, @@ -19,7 +18,6 @@ "val": "..." } ], - "about": { "authorName": "AVAKS", "authorContact": "https://t.me/@avaks_dev", @@ -39,13 +37,13 @@ "int": "Интервал запроса погоды в часах" } }, - "defActive": false, - "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], @@ -53,4 +51,4 @@ "esp8266_2mb": [], "esp8266_2mb_ota": [] } -} +} \ No newline at end of file diff --git a/src/utils/JsonUtils.cpp b/src/utils/JsonUtils.cpp index 59950c9f..8e7d2f5e 100644 --- a/src/utils/JsonUtils.cpp +++ b/src/utils/JsonUtils.cpp @@ -2,26 +2,34 @@ #include "utils/FileUtils.h" // new================================================================================ -String jsonReadStrDoc(DynamicJsonDocument& doc, String name) { +String jsonReadStrDoc(DynamicJsonDocument &doc, String name) +{ return doc[name].as(); } -void jsonWriteStrDoc(DynamicJsonDocument& doc, String name, String value) { +void jsonWriteStrDoc(DynamicJsonDocument &doc, String name, String value) +{ doc[name] = value; } // new============================================================================== -bool jsonRead(const String& json, String key, long& value, bool e) { +bool jsonRead(const String &json, String key, long &value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } return false; - } else if (!doc.containsKey(key)) { - if (e) { + } + else if (!doc.containsKey(key)) + { + if (e) + { SerialPrint("E", F("jsonRead"), key + " missing in " + json); jsonErrorDetected(); } @@ -31,17 +39,23 @@ bool jsonRead(const String& json, String key, long& value, bool e) { return true; } -bool jsonRead(const String& json, String key, float& value, bool e) { +bool jsonRead(const String &json, String key, float &value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } return false; - } else if (!doc.containsKey(key)) { - if (e) { + } + else if (!doc.containsKey(key)) + { + if (e) + { SerialPrint("E", F("jsonRead"), key + " missing in " + json); jsonErrorDetected(); } @@ -51,17 +65,23 @@ bool jsonRead(const String& json, String key, float& value, bool e) { return true; } -bool jsonRead(const String& json, String key, String& value, bool e) { +bool jsonRead(const String &json, String key, String &value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } return false; - } else if (!doc.containsKey(key)) { - if (e) { + } + else if (!doc.containsKey(key)) + { + if (e) + { SerialPrint("E", F("jsonRead"), key + " missing in " + json); jsonErrorDetected(); } @@ -71,24 +91,31 @@ bool jsonRead(const String& json, String key, String& value, bool e) { return true; } -bool jsonRead(const String& json, String key, bool& value, bool e) { +bool jsonRead(const String &json, String key, bool &value, bool e) +{ int lvalue = value; bool ret = jsonRead(json, key, lvalue, e); value = lvalue; return ret; } -bool jsonRead(const String& json, String key, int& value, bool e) { +bool jsonRead(const String &json, String key, int &value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } return false; - } else if (!doc.containsKey(key)) { - if (e) { + } + else if (!doc.containsKey(key)) + { + if (e) + { SerialPrint("E", F("jsonRead"), key + " missing in " + json); jsonErrorDetected(); } @@ -98,13 +125,59 @@ bool jsonRead(const String& json, String key, int& value, bool e) { return true; } +bool jsonReadArray(const String &json, String key, std::vector &jArray, bool e) +{ + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) + { + if (e) + { + SerialPrint("E", F("jsonReadArray"), error.f_str()); + jsonErrorDetected(); + } + return false; + } + else if (!doc.containsKey(key)) + { + if (e) + { + SerialPrint("E", F("jsonReadArray"), key + " missing in " + json); + jsonErrorDetected(); + } + return false; + } + // SerialPrint("E", F("jsonReadArray"), key + " doc " + doc[key].as()); + if (doc[key].is()) + { + for (int8_t i = 0; i < doc[key].size(); i++) + jArray.push_back(doc[key][i].as()); + // SerialPrint("E", F("jsonReadArray"), "isArray"+key + " doc " + doc[key].as()); + } + else + { + jArray.push_back(doc[key].as()); + // DynamicJsonDocument docArr(JSON_BUFFER_SIZE/5); + // jArray = doc[key].as(); + // String tmp = doc[key].as(); + // jArray.add("dsdsd"); + // SerialPrint("E", F("jsonReadArray"), "notArray"+key + " doc " + doc[key].as()); + // SerialPrint("E", F("jsonReadArray"), "count: " + String(jArray.size()) +" key: " + key + " arr " + jArray[0]); + } + // SerialPrint("E", F("jsonReadArray"), "count: " + String(jArray.size()) +" key: " + key + " doc " + jArray[0].as()); + return true; +} + // new============================================================================== -bool jsonWriteStr_(String& json, const String& key, const String& value, bool e) { +bool jsonWriteStr_(String &json, const String &key, const String &value, bool e) +{ bool ret = true; DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -116,12 +189,15 @@ bool jsonWriteStr_(String& json, const String& key, const String& value, bool e) return ret; } -bool jsonWriteBool_(String& json, const String& key, bool value, bool e) { +bool jsonWriteBool_(String &json, const String &key, bool value, bool e) +{ bool ret = true; DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -133,12 +209,15 @@ bool jsonWriteBool_(String& json, const String& key, bool value, bool e) { return ret; } -bool jsonWriteInt_(String& json, const String& key, int value, bool e) { +bool jsonWriteInt_(String &json, const String &key, int value, bool e) +{ bool ret = true; DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -150,12 +229,15 @@ bool jsonWriteInt_(String& json, const String& key, int value, bool e) { return ret; } -bool jsonWriteFloat_(String& json, const String &key, float value, bool e) { +bool jsonWriteFloat_(String &json, const String &key, float value, bool e) +{ bool ret = true; DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -167,24 +249,29 @@ bool jsonWriteFloat_(String& json, const String &key, float value, bool e) { return ret; } -void writeUint8tValueToJsonString(uint8_t* payload, size_t length, size_t headerLenth, String& json) { +void writeUint8tValueToJsonString(uint8_t *payload, size_t length, size_t headerLenth, String &json) +{ String payloadStr; payloadStr.reserve(length + 1); - for (size_t i = headerLenth; i < length; i++) { + for (size_t i = headerLenth; i < length; i++) + { payloadStr += (char)payload[i]; } jsonMergeObjects(json, payloadStr); } -bool jsonMergeObjects(String& json1, String& json2, bool e) { +bool jsonMergeObjects(String &json1, String &json2, bool e) +{ bool ret = true; DynamicJsonDocument doc1(JSON_BUFFER_SIZE); DeserializationError error1 = deserializeJson(doc1, json1); DynamicJsonDocument doc2(JSON_BUFFER_SIZE); DeserializationError error2 = deserializeJson(doc2, json2); jsonMergeDocs(doc1.as(), doc2.as()); - if (error1 || error2) { - if (e) { + if (error1 || error2) + { + if (e) + { SerialPrint("E", F("json"), "jsonMergeObjects error"); jsonErrorDetected(); } @@ -195,18 +282,23 @@ bool jsonMergeObjects(String& json1, String& json2, bool e) { return ret; } -void jsonMergeDocs(JsonObject dest, JsonObjectConst src) { - for (auto kvp : src) { +void jsonMergeDocs(JsonObject dest, JsonObjectConst src) +{ + for (auto kvp : src) + { dest[kvp.key()] = kvp.value(); } } // depricated====================================================================== -String jsonReadStr(const String& json, String name, bool e) { +String jsonReadStr(const String &json, String name, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } @@ -214,11 +306,14 @@ String jsonReadStr(const String& json, String name, bool e) { return doc[name].as(); } -boolean jsonReadBool(const String& json, String name, bool e) { +boolean jsonReadBool(const String &json, String name, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } @@ -226,11 +321,14 @@ boolean jsonReadBool(const String& json, String name, bool e) { return doc[name].as(); } -int jsonReadInt(const String& json, String name, bool e) { +int jsonReadInt(const String &json, String name, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } @@ -238,11 +336,14 @@ int jsonReadInt(const String& json, String name, bool e) { return doc[name].as(); } -long int jsonReadLInt(const String& json, String name, bool e) { +long int jsonReadLInt(const String &json, String name, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } @@ -251,11 +352,14 @@ long int jsonReadLInt(const String& json, String name, bool e) { } // depricated======================================================================== -String jsonWriteStr(String& json, String name, String value, bool e) { +String jsonWriteStr(String &json, String name, String value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -266,11 +370,14 @@ String jsonWriteStr(String& json, String name, String value, bool e) { return json; } -String jsonWriteBool(String& json, String name, boolean value, bool e) { +String jsonWriteBool(String &json, String name, boolean value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -281,11 +388,14 @@ String jsonWriteBool(String& json, String name, boolean value, bool e) { return json; } -String jsonWriteInt(String& json, String name, int value, bool e) { +String jsonWriteInt(String &json, String name, int value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -296,11 +406,14 @@ String jsonWriteInt(String& json, String name, int value, bool e) { return json; } -String jsonWriteFloat(String& json, String name, float value, bool e) { +String jsonWriteFloat(String &json, String name, float value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -311,7 +424,8 @@ String jsonWriteFloat(String& json, String name, float value, bool e) { return json; } -void jsonErrorDetected() { +void jsonErrorDetected() +{ // пример как отправить ошибку с количеством // jsonWriteInt(errorsHeapJson, F("jse2"), 1); // int number = jsonReadInt(errorsHeapJson, F("jse2n")); diff --git a/src/utils/Statistic.cpp b/src/utils/Statistic.cpp index 621e1de5..1b34bf72 100644 --- a/src/utils/Statistic.cpp +++ b/src/utils/Statistic.cpp @@ -34,7 +34,7 @@ void updateDeviceStatus() { int httpResponseCode = http.POST(httpRequestData); if (httpResponseCode > 0) { - ret = httpResponseCode; + ret = http.errorToString(httpResponseCode).c_str(); if (httpResponseCode == HTTP_CODE_OK) { String payload = http.getString(); ret += " " + payload; diff --git a/src/utils/WiFiUtils.cpp b/src/utils/WiFiUtils.cpp index 681d2c8a..cf1dc846 100644 --- a/src/utils/WiFiUtils.cpp +++ b/src/utils/WiFiUtils.cpp @@ -1,141 +1,210 @@ #include "utils/WiFiUtils.h" +#include +#define TRIESONE 25 // количество попыток подключения к одной сети из несколких +#define TRIES 40 // количество попыток подключения сети если она одна -void routerConnect() { - WiFi.setAutoConnect(false); - WiFi.persistent(false); +void routerConnect() +{ + WiFi.setAutoConnect(false); + WiFi.persistent(false); - WiFi.mode(WIFI_STA); - byte tries = 40; + WiFi.mode(WIFI_STA); + byte triesOne = TRIESONE; - String _ssid = jsonReadStr(settingsFlashJson, "routerssid"); - String _password = jsonReadStr(settingsFlashJson, "routerpass"); + std::vector _ssidList; + std::vector _passwordList; + jsonReadArray(settingsFlashJson, "routerssid", _ssidList); + jsonReadArray(settingsFlashJson, "routerpass", _passwordList); + if (_ssidList.size() > 1) + triesOne = TRIES; - if (_ssid == "" && _password == "") { - WiFi.begin(); - } else { - WiFi.begin(_ssid.c_str(), _password.c_str()); + if (_passwordList.size() == 0 && _ssidList[0] == "" && _passwordList[0] == "") + { + WiFi.begin(); + } + else + { + WiFi.begin(_ssidList[0].c_str(), _passwordList[0].c_str()); #ifdef ESP32 - WiFi.setTxPower(WIFI_POWER_19_5dBm); + WiFi.setTxPower(WIFI_POWER_19_5dBm); #else - WiFi.setOutputPower(20.5); + WiFi.setOutputPower(20.5); #endif - SerialPrint("i", "WIFI", "ssid: " + _ssid); - SerialPrint("i", "WIFI", "pass: " + _password); + String _ssid; + String _password; + for (int8_t i = 0; i < _ssidList.size(); i++) + { + _ssid = _ssid + _ssidList[i] + "; "; } - - while (--tries && WiFi.status() != WL_CONNECTED) { - if (WiFi.status() == WL_CONNECT_FAILED) { - SerialPrint("E", "WIFI", "password is not correct"); - tries = 1; - jsonWriteInt(errorsHeapJson, "passer", 1); - break; - } - Serial.print("."); - delay(1000); + for (int8_t i = 0; i < _passwordList.size(); i++) + { + _password = _password + _passwordList[i] + "; "; } - - if (WiFi.status() != WL_CONNECTED) { - Serial.println(""); - startAPMode(); - } else { - Serial.println(""); - SerialPrint("i", "WIFI", "http://" + WiFi.localIP().toString()); - jsonWriteStr(settingsFlashJson, "ip", WiFi.localIP().toString()); - - mqttInit(); + SerialPrint("i", "WIFI", "ssid list: " + _ssid); + SerialPrint("i", "WIFI", "pass list: " + _password); + } + for (size_t i = 0; i < _ssidList.size(); i++) + { + triesOne = TRIESONE; + if (WiFi.status() == WL_CONNECTED) + break; + WiFi.begin(_ssidList[i].c_str(), _passwordList[i].c_str()); + SerialPrint("i", "WIFI", "ssid connect: " + _ssidList[i]); + SerialPrint("i", "WIFI", "pass connect: " + _passwordList[i]); + while (--triesOne && WiFi.status() != WL_CONNECTED) + { +// SerialPrint("i", "WIFI", ": " + String((int)WiFi.status())); +#ifdef ESP8266 + if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_WRONG_PASSWORD) +#else + if (WiFi.status() == WL_CONNECT_FAILED) +#endif + { + SerialPrint("E", "WIFI", "password is not correct"); + triesOne = 1; + jsonWriteInt(errorsHeapJson, "passer", 1); + break; + } + Serial.print("."); + delay(1000); } - SerialPrint("i", F("WIFI"), F("Network Init")); + Serial.println(""); + } + + if (WiFi.status() != WL_CONNECTED) + { + Serial.println(""); + startAPMode(); + } + else + { + Serial.println(""); + SerialPrint("i", "WIFI", "http://" + WiFi.localIP().toString()); + jsonWriteStr(settingsFlashJson, "ip", WiFi.localIP().toString()); + + mqttInit(); + } + SerialPrint("i", F("WIFI"), F("Network Init")); } -bool startAPMode() { - SerialPrint("i", "WIFI", "AP Mode"); +bool startAPMode() +{ + SerialPrint("i", "WIFI", "AP Mode"); - WiFi.disconnect(); - WiFi.mode(WIFI_AP); + WiFi.disconnect(); + WiFi.mode(WIFI_AP); - String _ssidAP = jsonReadStr(settingsFlashJson, "apssid"); - String _passwordAP = jsonReadStr(settingsFlashJson, "appass"); + String _ssidAP = jsonReadStr(settingsFlashJson, "apssid"); + String _passwordAP = jsonReadStr(settingsFlashJson, "appass"); - WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str()); - IPAddress myIP = WiFi.softAPIP(); + WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str()); + IPAddress myIP = WiFi.softAPIP(); - SerialPrint("i", "WIFI", "AP IP: " + myIP.toString()); - jsonWriteStr(settingsFlashJson, "ip", myIP.toString()); + SerialPrint("i", "WIFI", "AP IP: " + myIP.toString()); + jsonWriteStr(settingsFlashJson, "ip", myIP.toString()); - if (jsonReadInt(errorsHeapJson, "passer") != 1) { - ts.add( - WIFI_SCAN, 30 * 1000, [&](void*) { - String sta_ssid = jsonReadStr(settingsFlashJson, "routerssid"); - - SerialPrint("i", "WIFI", "scanning for " + sta_ssid); - - if (RouterFind(sta_ssid)) { - ts.remove(WIFI_SCAN); - WiFi.scanDelete(); - routerConnect(); - } - }, - nullptr, true); - } - return true; + if (jsonReadInt(errorsHeapJson, "passer") != 1) + { + ts.add( + WIFI_SCAN, 30 * 1000, + [&](void *) + { + std::vector jArray; + jsonReadArray(settingsFlashJson, "routerssid", jArray); + for (int8_t i = 0; i < jArray.size(); i++) + { + SerialPrint("i", "WIFI", "scanning for " + jArray[i]); + } + if (RouterFind(jArray)) + { + ts.remove(WIFI_SCAN); + WiFi.scanDelete(); + routerConnect(); + } + }, + nullptr, true); + } + return true; } -boolean RouterFind(String ssid) { - bool res = false; - int n = WiFi.scanComplete(); - SerialPrint("i", "WIFI", "scan result: " + String(n, DEC)); +boolean RouterFind(std::vector jArray) +{ + bool res = false; + int n = WiFi.scanComplete(); + SerialPrint("i", "WIFI", "scan result: " + String(n, DEC)); - if (n == -2) { //Сканирование не было запущено, запускаем - SerialPrint("i", "WIFI", "start scanning"); - WiFi.scanNetworks(true, false); // async, show_hidden - } + if (n == -2) + { // Сканирование не было запущено, запускаем + SerialPrint("i", "WIFI", "start scanning"); + WiFi.scanNetworks(true, false); // async, show_hidden + } - else if (n == -1) { //Сканирование все еще выполняется - SerialPrint("i", "WIFI", "scanning in progress"); - } + else if (n == -1) + { // Сканирование все еще выполняется + SerialPrint("i", "WIFI", "scanning in progress"); + } - else if (n == 0) { //ни одна сеть не найдена - SerialPrint("i", "WIFI", "no networks found"); - WiFi.scanNetworks(true, false); - } - - else if (n > 0) { - for (int8_t i = 0; i < n; i++) { - if (WiFi.SSID(i) == ssid) { - res = true; - } - // SerialPrint("i", "WIFI", (res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i)); - jsonWriteStr_(ssidListHeapJson, String(i), WiFi.SSID(i)); - - // String(WiFi.RSSI(i) + else if (n == 0) + { // ни одна сеть не найдена + SerialPrint("i", "WIFI", "no networks found"); + WiFi.scanNetworks(true, false); + } + else if (n > 0) + { + for (int8_t i = 0; i < n; i++) + { + for (int8_t k = 0; k < jArray.size(); k++) + { + if (WiFi.SSID(i) == jArray[k]) + { + res = true; } + } + // SerialPrint("i", "WIFI", (res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i)); + jsonWriteStr_(ssidListHeapJson, String(i), WiFi.SSID(i)); + + // String(WiFi.RSSI(i) } - SerialPrint("i", "WIFI", ssidListHeapJson); - WiFi.scanDelete(); - return res; + } + SerialPrint("i", "WIFI", ssidListHeapJson); + WiFi.scanDelete(); + return res; } // boolean isNetworkActive() { // return WiFi.status() == WL_CONNECTED; // } -uint8_t RSSIquality() { - uint8_t res = 0; - if (WiFi.status() == WL_CONNECTED) { - int rssi = WiFi.RSSI(); - if (rssi >= -50) { - res = 6; //"Excellent"; - } else if (rssi < -50 && rssi >= -60) { - res = 5; //"Very good"; - } else if (rssi < -60 && rssi >= -70) { - res = 4; //"Good"; - } else if (rssi < -70 && rssi >= -80) { - res = 3; //"Low"; - } else if (rssi < -80 && rssi > -100) { - res = 2; //"Very low"; - } else if (rssi <= -100) { - res = 1; //"No signal"; - } +uint8_t RSSIquality() +{ + uint8_t res = 0; + if (WiFi.status() == WL_CONNECTED) + { + int rssi = WiFi.RSSI(); + if (rssi >= -50) + { + res = 6; //"Excellent"; } - return res; + else if (rssi < -50 && rssi >= -60) + { + res = 5; //"Very good"; + } + else if (rssi < -60 && rssi >= -70) + { + res = 4; //"Good"; + } + else if (rssi < -70 && rssi >= -80) + { + res = 3; //"Low"; + } + else if (rssi < -80 && rssi > -100) + { + res = 2; //"Very low"; + } + else if (rssi <= -100) + { + res = 1; //"No signal"; + } + } + return res; } diff --git a/tools/large_spiffs_16MB.csv b/tools/large_spiffs_16MB.csv new file mode 100644 index 00000000..2fd72050 --- /dev/null +++ b/tools/large_spiffs_16MB.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x480000, +app1, app, ota_1, 0x490000,0x480000, +spiffs, data, spiffs, 0x910000,0x6E0000, +coredump, data, coredump,0xFF0000,0x10000, \ No newline at end of file diff --git a/tools/patch8266_16m.py b/tools/patch8266_16m.py new file mode 100644 index 00000000..048290f8 --- /dev/null +++ b/tools/patch8266_16m.py @@ -0,0 +1,16 @@ +# правим %USERPROFILE%\.platformio\platforms\espressif8266\builder\main.py 103-115 +# для добавления возможности прошивки 16мб модуля esp8266 + +import os +import shutil + + +mainPyPath = os.environ['USERPROFILE'] + '\\.platformio\\platforms\\espressif8266@4.0.1\\builder\\main.py' + +with open(mainPyPath) as fr: + oldData = fr.read() + if not 'if _value == -0x6000:' in oldData: + shutil.copyfile(mainPyPath, mainPyPath+'.bak') + newData = oldData.replace('_value += 0xE00000 # correction', '_value += 0xE00000 # correction\n\n if _value == -0x6000:\n _value = env[k]-0x40200000') + with open(mainPyPath, 'w') as fw: + fw.write(newData) \ No newline at end of file diff --git a/webConfigMyProfile/build/bundle.js b/webConfigMyProfile/build/bundle.js index b0ced366..bfe7e3b3 100644 --- a/webConfigMyProfile/build/bundle.js +++ b/webConfigMyProfile/build/bundle.js @@ -1,5 +1,616 @@ -var app=function(){"use strict";function t(){}const e=t=>t;function n(t,e){for(const n in e)t[n]=e[n];return t}function o(t){return t()}function r(){return Object.create(null)}function l(t){t.forEach(o)}function i(t){return"function"==typeof t}function s(t,e){return t!=t?e==e:t!==e||t&&"object"==typeof t||"function"==typeof t}function c(t,e,n,o){if(t){const r=a(t,e,n,o);return t[0](r)}}function a(t,e,o,r){return t[1]&&r?n(o.ctx.slice(),t[1](r(e))):o.ctx}function u(t,e,n,o){if(t[2]&&o){const r=t[2](o(n));if(void 0===e.dirty)return r;if("object"==typeof r){const t=[],n=Math.max(e.dirty.length,r.length);for(let o=0;o32){const e=[],n=t.ctx.length/32;for(let t=0;twindow.performance.now():()=>Date.now(),m=p?t=>requestAnimationFrame(t):t;const g=new Set;function v(t){g.forEach((e=>{e.c(t)||(g.delete(e),e.f())})),0!==g.size&&m(v)}function $(t){let e;return 0===g.size&&m(v),{promise:new Promise((n=>{g.add(e={c:t,f:n})})),abort(){g.delete(e)}}}function b(t,e){t.appendChild(e)}function y(t){if(!t)return document;const e=t.getRootNode?t.getRootNode():t.ownerDocument;return e&&e.host?e:t.ownerDocument}function x(t){const e=S("style");return function(t,e){b(t.head||t,e),e.sheet}(y(t),e),e.sheet}function _(t,e,n){t.insertBefore(e,n||null)}function w(t){t.parentNode.removeChild(t)}function k(t,e){for(let n=0;nt.removeEventListener(e,n,o)}function P(t,e,n){null==n?t.removeAttribute(e):t.getAttribute(e)!==n&&t.setAttribute(e,n)}function q(t,e){e=""+e,t.wholeText!==e&&(t.data=e)}function M(t,e){t.value=null==e?"":e}function I(t,e,n,o){null===n?t.style.removeProperty(e):t.style.setProperty(e,n,o?"important":"")}function T(t,e){for(let n=0;n>>0}(u)}_${s}`,d=y(t),{stylesheet:p,rules:h}=G.get(d)||function(t,e){const n={stylesheet:x(e),rules:{}};return G.set(t,n),n}(d,t);h[f]||(h[f]=!0,p.insertRule(`@keyframes ${f} ${u}`,p.cssRules.length));const m=t.style.animation||"";return t.style.animation=`${m?`${m}, `:""}${f} ${o}ms linear ${r}ms 1 both`,U+=1,f}function A(t,e){const n=(t.style.animation||"").split(", "),o=n.filter(e?t=>t.indexOf(e)<0:t=>-1===t.indexOf("__svelte")),r=n.length-o.length;r&&(t.style.animation=o.join(", "),U-=r,U||m((()=>{U||(G.forEach((t=>{const{ownerNode:e}=t.stylesheet;e&&w(e)})),G.clear())})))}function F(n,o,r,l){if(!o)return t;const i=n.getBoundingClientRect();if(o.left===i.left&&o.right===i.right&&o.top===i.top&&o.bottom===i.bottom)return t;const{delay:s=0,duration:c=300,easing:a=e,start:u=h()+s,end:f=u+c,tick:d=t,css:p}=r(n,{from:o,to:i},l);let m,g=!0,v=!1;function b(){p&&A(n,m),g=!1}return $((t=>{if(!v&&t>=u&&(v=!0),v&&t>=f&&(d(1,0),b()),!g)return!1;if(v){const e=0+1*a((t-u)/c);d(e,1-e)}return!0})),p&&(m=D(n,0,1,c,s,a,p)),s||(v=!0),d(0,1),b}function L(t){const e=getComputedStyle(t);if("absolute"!==e.position&&"fixed"!==e.position){const{width:n,height:o}=e,r=t.getBoundingClientRect();t.style.position="absolute",t.style.width=n,t.style.height=o,J(t,r)}}function J(t,e){const n=t.getBoundingClientRect();if(e.left!==n.left||e.top!==n.top){const o=getComputedStyle(t),r="none"===o.transform?"":o.transform;t.style.transform=`${r} translate(${e.left-n.left}px, ${e.top-n.top}px)`}}function V(t){B=t}function z(){if(!B)throw new Error("Function called outside component initialization");return B}const K=[],H=[],Q=[],W=[],X=Promise.resolve();let Y=!1;function Z(t){Q.push(t)}function tt(t){W.push(t)}const et=new Set;let nt,ot=0;function rt(){const t=B;do{for(;ot{nt=null}))),nt}function st(t,e,n){t.dispatchEvent(R(`${e?"intro":"outro"}${n}`))}const ct=new Set;let at;function ut(){at={r:0,c:[],p:at}}function ft(){at.r||l(at.c),at=at.p}function dt(t,e){t&&t.i&&(ct.delete(t),t.i(e))}function pt(t,e,n,o){if(t&&t.o){if(ct.has(t))return;ct.add(t),at.c.push((()=>{ct.delete(t),o&&(n&&t.d(1),o())})),t.o(e)}else o&&o()}const ht={duration:0};function mt(n,o,r){let l,s,c=o(n,r),a=!1,u=0;function f(){l&&A(n,l)}function d(){const{delay:o=0,duration:r=300,easing:i=e,tick:d=t,css:p}=c||ht;p&&(l=D(n,0,1,r,o,i,p,u++)),d(0,1);const m=h()+o,g=m+r;s&&s.abort(),a=!0,Z((()=>st(n,!0,"start"))),s=$((t=>{if(a){if(t>=g)return d(1,0),st(n,!0,"end"),f(),a=!1;if(t>=m){const e=i((t-m)/r);d(e,1-e)}}return a}))}let p=!1;return{start(){p||(p=!0,A(n),i(c)?(c=c(),it().then(d)):d())},invalidate(){p=!1},end(){a&&(f(),a=!1)}}}function gt(n,o,r){let s,c=o(n,r),a=!0;const u=at;function f(){const{delay:o=0,duration:r=300,easing:i=e,tick:f=t,css:d}=c||ht;d&&(s=D(n,1,0,r,o,i,d));const p=h()+o,m=p+r;Z((()=>st(n,!1,"start"))),$((t=>{if(a){if(t>=m)return f(0,1),st(n,!1,"end"),--u.r||l(u.c),!1;if(t>=p){const e=i((t-p)/r);f(1-e,e)}}return a}))}return u.r+=1,i(c)?it().then((()=>{c=c(),f()})):f(),{end(t){t&&c.tick&&c.tick(1,0),a&&(s&&A(n,s),a=!1)}}}function vt(t,e){t.f(),function(t,e){pt(t,1,1,(()=>{e.delete(t.key)}))}(t,e)}function $t(t,e,n,o,r,l,i,s,c,a,u,f){let d=t.length,p=l.length,h=d;const m={};for(;h--;)m[t[h].key]=h;const g=[],v=new Map,$=new Map;for(h=p;h--;){const t=f(r,l,h),s=n(t);let c=i.get(s);c?o&&c.p(t,e):(c=a(s,t),c.c()),v.set(s,g[h]=c),s in m&&$.set(s,Math.abs(h-m[s]))}const b=new Set,y=new Set;function x(t){dt(t,1),t.m(s,u),i.set(t.key,t),u=t.first,p--}for(;d&&p;){const e=g[p-1],n=t[d-1],o=e.key,r=n.key;e===n?(u=e.first,d--,p--):v.has(r)?!i.has(o)||b.has(o)?x(e):y.has(r)?d--:$.get(o)>$.get(r)?(y.add(o),x(e)):(b.add(r),d--):(c(n,i),d--)}for(;d--;){const e=t[d];v.has(e.key)||c(e,i)}for(;p;)x(g[p-1]);return g}function bt(t,e,n){const o=t.$$.props[e];void 0!==o&&(t.$$.bound[o]=n,n(t.$$.ctx[o]))}function yt(t){t&&t.c()}function xt(t,e,n,r){const{fragment:s,on_mount:c,on_destroy:a,after_update:u}=t.$$;s&&s.m(e,n),r||Z((()=>{const e=c.map(o).filter(i);a?a.push(...e):l(e),t.$$.on_mount=[]})),u.forEach(Z)}function _t(t,e){const n=t.$$;null!==n.fragment&&(l(n.on_destroy),n.fragment&&n.fragment.d(e),n.on_destroy=n.fragment=null,n.ctx=[])}function wt(t,e){-1===t.$$.dirty[0]&&(K.push(t),Y||(Y=!0,X.then(rt)),t.$$.dirty.fill(0)),t.$$.dirty[e/31|0]|=1<{const r=o.length?o[0]:n;return d.ctx&&s(d.ctx[t],d.ctx[t]=r)&&(!d.skip_bound&&d.bound[t]&&d.bound[t](r),p&&wt(e,t)),n})):[],d.update(),p=!0,l(d.before_update),d.fragment=!!i&&i(d.ctx),n.target){if(n.hydrate){const t=function(t){return Array.from(t.childNodes)}(n.target);d.fragment&&d.fragment.l(t),t.forEach(w)}else d.fragment&&d.fragment.c();n.intro&&dt(e.$$.fragment),xt(e,n.target,n.anchor,n.customElement),rt()}V(f)}class St{$destroy(){_t(this,1),this.$destroy=t}$on(t,e){const n=this.$$.callbacks[t]||(this.$$.callbacks[t]=[]);return n.push(e),()=>{const t=n.indexOf(e);-1!==t&&n.splice(t,1)}}$set(t){var e;this.$$set&&(e=t,0!==Object.keys(e).length)&&(this.$$.skip_bound=!0,this.$$set(t),this.$$.skip_bound=!1)}}function jt(t){const e=t-1;return e*e*e+1}function Ot(t){return--t*t*t*t*t+1} -/*! ***************************************************************************** +var app = (function () { + "use strict"; + function t() {} + const e = (t) => t; + function n(t, e) { + for (const n in e) t[n] = e[n]; + return t; + } + function o(t) { + return t(); + } + function r() { + return Object.create(null); + } + function l(t) { + t.forEach(o); + } + function i(t) { + return "function" == typeof t; + } + function s(t, e) { + return t != t + ? e == e + : t !== e || (t && "object" == typeof t) || "function" == typeof t; + } + function c(t, e, n, o) { + if (t) { + const r = a(t, e, n, o); + return t[0](r); + } + } + function a(t, e, o, r) { + return t[1] && r ? n(o.ctx.slice(), t[1](r(e))) : o.ctx; + } + function u(t, e, n, o) { + if (t[2] && o) { + const r = t[2](o(n)); + if (void 0 === e.dirty) return r; + if ("object" == typeof r) { + const t = [], + n = Math.max(e.dirty.length, r.length); + for (let o = 0; o < n; o += 1) t[o] = e.dirty[o] | r[o]; + return t; + } + return e.dirty | r; + } + return e.dirty; + } + function f(t, e, n, o, r, l) { + if (r) { + const i = a(e, n, o, l); + t.p(i, r); + } + } + function d(t) { + if (t.ctx.length > 32) { + const e = [], + n = t.ctx.length / 32; + for (let t = 0; t < n; t++) e[t] = -1; + return e; + } + return -1; + } + const p = "undefined" != typeof window; + let h = p ? () => window.performance.now() : () => Date.now(), + m = p ? (t) => requestAnimationFrame(t) : t; + const g = new Set(); + function v(t) { + g.forEach((e) => { + e.c(t) || (g.delete(e), e.f()); + }), + 0 !== g.size && m(v); + } + function $(t) { + let e; + return ( + 0 === g.size && m(v), + { + promise: new Promise((n) => { + g.add((e = { c: t, f: n })); + }), + abort() { + g.delete(e); + }, + } + ); + } + function b(t, e) { + t.appendChild(e); + } + function y(t) { + if (!t) return document; + const e = t.getRootNode ? t.getRootNode() : t.ownerDocument; + return e && e.host ? e : t.ownerDocument; + } + function x(t) { + const e = S("style"); + return ( + (function (t, e) { + b(t.head || t, e), e.sheet; + })(y(t), e), + e.sheet + ); + } + function _(t, e, n) { + t.insertBefore(e, n || null); + } + function w(t) { + t.parentNode.removeChild(t); + } + function k(t, e) { + for (let n = 0; n < t.length; n += 1) t[n] && t[n].d(e); + } + function S(t) { + return document.createElement(t); + } + function j(t) { + return document.createTextNode(t); + } + function O() { + return j(" "); + } + function C() { + return j(""); + } + function N(t, e, n, o) { + return t.addEventListener(e, n, o), () => t.removeEventListener(e, n, o); + } + function P(t, e, n) { + null == n + ? t.removeAttribute(e) + : t.getAttribute(e) !== n && t.setAttribute(e, n); + } + function q(t, e) { + (e = "" + e), t.wholeText !== e && (t.data = e); + } + function M(t, e) { + t.value = null == e ? "" : e; + } + function I(t, e, n, o) { + null === n + ? t.style.removeProperty(e) + : t.style.setProperty(e, n, o ? "important" : ""); + } + function T(t, e) { + for (let n = 0; n < t.options.length; n += 1) { + const o = t.options[n]; + if (o.__value === e) return void (o.selected = !0); + } + t.selectedIndex = -1; + } + function E(t) { + const e = t.querySelector(":checked") || t.options[0]; + return e && e.__value; + } + function R(t, e, { bubbles: n = !1, cancelable: o = !1 } = {}) { + const r = document.createEvent("CustomEvent"); + return r.initCustomEvent(t, n, o, e), r; + } + const G = new Map(); + let B, + U = 0; + function D(t, e, n, o, r, l, i, s = 0) { + const c = 16.666 / o; + let a = "{\n"; + for (let t = 0; t <= 1; t += c) { + const o = e + (n - e) * l(t); + a += 100 * t + `%{${i(o, 1 - o)}}\n`; + } + const u = a + `100% {${i(n, 1 - n)}}\n}`, + f = `__svelte_${(function (t) { + let e = 5381, + n = t.length; + for (; n--; ) e = ((e << 5) - e) ^ t.charCodeAt(n); + return e >>> 0; + })(u)}_${s}`, + d = y(t), + { stylesheet: p, rules: h } = + G.get(d) || + (function (t, e) { + const n = { stylesheet: x(e), rules: {} }; + return G.set(t, n), n; + })(d, t); + h[f] || + ((h[f] = !0), p.insertRule(`@keyframes ${f} ${u}`, p.cssRules.length)); + const m = t.style.animation || ""; + return ( + (t.style.animation = `${ + m ? `${m}, ` : "" + }${f} ${o}ms linear ${r}ms 1 both`), + (U += 1), + f + ); + } + function A(t, e) { + const n = (t.style.animation || "").split(", "), + o = n.filter( + e ? (t) => t.indexOf(e) < 0 : (t) => -1 === t.indexOf("__svelte") + ), + r = n.length - o.length; + r && + ((t.style.animation = o.join(", ")), + (U -= r), + U || + m(() => { + U || + (G.forEach((t) => { + const { ownerNode: e } = t.stylesheet; + e && w(e); + }), + G.clear()); + })); + } + function F(n, o, r, l) { + if (!o) return t; + const i = n.getBoundingClientRect(); + if ( + o.left === i.left && + o.right === i.right && + o.top === i.top && + o.bottom === i.bottom + ) + return t; + const { + delay: s = 0, + duration: c = 300, + easing: a = e, + start: u = h() + s, + end: f = u + c, + tick: d = t, + css: p, + } = r(n, { from: o, to: i }, l); + let m, + g = !0, + v = !1; + function b() { + p && A(n, m), (g = !1); + } + return ( + $((t) => { + if ((!v && t >= u && (v = !0), v && t >= f && (d(1, 0), b()), !g)) + return !1; + if (v) { + const e = 0 + 1 * a((t - u) / c); + d(e, 1 - e); + } + return !0; + }), + p && (m = D(n, 0, 1, c, s, a, p)), + s || (v = !0), + d(0, 1), + b + ); + } + function L(t) { + const e = getComputedStyle(t); + if ("absolute" !== e.position && "fixed" !== e.position) { + const { width: n, height: o } = e, + r = t.getBoundingClientRect(); + (t.style.position = "absolute"), + (t.style.width = n), + (t.style.height = o), + J(t, r); + } + } + function J(t, e) { + const n = t.getBoundingClientRect(); + if (e.left !== n.left || e.top !== n.top) { + const o = getComputedStyle(t), + r = "none" === o.transform ? "" : o.transform; + t.style.transform = `${r} translate(${e.left - n.left}px, ${ + e.top - n.top + }px)`; + } + } + function V(t) { + B = t; + } + function z() { + if (!B) throw new Error("Function called outside component initialization"); + return B; + } + const K = [], + H = [], + Q = [], + W = [], + X = Promise.resolve(); + let Y = !1; + function Z(t) { + Q.push(t); + } + function tt(t) { + W.push(t); + } + const et = new Set(); + let nt, + ot = 0; + function rt() { + const t = B; + do { + for (; ot < K.length; ) { + const t = K[ot]; + ot++, V(t), lt(t.$$); + } + for (V(null), K.length = 0, ot = 0; H.length; ) H.pop()(); + for (let t = 0; t < Q.length; t += 1) { + const e = Q[t]; + et.has(e) || (et.add(e), e()); + } + Q.length = 0; + } while (K.length); + for (; W.length; ) W.pop()(); + (Y = !1), et.clear(), V(t); + } + function lt(t) { + if (null !== t.fragment) { + t.update(), l(t.before_update); + const e = t.dirty; + (t.dirty = [-1]), + t.fragment && t.fragment.p(t.ctx, e), + t.after_update.forEach(Z); + } + } + function it() { + return ( + nt || + ((nt = Promise.resolve()), + nt.then(() => { + nt = null; + })), + nt + ); + } + function st(t, e, n) { + t.dispatchEvent(R(`${e ? "intro" : "outro"}${n}`)); + } + const ct = new Set(); + let at; + function ut() { + at = { r: 0, c: [], p: at }; + } + function ft() { + at.r || l(at.c), (at = at.p); + } + function dt(t, e) { + t && t.i && (ct.delete(t), t.i(e)); + } + function pt(t, e, n, o) { + if (t && t.o) { + if (ct.has(t)) return; + ct.add(t), + at.c.push(() => { + ct.delete(t), o && (n && t.d(1), o()); + }), + t.o(e); + } else o && o(); + } + const ht = { duration: 0 }; + function mt(n, o, r) { + let l, + s, + c = o(n, r), + a = !1, + u = 0; + function f() { + l && A(n, l); + } + function d() { + const { + delay: o = 0, + duration: r = 300, + easing: i = e, + tick: d = t, + css: p, + } = c || ht; + p && (l = D(n, 0, 1, r, o, i, p, u++)), d(0, 1); + const m = h() + o, + g = m + r; + s && s.abort(), + (a = !0), + Z(() => st(n, !0, "start")), + (s = $((t) => { + if (a) { + if (t >= g) return d(1, 0), st(n, !0, "end"), f(), (a = !1); + if (t >= m) { + const e = i((t - m) / r); + d(e, 1 - e); + } + } + return a; + })); + } + let p = !1; + return { + start() { + p || ((p = !0), A(n), i(c) ? ((c = c()), it().then(d)) : d()); + }, + invalidate() { + p = !1; + }, + end() { + a && (f(), (a = !1)); + }, + }; + } + function gt(n, o, r) { + let s, + c = o(n, r), + a = !0; + const u = at; + function f() { + const { + delay: o = 0, + duration: r = 300, + easing: i = e, + tick: f = t, + css: d, + } = c || ht; + d && (s = D(n, 1, 0, r, o, i, d)); + const p = h() + o, + m = p + r; + Z(() => st(n, !1, "start")), + $((t) => { + if (a) { + if (t >= m) return f(0, 1), st(n, !1, "end"), --u.r || l(u.c), !1; + if (t >= p) { + const e = i((t - p) / r); + f(1 - e, e); + } + } + return a; + }); + } + return ( + (u.r += 1), + i(c) + ? it().then(() => { + (c = c()), f(); + }) + : f(), + { + end(t) { + t && c.tick && c.tick(1, 0), a && (s && A(n, s), (a = !1)); + }, + } + ); + } + function vt(t, e) { + t.f(), + (function (t, e) { + pt(t, 1, 1, () => { + e.delete(t.key); + }); + })(t, e); + } + function $t(t, e, n, o, r, l, i, s, c, a, u, f) { + let d = t.length, + p = l.length, + h = d; + const m = {}; + for (; h--; ) m[t[h].key] = h; + const g = [], + v = new Map(), + $ = new Map(); + for (h = p; h--; ) { + const t = f(r, l, h), + s = n(t); + let c = i.get(s); + c ? o && c.p(t, e) : ((c = a(s, t)), c.c()), + v.set(s, (g[h] = c)), + s in m && $.set(s, Math.abs(h - m[s])); + } + const b = new Set(), + y = new Set(); + function x(t) { + dt(t, 1), t.m(s, u), i.set(t.key, t), (u = t.first), p--; + } + for (; d && p; ) { + const e = g[p - 1], + n = t[d - 1], + o = e.key, + r = n.key; + e === n + ? ((u = e.first), d--, p--) + : v.has(r) + ? !i.has(o) || b.has(o) + ? x(e) + : y.has(r) + ? d-- + : $.get(o) > $.get(r) + ? (y.add(o), x(e)) + : (b.add(r), d--) + : (c(n, i), d--); + } + for (; d--; ) { + const e = t[d]; + v.has(e.key) || c(e, i); + } + for (; p; ) x(g[p - 1]); + return g; + } + function bt(t, e, n) { + const o = t.$$.props[e]; + void 0 !== o && ((t.$$.bound[o] = n), n(t.$$.ctx[o])); + } + function yt(t) { + t && t.c(); + } + function xt(t, e, n, r) { + const { fragment: s, on_mount: c, on_destroy: a, after_update: u } = t.$$; + s && s.m(e, n), + r || + Z(() => { + const e = c.map(o).filter(i); + a ? a.push(...e) : l(e), (t.$$.on_mount = []); + }), + u.forEach(Z); + } + function _t(t, e) { + const n = t.$$; + null !== n.fragment && + (l(n.on_destroy), + n.fragment && n.fragment.d(e), + (n.on_destroy = n.fragment = null), + (n.ctx = [])); + } + function wt(t, e) { + -1 === t.$$.dirty[0] && + (K.push(t), Y || ((Y = !0), X.then(rt)), t.$$.dirty.fill(0)), + (t.$$.dirty[(e / 31) | 0] |= 1 << e % 31); + } + function kt(e, n, o, i, s, c, a, u = [-1]) { + const f = B; + V(e); + const d = (e.$$ = { + fragment: null, + ctx: null, + props: c, + update: t, + not_equal: s, + bound: r(), + on_mount: [], + on_destroy: [], + on_disconnect: [], + before_update: [], + after_update: [], + context: new Map(n.context || (f ? f.$$.context : [])), + callbacks: r(), + dirty: u, + skip_bound: !1, + root: n.target || f.$$.root, + }); + a && a(d.root); + let p = !1; + if ( + ((d.ctx = o + ? o(e, n.props || {}, (t, n, ...o) => { + const r = o.length ? o[0] : n; + return ( + d.ctx && + s(d.ctx[t], (d.ctx[t] = r)) && + (!d.skip_bound && d.bound[t] && d.bound[t](r), p && wt(e, t)), + n + ); + }) + : []), + d.update(), + (p = !0), + l(d.before_update), + (d.fragment = !!i && i(d.ctx)), + n.target) + ) { + if (n.hydrate) { + const t = (function (t) { + return Array.from(t.childNodes); + })(n.target); + d.fragment && d.fragment.l(t), t.forEach(w); + } else d.fragment && d.fragment.c(); + n.intro && dt(e.$$.fragment), + xt(e, n.target, n.anchor, n.customElement), + rt(); + } + V(f); + } + class St { + $destroy() { + _t(this, 1), (this.$destroy = t); + } + $on(t, e) { + const n = this.$$.callbacks[t] || (this.$$.callbacks[t] = []); + return ( + n.push(e), + () => { + const t = n.indexOf(e); + -1 !== t && n.splice(t, 1); + } + ); + } + $set(t) { + var e; + this.$$set && + ((e = t), 0 !== Object.keys(e).length) && + ((this.$$.skip_bound = !0), this.$$set(t), (this.$$.skip_bound = !1)); + } + } + function jt(t) { + const e = t - 1; + return e * e * e + 1; + } + function Ot(t) { + return --t * t * t * t * t + 1; + } + /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any @@ -12,5 +623,2265 @@ var app=function(){"use strict";function t(){}const e=t=>t;function n(t,e){for(c LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ***************************************************************************** */function Ct(t){var{fallback:e}=t,o=function(t,e){var n={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&e.indexOf(o)<0&&(n[o]=t[o]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(o=Object.getOwnPropertySymbols(t);r(t.set(c.key,{rect:s.getBoundingClientRect()}),()=>{if(r.has(c.key)){const{rect:t}=r.get(c.key);return r.delete(c.key),function(t,e,r){const{delay:l=0,duration:s=(t=>30*Math.sqrt(t)),easing:c=jt}=n(n({},o),r),a=e.getBoundingClientRect(),u=t.left-a.left,f=t.top-a.top,d=t.width/a.width,p=t.height/a.height,h=Math.sqrt(u*u+f*f),m=getComputedStyle(e),g="none"===m.transform?"":m.transform,v=+m.opacity;return{delay:l,duration:i(s)?s(h):s,easing:c,css:(t,e)=>`\n\t\t\t\topacity: ${t*v};\n\t\t\t\ttransform-origin: top left;\n\t\t\t\ttransform: ${g} translate(${e*u}px,${e*f}px) scale(${t+(1-t)*d}, ${t+(1-t)*p});\n\t\t\t`}}(t,s,c)}return t.delete(c.key),e&&e(s,c,l)})}return[s(l,r,!1),s(r,l,!0)]}function Nt(t,{from:e,to:n},o={}){const r=getComputedStyle(t),l="none"===r.transform?"":r.transform,[s,c]=r.transformOrigin.split(" ").map(parseFloat),a=e.left+e.width*s/n.width-(n.left+s),u=e.top+e.height*c/n.height-(n.top+c),{delay:f=0,duration:d=(t=>120*Math.sqrt(t)),easing:p=jt}=o;return{delay:f,duration:i(d)?d(Math.sqrt(a*a+u*u)):d,easing:p,css:(t,o)=>{const r=o*a,i=o*u,s=t+o*e.width/n.width,c=t+o*e.height/n.height;return`transform: ${l} translate(${r}px, ${i}px) scale(${s}, ${c});`}}}function Pt(e){let n,o,r,l,i,s,c,a,u,f,d;return{c(){n=S("div"),o=S("div"),r=S("div"),l=O(),i=S("div"),s=O(),c=S("div"),a=O(),u=S("div"),f=j(e[0]),d=j("%"),P(r,"class","gauge-fill gauge-bg svelte-1er7lpr"),P(i,"class","gauge-fill svelte-1er7lpr"),I(i,"transform","rotate(-"+e[2]+"deg)"),I(i,"box-shadow","inset 0 0 60px -5px "+e[1]),P(c,"class","gauge-white svelte-1er7lpr"),P(u,"class","gauge-value svelte-1er7lpr"),P(o,"class","gauge-overflow svelte-1er7lpr"),P(n,"class","gauge svelte-1er7lpr")},m(t,e){_(t,n,e),b(n,o),b(o,r),b(o,l),b(o,i),b(o,s),b(o,c),b(o,a),b(o,u),b(u,f),b(u,d)},p(t,[e]){4&e&&I(i,"transform","rotate(-"+t[2]+"deg)"),2&e&&I(i,"box-shadow","inset 0 0 60px -5px "+t[1]),1&e&&q(f,t[0])},i:t,o:t,d(t){t&&w(n)}}}function qt(t,e,n){let o,r,{title:l}=e,{value:i=l}=e,{thresholds:s="90,100"}=e,{colors:c="#7CFC00,#FFD700,#FF0000"}=e;return t.$$set=t=>{"title"in t&&n(3,l=t.title),"value"in t&&n(0,i=t.value),"thresholds"in t&&n(4,s=t.thresholds),"colors"in t&&n(5,c=t.colors)},t.$$.update=()=>{if(49&t.$$.dirty){const t=String(s).split(","),e=t.indexOf(t.find((t=>i({}),Tt=t=>({});function Et(t){let e,n,o,r,i,s,a,p,h,m,g,v,$;const y=t[4].header,x=c(y,t,t[3],Tt),k=t[4].default,j=c(k,t,t[3],null);return{c(){e=S("div"),n=O(),o=S("div"),x&&x.c(),r=O(),i=S("hr"),s=O(),j&&j.c(),a=O(),p=S("hr"),h=O(),m=S("button"),m.textContent="Close",P(e,"class","modal-background svelte-5a6h72"),I(m,"float","right"),I(m,"margin-right","2%"),I(m,"border","1px solid lightblue"),I(m,"border-radius","8px"),m.autofocus=!0,P(m,"class","svelte-5a6h72"),P(o,"class","modal svelte-5a6h72"),P(o,"role","dialog"),P(o,"aria-modal","true")},m(l,c){_(l,e,c),_(l,n,c),_(l,o,c),x&&x.m(o,null),b(o,r),b(o,i),b(o,s),j&&j.m(o,null),b(o,a),b(o,p),b(o,h),b(o,m),t[5](o),g=!0,m.focus(),v||($=[N(window,"keydown",t[2]),N(e,"click",t[1]),N(m,"click",t[1])],v=!0)},p(t,[e]){x&&x.p&&(!g||8&e)&&f(x,y,t,t[3],g?u(y,t[3],e,It):d(t[3]),Tt),j&&j.p&&(!g||8&e)&&f(j,k,t,t[3],g?u(k,t[3],e,null):d(t[3]),null)},i(t){g||(dt(x,t),dt(j,t),g=!0)},o(t){pt(x,t),pt(j,t),g=!1},d(r){r&&w(e),r&&w(n),r&&w(o),x&&x.d(r),j&&j.d(r),t[5](null),v=!1,l($)}}}function Rt(t,e,n){let{$$slots:o={},$$scope:r}=e;const l=function(){const t=z();return(e,n,{cancelable:o=!1}={})=>{const r=t.$$.callbacks[e];if(r){const l=R(e,n,{cancelable:o});return r.slice().forEach((e=>{e.call(t,l)})),!l.defaultPrevented}return!0}}(),i=()=>l("close");let s;const c="undefined"!=typeof document&&document.activeElement;var a;return c&&(a=()=>{c.focus()},z().$$.on_destroy.push(a)),t.$$set=t=>{"$$scope"in t&&n(3,r=t.$$scope)},[s,i,t=>{if("Escape"!==t.key){if("Tab"===t.key){const e=s.querySelectorAll("*"),n=Array.from(e).filter((t=>t.tabIndex>=0));let o=n.indexOf(document.activeElement);-1===o&&t.shiftKey&&(o=0),o+=n.length+(t.shiftKey?-1:1),o%=n.length,n[o].focus(),t.preventDefault()}}else i()},r,o,function(t){H[t?"unshift":"push"]((()=>{s=t,n(0,s)}))}]}class Gt extends St{constructor(t){super(),kt(this,t,Rt,Et,s,{})}}function Bt(t){let e,n;const o=t[1].default,r=c(o,t,t[0],null);return{c(){e=S("div"),r&&r.c(),P(e,"class","box svelte-1q88uwi")},m(t,o){_(t,e,o),r&&r.m(e,null),n=!0},p(t,[e]){r&&r.p&&(!n||1&e)&&f(r,o,t,t[0],n?u(o,t[0],e,null):d(t[0]),null)},i(t){n||(dt(r,t),n=!0)},o(t){pt(r,t),n=!1},d(t){t&&w(e),r&&r.d(t)}}}function Ut(t,e,n){let{$$slots:o={},$$scope:r}=e;return t.$$set=t=>{"$$scope"in t&&n(0,r=t.$$scope)},[r,o]}class Dt extends St{constructor(t){super(),kt(this,t,Ut,Bt,s,{})}}function At(t,e,n){const o=t.slice();return o[62]=e[n],o}function Ft(t,e,n){const o=t.slice();return o[65]=e[n],o}function Lt(t,e,n){const o=t.slice();return o[68]=e[n][0],o[69]=e[n][1],o}function Jt(t,e,n){const o=t.slice();return o[68]=e[n][0],o[69]=e[n][1],o}function Vt(t,e,n){const o=t.slice();return o[74]=e[n],o[75]=e,o[76]=n,o}function zt(t,e,n){const o=t.slice();return o[68]=e[n][0],o[69]=e[n][1],o}function Kt(t,e,n){const o=t.slice();return o[74]=e[n],o[79]=e,o[80]=n,o}function Ht(t,e,n){const o=t.slice();return o[81]=e[n],o}function Qt(t){let e,n,o,r;function l(e){t[19](e)}let i={};return void 0!==t[1]&&(i.value=t[1]),e=new Mt({props:i}),H.push((()=>bt(e,"value",l))),{c(){yt(e.$$.fragment),o=j("                   ")},m(t,n){xt(e,t,n),_(t,o,n),r=!0},p(t,o){const r={};!n&&2&o[0]&&(n=!0,r.value=t[1],tt((()=>n=!1))),e.$set(r)},i(t){r||(dt(e.$$.fragment,t),r=!0)},o(t){pt(e.$$.fragment,t),r=!1},d(t){_t(e,t),t&&w(o)}}}function Wt(t){let e,n,o,r;function l(e){t[20](e)}let i={};return void 0!==t[1]&&(i.value=t[1]),e=new Mt({props:i}),H.push((()=>bt(e,"value",l))),{c(){yt(e.$$.fragment),o=j("                   ")},m(t,n){xt(e,t,n),_(t,o,n),r=!0},p(t,o){const r={};!n&&2&o[0]&&(n=!0,r.value=t[1],tt((()=>n=!1))),e.$set(r)},i(t){r||(dt(e.$$.fragment,t),r=!0)},o(t){pt(e.$$.fragment,t),r=!1},d(t){_t(e,t),t&&w(o)}}}function Xt(t){let e,n,o,r;function l(e){t[21](e)}let i={};return void 0!==t[1]&&(i.value=t[1]),e=new Mt({props:i}),H.push((()=>bt(e,"value",l))),{c(){yt(e.$$.fragment),o=j("                   ")},m(t,n){xt(e,t,n),_(t,o,n),r=!0},p(t,o){const r={};!n&&2&o[0]&&(n=!0,r.value=t[1],tt((()=>n=!1))),e.$set(r)},i(t){r||(dt(e.$$.fragment,t),r=!0)},o(t){pt(e.$$.fragment,t),r=!1},d(t){_t(e,t),t&&w(o)}}}function Yt(t){let e,n,o,r;function l(e){t[22](e)}let i={};return void 0!==t[1]&&(i.value=t[1]),e=new Mt({props:i}),H.push((()=>bt(e,"value",l))),{c(){yt(e.$$.fragment),o=j("                   ")},m(t,n){xt(e,t,n),_(t,o,n),r=!0},p(t,o){const r={};!n&&2&o[0]&&(n=!0,r.value=t[1],tt((()=>n=!1))),e.$set(r)},i(t){r||(dt(e.$$.fragment,t),r=!0)},o(t){pt(e.$$.fragment,t),r=!1},d(t){_t(e,t),t&&w(o)}}}function Zt(e){let n,o,r,l=e[81].text+"";return{c(){n=S("option"),o=j(l),r=O(),n.__value=e[81],n.value=n.__value},m(t,e){_(t,n,e),b(n,o),b(n,r)},p:t,d(t){t&&w(n)}}}function te(e){let n,o,r,l=e[81].text+"";return{c(){n=S("option"),o=j(l),r=O(),n.__value=e[81],n.value=n.__value},m(t,e){_(t,n,e),b(n,o),b(n,r)},p:t,d(t){t&&w(n)}}}function ee(e){let n,o,r,l=e[81].text+"";return{c(){n=S("option"),o=j(l),r=O(),n.__value=e[81],n.value=n.__value},m(t,e){_(t,n,e),b(n,o),b(n,r)},p:t,d(t){t&&w(n)}}}function ne(t){let e;let n=function(t,e){return"esp8266_1mb"==t[81].text?ee:"esp8266_1mb_ota"==t[81].text?te:Zt}(t),o=n(t);return{c(){o.c(),e=C()},m(t,n){o.m(t,n),_(t,e,n)},p(t,e){o.p(t,e)},d(t){o.d(t),t&&w(e)}}}function oe(t){let e,n,o,r,i,s,c,a,u,f,d,p,h,m,g,v,$,y,x,k,C,q,T,E,R,G,B,U,D,A,F,L,J,V,z,K,H,Q;return{c(){e=S("p"),n=j("wifi сеть      "),o=S("input"),r=S("br"),i=O(),s=S("p"),c=j("пароль       "),a=S("input"),u=S("br"),f=O(),d=S("p"),p=j("MQTT сервер      "),h=S("input"),m=S("br"),g=O(),v=S("p"),$=j("порт       "),y=S("input"),x=S("br"),k=O(),C=S("p"),q=j("префикс      "),T=S("input"),E=S("br"),R=O(),G=S("p"),B=j("логин       "),U=S("input"),D=S("br"),A=O(),F=S("p"),L=j("пароль       "),J=S("input"),V=S("br"),z=O(),K=S("br"),I(o,"float","right"),P(o,"class","svelte-185rejv"),I(e,"color","#ccc"),I(a,"float","right"),P(a,"class","svelte-185rejv"),I(s,"color","#ccc"),I(h,"float","right"),P(h,"class","svelte-185rejv"),I(d,"color","#ccc"),I(y,"float","right"),P(y,"class","svelte-185rejv"),I(v,"color","#ccc"),I(T,"float","right"),P(T,"class","svelte-185rejv"),I(C,"color","#ccc"),I(U,"float","right"),P(U,"class","svelte-185rejv"),I(G,"color","#ccc"),I(J,"float","right"),P(J,"class","svelte-185rejv"),I(F,"color","#ccc")},m(l,w){_(l,e,w),b(e,n),b(e,o),M(o,t[0].iotmSettings.routerssid),b(e,r),_(l,i,w),_(l,s,w),b(s,c),b(s,a),M(a,t[0].iotmSettings.routerpass),b(s,u),_(l,f,w),_(l,d,w),b(d,p),b(d,h),M(h,t[0].iotmSettings.mqttServer),b(d,m),_(l,g,w),_(l,v,w),b(v,$),b(v,y),M(y,t[0].iotmSettings.mqttPort),b(v,x),_(l,k,w),_(l,C,w),b(C,q),b(C,T),M(T,t[0].iotmSettings.mqttPrefix),b(C,E),_(l,R,w),_(l,G,w),b(G,B),b(G,U),M(U,t[0].iotmSettings.mqttUser),b(G,D),_(l,A,w),_(l,F,w),b(F,L),b(F,J),M(J,t[0].iotmSettings.mqttPass),b(F,V),_(l,z,w),_(l,K,w),H||(Q=[N(o,"input",t[29]),N(a,"input",t[30]),N(h,"input",t[31]),N(y,"input",t[32]),N(T,"input",t[33]),N(U,"input",t[34]),N(J,"input",t[35])],H=!0)},p(t,e){1&e[0]&&o.value!==t[0].iotmSettings.routerssid&&M(o,t[0].iotmSettings.routerssid),1&e[0]&&a.value!==t[0].iotmSettings.routerpass&&M(a,t[0].iotmSettings.routerpass),1&e[0]&&h.value!==t[0].iotmSettings.mqttServer&&M(h,t[0].iotmSettings.mqttServer),1&e[0]&&y.value!==t[0].iotmSettings.mqttPort&&M(y,t[0].iotmSettings.mqttPort),1&e[0]&&T.value!==t[0].iotmSettings.mqttPrefix&&M(T,t[0].iotmSettings.mqttPrefix),1&e[0]&&U.value!==t[0].iotmSettings.mqttUser&&M(U,t[0].iotmSettings.mqttUser),1&e[0]&&J.value!==t[0].iotmSettings.mqttPass&&M(J,t[0].iotmSettings.mqttPass)},d(t){t&&w(e),t&&w(i),t&&w(s),t&&w(f),t&&w(d),t&&w(g),t&&w(v),t&&w(k),t&&w(C),t&&w(R),t&&w(G),t&&w(A),t&&w(F),t&&w(z),t&&w(K),H=!1,l(Q)}}}function re(t){let e,n,o,r,i,s,c,a,u,f,d,p,h,m,g,v,$,y,x,C,q,E,R,G,B,U,D,A,F,L="esp8266_4mb"==t[9].text&&Qt(t),J="esp32_4mb"==t[9].text&&Wt(t),V="esp8266_1mb"==t[9].text&&Xt(t),z="esp8266_1mb_ota"==t[9].text&&Yt(t),K=t[16],H=[];for(let e=0;et[23].call(s))),P(f,"align","right"),void 0===t[9]&&Z((()=>t[25].call(f))),P(e,"align","right"),I(m,"display",t[8]?"none":"inline"),I($,"display",t[8]?"inline":"none"),E.hidden=!0,P(E,"type","text"),P(E,"name","configpost"),P(E,"class","svelte-185rejv"),P(G,"align","center"),P(q,"action","index.php"),P(q,"method","post"),P(q,"name","fwbuilder"),P(U,"type","submit"),I(U,"border","1px solid lightblue"),I(U,"border-radius","8px"),P(U,"name","send"),U.value="Сохранить myProfile.json",P(U,"class","svelte-185rejv")},m(l,w){_(l,e,w),L&&L.m(e,null),b(e,n),J&&J.m(e,null),b(e,o),V&&V.m(e,null),b(e,r),z&&z.m(e,null),b(e,i),b(e,s),b(s,c),b(s,a),T(s,t[7]),b(e,u),b(e,f);for(let t=0;t{L=null})),ft()),"esp32_4mb"==t[9].text?J?(J.p(t,l),512&l[0]&&dt(J,1)):(J=Wt(t),J.c(),dt(J,1),J.m(e,o)):J&&(ut(),pt(J,1,1,(()=>{J=null})),ft()),"esp8266_1mb"==t[9].text?V?(V.p(t,l),512&l[0]&&dt(V,1)):(V=Xt(t),V.c(),dt(V,1),V.m(e,r)):V&&(ut(),pt(V,1,1,(()=>{V=null})),ft()),"esp8266_1mb_ota"==t[9].text?z?(z.p(t,l),512&l[0]&&dt(z,1)):(z=Yt(t),z.c(),dt(z,1),z.m(e,i)):z&&(ut(),pt(z,1,1,(()=>{z=null})),ft()),128&l[0]&&T(s,t[7]),65536&l[0]){let e;for(K=t[16],e=0;e{d&&d.end(1),f=mt(o,n[11],{key:n[74].path}),f.start()})),h=!0)},o(t){f&&f.invalidate(),d=gt(o,n[10],{key:n[74].path}),h=!1},d(t){t&&w(o),t&&d&&d.end(),m=!1,l(g)}}}function ie(t){let e,n,o,r,l,i,s=t[68]+"",c=[],a=new Map,u=t[0].modules[t[68]].filter($e);const f=t=>t[74].path;for(let e=0;e{d&&d.end(1),f=mt(o,n[11],{key:n[74].path}),f.start()})),h=!0)},o(t){f&&f.invalidate(),d=gt(o,n[10],{key:n[74].path}),h=!1},d(t){t&&w(o),t&&d&&d.end(),m=!1,l(g)}}}function ce(t){let e,n,o,r,l,i,s=t[68]+"",c=[],a=new Map,u=t[0].modules[t[68]].filter(be);const f=t=>t[74].path;for(let e=0;e2,d=f&&de(),p=t[62].params,h=[];for(let e=0;e2),f?d||(d=de(),d.c(),d.m(e,s)):d&&(d.d(1),d=null),16&n[0]){let o;for(p=t[62].params,o=0;opt(g[t],1,1,(()=>{g[t]=null}));let $=Object.entries(t[0].modules),y=[];for(let e=0;e<$.length;e+=1)y[e]=ce(Jt(t,$,e));const x=t=>pt(y[t],1,1,(()=>{y[t]=null}));let j=t[6]&&ae(t);return{c(){e=S("p"),yt(n.$$.fragment),o=O(),r=S("div"),l=S("div"),i=S("h2"),i.textContent="доступные модули",s=O();for(let t=0;t{j=null})),ft())},i(t){if(!h){dt(n.$$.fragment,t);for(let t=0;t!t.active,be=t=>t.active;function ye(t,e,n){let o="https://raw.githubusercontent.com/IoTManagerProject/IoTManager/ver4dev/myProfile.json?1",r={},l=0,i={},s=[],c=[],a=[],u=[],f=!1,d="dev",p={};async function h(t){try{let e=await fetch(t,{mode:"cors",method:"GET"});e.ok?n(0,r=await e.json()):console.log("error",e.statusText)}catch(t){console.log(t)}}r={iotmSettings:{},projectProp:{platformio:{}},modules:{"Виртуальные элементы":[],"Сенсоры":[],"Исполнительные устройства":[],"Экраны":[]}},h(o),async function(t){try{let e=await fetch(t,{mode:"cors",method:"GET"});e.ok?p=await e.json():console.log("error",e.statusText)}catch(t){console.log(t)}}("https://iotmanager.org/firmwarebuilder/moduleSize.json?1");const[m,g]=Ct({fallback(t,e){const n=getComputedStyle(t),o="none"===n.transform?"":n.transform;return{duration:600,easing:Ot,css:t=>`\n\t\t\t\t\ttransform: ${o} scale(${t});\n\t\t\t\t\topacity: ${t}\n\t\t\t\t`}}});function v(t){console.log(t.path),o="https://raw.githubusercontent.com/IoTManagerProject/IoTManager/ver4stable/"+JSON.parse(JSON.stringify(t.path).replace(/\\\\/g,"/"))+"/modinfo.json",i=[],n(2,s=[]),n(3,c=[]),n(3,c.name="Данные загружаются...",c),n(4,a=[]),n(5,u=[]),async function(t){i=[];try{let e=await fetch(t,{mode:"cors",method:"GET"});e.ok?(i=await e.json(),n(2,s=i),n(3,c=i.configItem[0]),n(4,a=i.about),n(5,u=a.propInfo)):console.log("error",e.statusText)}catch(t){console.log(t)}}(o),n(6,f=!0)}let $=!0;function b(t){n(8,$=t)}function y(){o="dev"==d?"https://raw.githubusercontent.com/IoTManagerProject/IoTManager/ver4dev/myProfile.json?1":"https://raw.githubusercontent.com/IoTManagerProject/IoTManager/ver4stable/myProfile.json?1",h(o)}function x(){n(1,l=0),n(0,r.projectProp.platformio.default_envs=_.text,r),k()}let _=[],w=[{id:1,text:"esp8266_4mb"},{id:2,text:"esp32_4mb"},{id:3,text:"esp8266_1mb"},{id:4,text:"esp8266_1mb_ota"}];function k(){n(1,l=0);for(const[t,e]of Object.entries(r.modules))for(const[e,o]of Object.entries(r.modules[t].filter((t=>t.active)))){let t=o.path.slice(o.path.lastIndexOf("/")+1,o.path.length);p[t]&&n(1,l+=Math.round(p[t][_.text]))}"esp8266_4mb"==_.text&&n(1,l=Math.round(l/6110)),"esp32_4mb"==_.text&&n(1,l=Math.round(l/3243)),"esp8266_1mb"==_.text&&n(1,l=Math.round(l/3237)),"esp8266_1mb_ota"==_.text&&n(1,l=Math.round(l/2601))}function S(){var t=document.createElement("a");t.href=window.URL.createObjectURL(new Blob([JSON.stringify(r)],{type:"text/plain"})),t.download="myProfile.json",console.log(JSON.stringify(r))}return[r,l,s,c,a,u,f,d,$,_,m,g,v,b,y,x,w,k,S,function(t){l=t,n(1,l)},function(t){l=t,n(1,l)},function(t){l=t,n(1,l)},function(t){l=t,n(1,l)},function(){d=E(this),n(7,d)},()=>y(),function(){_=E(this),n(9,_),n(16,w)},()=>x(),()=>b(!0),()=>b(!1),function(){r.iotmSettings.routerssid=this.value,n(0,r)},function(){r.iotmSettings.routerpass=this.value,n(0,r)},function(){r.iotmSettings.mqttServer=this.value,n(0,r)},function(){r.iotmSettings.mqttPort=this.value,n(0,r)},function(){r.iotmSettings.mqttPrefix=this.value,n(0,r)},function(){r.iotmSettings.mqttUser=this.value,n(0,r)},function(){r.iotmSettings.mqttPass=this.value,n(0,r)},function(){r=this.value,n(0,r)},()=>S(),function(t,e){t[e].active=this.checked,n(0,r)},t=>v(t),function(t,e){t[e].active=this.checked,n(0,r)},t=>v(t),()=>n(6,f=!1)]}return new class extends St{constructor(t){super(),kt(this,t,ye,ve,s,{},null,[-1,-1,-1])}}({target:document.body})}(); + ***************************************************************************** */ function Ct( + t + ) { + var { fallback: e } = t, + o = (function (t, e) { + var n = {}; + for (var o in t) + Object.prototype.hasOwnProperty.call(t, o) && + e.indexOf(o) < 0 && + (n[o] = t[o]); + if (null != t && "function" == typeof Object.getOwnPropertySymbols) { + var r = 0; + for (o = Object.getOwnPropertySymbols(t); r < o.length; r++) + e.indexOf(o[r]) < 0 && + Object.prototype.propertyIsEnumerable.call(t, o[r]) && + (n[o[r]] = t[o[r]]); + } + return n; + })(t, ["fallback"]); + const r = new Map(), + l = new Map(); + function s(t, r, l) { + return (s, c) => ( + t.set(c.key, { rect: s.getBoundingClientRect() }), + () => { + if (r.has(c.key)) { + const { rect: t } = r.get(c.key); + return ( + r.delete(c.key), + (function (t, e, r) { + const { + delay: l = 0, + duration: s = (t) => 30 * Math.sqrt(t), + easing: c = jt, + } = n(n({}, o), r), + a = e.getBoundingClientRect(), + u = t.left - a.left, + f = t.top - a.top, + d = t.width / a.width, + p = t.height / a.height, + h = Math.sqrt(u * u + f * f), + m = getComputedStyle(e), + g = "none" === m.transform ? "" : m.transform, + v = +m.opacity; + return { + delay: l, + duration: i(s) ? s(h) : s, + easing: c, + css: (t, e) => + `\n\t\t\t\topacity: ${ + t * v + };\n\t\t\t\ttransform-origin: top left;\n\t\t\t\ttransform: ${g} translate(${ + e * u + }px,${e * f}px) scale(${t + (1 - t) * d}, ${ + t + (1 - t) * p + });\n\t\t\t`, + }; + })(t, s, c) + ); + } + return t.delete(c.key), e && e(s, c, l); + } + ); + } + return [s(l, r, !1), s(r, l, !0)]; + } + function Nt(t, { from: e, to: n }, o = {}) { + const r = getComputedStyle(t), + l = "none" === r.transform ? "" : r.transform, + [s, c] = r.transformOrigin.split(" ").map(parseFloat), + a = e.left + (e.width * s) / n.width - (n.left + s), + u = e.top + (e.height * c) / n.height - (n.top + c), + { + delay: f = 0, + duration: d = (t) => 120 * Math.sqrt(t), + easing: p = jt, + } = o; + return { + delay: f, + duration: i(d) ? d(Math.sqrt(a * a + u * u)) : d, + easing: p, + css: (t, o) => { + const r = o * a, + i = o * u, + s = t + (o * e.width) / n.width, + c = t + (o * e.height) / n.height; + return `transform: ${l} translate(${r}px, ${i}px) scale(${s}, ${c});`; + }, + }; + } + function Pt(e) { + let n, o, r, l, i, s, c, a, u, f, d; + return { + c() { + (n = S("div")), + (o = S("div")), + (r = S("div")), + (l = O()), + (i = S("div")), + (s = O()), + (c = S("div")), + (a = O()), + (u = S("div")), + (f = j(e[0])), + (d = j("%")), + P(r, "class", "gauge-fill gauge-bg svelte-1er7lpr"), + P(i, "class", "gauge-fill svelte-1er7lpr"), + I(i, "transform", "rotate(-" + e[2] + "deg)"), + I(i, "box-shadow", "inset 0 0 60px -5px " + e[1]), + P(c, "class", "gauge-white svelte-1er7lpr"), + P(u, "class", "gauge-value svelte-1er7lpr"), + P(o, "class", "gauge-overflow svelte-1er7lpr"), + P(n, "class", "gauge svelte-1er7lpr"); + }, + m(t, e) { + _(t, n, e), + b(n, o), + b(o, r), + b(o, l), + b(o, i), + b(o, s), + b(o, c), + b(o, a), + b(o, u), + b(u, f), + b(u, d); + }, + p(t, [e]) { + 4 & e && I(i, "transform", "rotate(-" + t[2] + "deg)"), + 2 & e && I(i, "box-shadow", "inset 0 0 60px -5px " + t[1]), + 1 & e && q(f, t[0]); + }, + i: t, + o: t, + d(t) { + t && w(n); + }, + }; + } + function qt(t, e, n) { + let o, + r, + { title: l } = e, + { value: i = l } = e, + { thresholds: s = "90,100" } = e, + { colors: c = "#7CFC00,#FFD700,#FF0000" } = e; + return ( + (t.$$set = (t) => { + "title" in t && n(3, (l = t.title)), + "value" in t && n(0, (i = t.value)), + "thresholds" in t && n(4, (s = t.thresholds)), + "colors" in t && n(5, (c = t.colors)); + }), + (t.$$.update = () => { + if (49 & t.$$.dirty) { + const t = String(s).split(","), + e = t.indexOf(t.find((t) => i < parseInt(t, 10))), + r = String(c).split(","); + n(1, (o = r[e] || r[r.length - 1])); + } + 1 & t.$$.dirty && n(2, (r = 1.8 * (100 - i))); + }), + [i, o, r, l, s, c] + ); + } + class Mt extends St { + constructor(t) { + super(), + kt(this, t, qt, Pt, s, { + title: 3, + value: 0, + thresholds: 4, + colors: 5, + }); + } + } + const It = (t) => ({}), + Tt = (t) => ({}); + function Et(t) { + let e, n, o, r, i, s, a, p, h, m, g, v, $; + const y = t[4].header, + x = c(y, t, t[3], Tt), + k = t[4].default, + j = c(k, t, t[3], null); + return { + c() { + (e = S("div")), + (n = O()), + (o = S("div")), + x && x.c(), + (r = O()), + (i = S("hr")), + (s = O()), + j && j.c(), + (a = O()), + (p = S("hr")), + (h = O()), + (m = S("button")), + (m.textContent = "Close"), + P(e, "class", "modal-background svelte-5a6h72"), + I(m, "float", "right"), + I(m, "margin-right", "2%"), + I(m, "border", "1px solid lightblue"), + I(m, "border-radius", "8px"), + (m.autofocus = !0), + P(m, "class", "svelte-5a6h72"), + P(o, "class", "modal svelte-5a6h72"), + P(o, "role", "dialog"), + P(o, "aria-modal", "true"); + }, + m(l, c) { + _(l, e, c), + _(l, n, c), + _(l, o, c), + x && x.m(o, null), + b(o, r), + b(o, i), + b(o, s), + j && j.m(o, null), + b(o, a), + b(o, p), + b(o, h), + b(o, m), + t[5](o), + (g = !0), + m.focus(), + v || + (($ = [ + N(window, "keydown", t[2]), + N(e, "click", t[1]), + N(m, "click", t[1]), + ]), + (v = !0)); + }, + p(t, [e]) { + x && + x.p && + (!g || 8 & e) && + f(x, y, t, t[3], g ? u(y, t[3], e, It) : d(t[3]), Tt), + j && + j.p && + (!g || 8 & e) && + f(j, k, t, t[3], g ? u(k, t[3], e, null) : d(t[3]), null); + }, + i(t) { + g || (dt(x, t), dt(j, t), (g = !0)); + }, + o(t) { + pt(x, t), pt(j, t), (g = !1); + }, + d(r) { + r && w(e), + r && w(n), + r && w(o), + x && x.d(r), + j && j.d(r), + t[5](null), + (v = !1), + l($); + }, + }; + } + function Rt(t, e, n) { + let { $$slots: o = {}, $$scope: r } = e; + const l = (function () { + const t = z(); + return (e, n, { cancelable: o = !1 } = {}) => { + const r = t.$$.callbacks[e]; + if (r) { + const l = R(e, n, { cancelable: o }); + return ( + r.slice().forEach((e) => { + e.call(t, l); + }), + !l.defaultPrevented + ); + } + return !0; + }; + })(), + i = () => l("close"); + let s; + const c = "undefined" != typeof document && document.activeElement; + var a; + return ( + c && + ((a = () => { + c.focus(); + }), + z().$$.on_destroy.push(a)), + (t.$$set = (t) => { + "$$scope" in t && n(3, (r = t.$$scope)); + }), + [ + s, + i, + (t) => { + if ("Escape" !== t.key) { + if ("Tab" === t.key) { + const e = s.querySelectorAll("*"), + n = Array.from(e).filter((t) => t.tabIndex >= 0); + let o = n.indexOf(document.activeElement); + -1 === o && t.shiftKey && (o = 0), + (o += n.length + (t.shiftKey ? -1 : 1)), + (o %= n.length), + n[o].focus(), + t.preventDefault(); + } + } else i(); + }, + r, + o, + function (t) { + H[t ? "unshift" : "push"](() => { + (s = t), n(0, s); + }); + }, + ] + ); + } + class Gt extends St { + constructor(t) { + super(), kt(this, t, Rt, Et, s, {}); + } + } + function Bt(t) { + let e, n; + const o = t[1].default, + r = c(o, t, t[0], null); + return { + c() { + (e = S("div")), r && r.c(), P(e, "class", "box svelte-1q88uwi"); + }, + m(t, o) { + _(t, e, o), r && r.m(e, null), (n = !0); + }, + p(t, [e]) { + r && + r.p && + (!n || 1 & e) && + f(r, o, t, t[0], n ? u(o, t[0], e, null) : d(t[0]), null); + }, + i(t) { + n || (dt(r, t), (n = !0)); + }, + o(t) { + pt(r, t), (n = !1); + }, + d(t) { + t && w(e), r && r.d(t); + }, + }; + } + function Ut(t, e, n) { + let { $$slots: o = {}, $$scope: r } = e; + return ( + (t.$$set = (t) => { + "$$scope" in t && n(0, (r = t.$$scope)); + }), + [r, o] + ); + } + class Dt extends St { + constructor(t) { + super(), kt(this, t, Ut, Bt, s, {}); + } + } + function At(t, e, n) { + const o = t.slice(); + return (o[62] = e[n]), o; + } + function Ft(t, e, n) { + const o = t.slice(); + return (o[65] = e[n]), o; + } + function Lt(t, e, n) { + const o = t.slice(); + return (o[68] = e[n][0]), (o[69] = e[n][1]), o; + } + function Jt(t, e, n) { + const o = t.slice(); + return (o[68] = e[n][0]), (o[69] = e[n][1]), o; + } + function Vt(t, e, n) { + const o = t.slice(); + return (o[74] = e[n]), (o[75] = e), (o[76] = n), o; + } + function zt(t, e, n) { + const o = t.slice(); + return (o[68] = e[n][0]), (o[69] = e[n][1]), o; + } + function Kt(t, e, n) { + const o = t.slice(); + return (o[74] = e[n]), (o[79] = e), (o[80] = n), o; + } + function Ht(t, e, n) { + const o = t.slice(); + return (o[81] = e[n]), o; + } + function Qt(t) { + let e, n, o, r; + function l(e) { + t[19](e); + } + let i = {}; + return ( + void 0 !== t[1] && (i.value = t[1]), + (e = new Mt({ props: i })), + H.push(() => bt(e, "value", l)), + { + c() { + yt(e.$$.fragment), (o = j("                   ")); + }, + m(t, n) { + xt(e, t, n), _(t, o, n), (r = !0); + }, + p(t, o) { + const r = {}; + !n && 2 & o[0] && ((n = !0), (r.value = t[1]), tt(() => (n = !1))), + e.$set(r); + }, + i(t) { + r || (dt(e.$$.fragment, t), (r = !0)); + }, + o(t) { + pt(e.$$.fragment, t), (r = !1); + }, + d(t) { + _t(e, t), t && w(o); + }, + } + ); + } + function Wt(t) { + let e, n, o, r; + function l(e) { + t[20](e); + } + let i = {}; + return ( + void 0 !== t[1] && (i.value = t[1]), + (e = new Mt({ props: i })), + H.push(() => bt(e, "value", l)), + { + c() { + yt(e.$$.fragment), (o = j("                   ")); + }, + m(t, n) { + xt(e, t, n), _(t, o, n), (r = !0); + }, + p(t, o) { + const r = {}; + !n && 2 & o[0] && ((n = !0), (r.value = t[1]), tt(() => (n = !1))), + e.$set(r); + }, + i(t) { + r || (dt(e.$$.fragment, t), (r = !0)); + }, + o(t) { + pt(e.$$.fragment, t), (r = !1); + }, + d(t) { + _t(e, t), t && w(o); + }, + } + ); + } + function Xt(t) { + let e, n, o, r; + function l(e) { + t[21](e); + } + let i = {}; + return ( + void 0 !== t[1] && (i.value = t[1]), + (e = new Mt({ props: i })), + H.push(() => bt(e, "value", l)), + { + c() { + yt(e.$$.fragment), (o = j("                   ")); + }, + m(t, n) { + xt(e, t, n), _(t, o, n), (r = !0); + }, + p(t, o) { + const r = {}; + !n && 2 & o[0] && ((n = !0), (r.value = t[1]), tt(() => (n = !1))), + e.$set(r); + }, + i(t) { + r || (dt(e.$$.fragment, t), (r = !0)); + }, + o(t) { + pt(e.$$.fragment, t), (r = !1); + }, + d(t) { + _t(e, t), t && w(o); + }, + } + ); + } + function Yt(t) { + let e, n, o, r; + function l(e) { + t[22](e); + } + let i = {}; + return ( + void 0 !== t[1] && (i.value = t[1]), + (e = new Mt({ props: i })), + H.push(() => bt(e, "value", l)), + { + c() { + yt(e.$$.fragment), (o = j("                   ")); + }, + m(t, n) { + xt(e, t, n), _(t, o, n), (r = !0); + }, + p(t, o) { + const r = {}; + !n && 2 & o[0] && ((n = !0), (r.value = t[1]), tt(() => (n = !1))), + e.$set(r); + }, + i(t) { + r || (dt(e.$$.fragment, t), (r = !0)); + }, + o(t) { + pt(e.$$.fragment, t), (r = !1); + }, + d(t) { + _t(e, t), t && w(o); + }, + } + ); + } + function Zt(e) { + let n, + o, + r, + l = e[81].text + ""; + return { + c() { + (n = S("option")), + (o = j(l)), + (r = O()), + (n.__value = e[81]), + (n.value = n.__value); + }, + m(t, e) { + _(t, n, e), b(n, o), b(n, r); + }, + p: t, + d(t) { + t && w(n); + }, + }; + } + function te(e) { + let n, + o, + r, + l = e[81].text + ""; + return { + c() { + (n = S("option")), + (o = j(l)), + (r = O()), + (n.__value = e[81]), + (n.value = n.__value); + }, + m(t, e) { + _(t, n, e), b(n, o), b(n, r); + }, + p: t, + d(t) { + t && w(n); + }, + }; + } + function ee(e) { + let n, + o, + r, + l = e[81].text + ""; + return { + c() { + (n = S("option")), + (o = j(l)), + (r = O()), + (n.__value = e[81]), + (n.value = n.__value); + }, + m(t, e) { + _(t, n, e), b(n, o), b(n, r); + }, + p: t, + d(t) { + t && w(n); + }, + }; + } + function ne(t) { + let e; + let n = (function (t, e) { + return "esp8266_1mb" == t[81].text + ? ee + : "esp8266_1mb_ota" == t[81].text + ? te + : Zt; + })(t), + o = n(t); + return { + c() { + o.c(), (e = C()); + }, + m(t, n) { + o.m(t, n), _(t, e, n); + }, + p(t, e) { + o.p(t, e); + }, + d(t) { + o.d(t), t && w(e); + }, + }; + } + function oe(t) { + let e, + n, + o, + r, + i, + s, + c, + a, + u, + f, + d, + p, + h, + m, + g, + v, + $, + y, + x, + k, + C, + q, + T, + E, + R, + G, + B, + U, + D, + A, + F, + L, + J, + V, + z, + K, + H, + Q; + return { + c() { + (e = S("p")), + (n = j("wifi сеть      ")), + (o = S("input")), + (r = S("br")), + (i = O()), + (s = S("p")), + (c = j("пароль       ")), + (a = S("input")), + (u = S("br")), + (f = O()), + (d = S("p")), + (p = j("MQTT сервер      ")), + (h = S("input")), + (m = S("br")), + (g = O()), + (v = S("p")), + ($ = j("порт       ")), + (y = S("input")), + (x = S("br")), + (k = O()), + (C = S("p")), + (q = j("префикс      ")), + (T = S("input")), + (E = S("br")), + (R = O()), + (G = S("p")), + (B = j("логин       ")), + (U = S("input")), + (D = S("br")), + (A = O()), + (F = S("p")), + (L = j("пароль       ")), + (J = S("input")), + (V = S("br")), + (z = O()), + (K = S("br")), + I(o, "float", "right"), + P(o, "class", "svelte-185rejv"), + I(e, "color", "#ccc"), + I(a, "float", "right"), + P(a, "class", "svelte-185rejv"), + I(s, "color", "#ccc"), + I(h, "float", "right"), + P(h, "class", "svelte-185rejv"), + I(d, "color", "#ccc"), + I(y, "float", "right"), + P(y, "class", "svelte-185rejv"), + I(v, "color", "#ccc"), + I(T, "float", "right"), + P(T, "class", "svelte-185rejv"), + I(C, "color", "#ccc"), + I(U, "float", "right"), + P(U, "class", "svelte-185rejv"), + I(G, "color", "#ccc"), + I(J, "float", "right"), + P(J, "class", "svelte-185rejv"), + I(F, "color", "#ccc"); + }, + m(l, w) { + _(l, e, w), + b(e, n), + b(e, o), + M(o, t[0].iotmSettings.routerssid), + b(e, r), + _(l, i, w), + _(l, s, w), + b(s, c), + b(s, a), + M(a, t[0].iotmSettings.routerpass), + b(s, u), + _(l, f, w), + _(l, d, w), + b(d, p), + b(d, h), + M(h, t[0].iotmSettings.mqttServer), + b(d, m), + _(l, g, w), + _(l, v, w), + b(v, $), + b(v, y), + M(y, t[0].iotmSettings.mqttPort), + b(v, x), + _(l, k, w), + _(l, C, w), + b(C, q), + b(C, T), + M(T, t[0].iotmSettings.mqttPrefix), + b(C, E), + _(l, R, w), + _(l, G, w), + b(G, B), + b(G, U), + M(U, t[0].iotmSettings.mqttUser), + b(G, D), + _(l, A, w), + _(l, F, w), + b(F, L), + b(F, J), + M(J, t[0].iotmSettings.mqttPass), + b(F, V), + _(l, z, w), + _(l, K, w), + H || + ((Q = [ + N(o, "input", t[29]), + N(a, "input", t[30]), + N(h, "input", t[31]), + N(y, "input", t[32]), + N(T, "input", t[33]), + N(U, "input", t[34]), + N(J, "input", t[35]), + ]), + (H = !0)); + }, + p(t, e) { + 1 & e[0] && + o.value !== t[0].iotmSettings.routerssid && + M(o, t[0].iotmSettings.routerssid), + 1 & e[0] && + a.value !== t[0].iotmSettings.routerpass && + M(a, t[0].iotmSettings.routerpass), + 1 & e[0] && + h.value !== t[0].iotmSettings.mqttServer && + M(h, t[0].iotmSettings.mqttServer), + 1 & e[0] && + y.value !== t[0].iotmSettings.mqttPort && + M(y, t[0].iotmSettings.mqttPort), + 1 & e[0] && + T.value !== t[0].iotmSettings.mqttPrefix && + M(T, t[0].iotmSettings.mqttPrefix), + 1 & e[0] && + U.value !== t[0].iotmSettings.mqttUser && + M(U, t[0].iotmSettings.mqttUser), + 1 & e[0] && + J.value !== t[0].iotmSettings.mqttPass && + M(J, t[0].iotmSettings.mqttPass); + }, + d(t) { + t && w(e), + t && w(i), + t && w(s), + t && w(f), + t && w(d), + t && w(g), + t && w(v), + t && w(k), + t && w(C), + t && w(R), + t && w(G), + t && w(A), + t && w(F), + t && w(z), + t && w(K), + (H = !1), + l(Q); + }, + }; + } + function re(t) { + let e, + n, + o, + r, + i, + s, + c, + a, + u, + f, + d, + p, + h, + m, + g, + v, + $, + y, + x, + C, + q, + E, + R, + G, + B, + U, + D, + A, + F, + L = "esp8266_4mb" == t[9].text && Qt(t), + J = "esp32_4mb" == t[9].text && Wt(t), + V = "esp8266_1mb" == t[9].text && Xt(t), + z = "esp8266_1mb_ota" == t[9].text && Yt(t), + K = t[16], + H = []; + for (let e = 0; e < K.length; e += 1) H[e] = ne(Ht(t, K, e)); + let Q = t[8] && oe(t); + return { + c() { + (e = S("form")), + L && L.c(), + (n = O()), + J && J.c(), + (o = O()), + V && V.c(), + (r = O()), + z && z.c(), + (i = O()), + (s = S("select")), + (c = S("option")), + (c.textContent = "ver4dev"), + (a = S("option")), + (a.textContent = "stabile"), + (u = O()), + (f = S("select")); + for (let t = 0; t < H.length; t += 1) H[t].c(); + (d = O()), + (p = S("br")), + (h = O()), + (m = S("p")), + (g = j("⏬")), + (v = O()), + ($ = S("p")), + (y = j("⏫")), + (x = O()), + Q && Q.c(), + (C = O()), + (q = S("form")), + (E = S("input")), + (R = O()), + (G = S("p")), + (B = O()), + (U = S("input")), + (c.__value = "dev"), + (c.value = c.__value), + (a.__value = "stabile"), + (a.value = a.__value), + P(s, "align", "right"), + void 0 === t[7] && Z(() => t[23].call(s)), + P(f, "align", "right"), + void 0 === t[9] && Z(() => t[25].call(f)), + P(e, "align", "right"), + I(m, "display", t[8] ? "none" : "inline"), + I($, "display", t[8] ? "inline" : "none"), + (E.hidden = !0), + P(E, "type", "text"), + P(E, "name", "configpost"), + P(E, "class", "svelte-185rejv"), + P(G, "align", "center"), + P(q, "action", "index.php"), + P(q, "method", "post"), + P(q, "name", "fwbuilder"), + P(U, "type", "submit"), + I(U, "border", "1px solid lightblue"), + I(U, "border-radius", "8px"), + P(U, "name", "send"), + (U.value = "Сохранить myProfile.json"), + P(U, "class", "svelte-185rejv"); + }, + m(l, w) { + _(l, e, w), + L && L.m(e, null), + b(e, n), + J && J.m(e, null), + b(e, o), + V && V.m(e, null), + b(e, r), + z && z.m(e, null), + b(e, i), + b(e, s), + b(s, c), + b(s, a), + T(s, t[7]), + b(e, u), + b(e, f); + for (let t = 0; t < H.length; t += 1) H[t].m(f, null); + T(f, t[9]), + _(l, d, w), + _(l, p, w), + _(l, h, w), + _(l, m, w), + b(m, g), + _(l, v, w), + _(l, $, w), + b($, y), + _(l, x, w), + Q && Q.m(l, w), + _(l, C, w), + _(l, q, w), + b(q, E), + M(E, t[0]), + b(q, R), + b(q, G), + _(l, B, w), + _(l, U, w), + (D = !0), + A || + ((F = [ + N(s, "change", t[23]), + N(s, "change", t[24]), + N(f, "change", t[25]), + N(f, "change", t[26]), + N(m, "click", t[27]), + N($, "click", t[28]), + N(E, "input", t[36]), + N(U, "click", t[37]), + ]), + (A = !0)); + }, + p(t, l) { + if ( + ("esp8266_4mb" == t[9].text + ? L + ? (L.p(t, l), 512 & l[0] && dt(L, 1)) + : ((L = Qt(t)), L.c(), dt(L, 1), L.m(e, n)) + : L && + (ut(), + pt(L, 1, 1, () => { + L = null; + }), + ft()), + "esp32_4mb" == t[9].text + ? J + ? (J.p(t, l), 512 & l[0] && dt(J, 1)) + : ((J = Wt(t)), J.c(), dt(J, 1), J.m(e, o)) + : J && + (ut(), + pt(J, 1, 1, () => { + J = null; + }), + ft()), + "esp8266_1mb" == t[9].text + ? V + ? (V.p(t, l), 512 & l[0] && dt(V, 1)) + : ((V = Xt(t)), V.c(), dt(V, 1), V.m(e, r)) + : V && + (ut(), + pt(V, 1, 1, () => { + V = null; + }), + ft()), + "esp8266_1mb_ota" == t[9].text + ? z + ? (z.p(t, l), 512 & l[0] && dt(z, 1)) + : ((z = Yt(t)), z.c(), dt(z, 1), z.m(e, i)) + : z && + (ut(), + pt(z, 1, 1, () => { + z = null; + }), + ft()), + 128 & l[0] && T(s, t[7]), + 65536 & l[0]) + ) { + let e; + for (K = t[16], e = 0; e < K.length; e += 1) { + const n = Ht(t, K, e); + H[e] ? H[e].p(n, l) : ((H[e] = ne(n)), H[e].c(), H[e].m(f, null)); + } + for (; e < H.length; e += 1) H[e].d(1); + H.length = K.length; + } + 66048 & l[0] && T(f, t[9]), + (!D || 256 & l[0]) && I(m, "display", t[8] ? "none" : "inline"), + (!D || 256 & l[0]) && I($, "display", t[8] ? "inline" : "none"), + t[8] + ? Q + ? Q.p(t, l) + : ((Q = oe(t)), Q.c(), Q.m(C.parentNode, C)) + : Q && (Q.d(1), (Q = null)), + 1 & l[0] && E.value !== t[0] && M(E, t[0]); + }, + i(t) { + D || (dt(L), dt(J), dt(V), dt(z), (D = !0)); + }, + o(t) { + pt(L), pt(J), pt(V), pt(z), (D = !1); + }, + d(t) { + t && w(e), + L && L.d(), + J && J.d(), + V && V.d(), + z && z.d(), + k(H, t), + t && w(d), + t && w(p), + t && w(h), + t && w(m), + t && w(v), + t && w($), + t && w(x), + Q && Q.d(t), + t && w(C), + t && w(q), + t && w(B), + t && w(U), + (A = !1), + l(F); + }, + }; + } + function le(e, n) { + let o, + r, + i, + s, + c, + a, + u, + f, + d, + p, + h, + m, + g, + v = + n[74].path.slice(n[74].path.lastIndexOf("/") + 1, n[74].path.length) + + "", + $ = t; + function y() { + n[38].call(r, n[79], n[80]); + } + function x() { + return n[39](n[74]); + } + return { + key: e, + first: null, + c() { + (o = S("label")), + (r = S("input")), + (i = O()), + (s = j(v)), + (c = O()), + (a = S("button")), + (a.textContent = "?"), + (u = O()), + P(r, "type", "checkbox"), + P(r, "class", "svelte-185rejv"), + P(a, "class", "svelte-185rejv"), + P(o, "class", "svelte-185rejv"), + (this.first = o); + }, + m(t, e) { + _(t, o, e), + b(o, r), + (r.checked = n[74].active), + b(o, i), + b(o, s), + b(o, c), + b(o, a), + b(o, u), + (h = !0), + m || + ((g = [ + N(r, "change", y), + N(r, "click", n[17]()), + N(a, "click", x), + ]), + (m = !0)); + }, + p(t, e) { + (n = t), + 1 & e[0] && (r.checked = n[74].active), + (!h || 1 & e[0]) && + v !== + (v = + n[74].path.slice( + n[74].path.lastIndexOf("/") + 1, + n[74].path.length + ) + "") && + q(s, v); + }, + r() { + p = o.getBoundingClientRect(); + }, + f() { + L(o), $(), J(o, p); + }, + a() { + $(), ($ = F(o, p, Nt, {})); + }, + i(t) { + h || + (Z(() => { + d && d.end(1), (f = mt(o, n[11], { key: n[74].path })), f.start(); + }), + (h = !0)); + }, + o(t) { + f && f.invalidate(), (d = gt(o, n[10], { key: n[74].path })), (h = !1); + }, + d(t) { + t && w(o), t && d && d.end(), (m = !1), l(g); + }, + }; + } + function ie(t) { + let e, + n, + o, + r, + l, + i, + s = t[68] + "", + c = [], + a = new Map(), + u = t[0].modules[t[68]].filter($e); + const f = (t) => t[74].path; + for (let e = 0; e < u.length; e += 1) { + let n = Kt(t, u, e), + o = f(n); + a.set(o, (c[e] = le(o, n))); + } + return { + c() { + (e = S("b")), (n = j(s)), (o = S("br")), (r = O()); + for (let t = 0; t < c.length; t += 1) c[t].c(); + l = C(); + }, + m(t, s) { + _(t, e, s), b(e, n), _(t, o, s), _(t, r, s); + for (let e = 0; e < c.length; e += 1) c[e].m(t, s); + _(t, l, s), (i = !0); + }, + p(t, e) { + if ( + ((!i || 1 & e[0]) && s !== (s = t[68] + "") && q(n, s), 135169 & e[0]) + ) { + (u = t[0].modules[t[68]].filter($e)), ut(); + for (let t = 0; t < c.length; t += 1) c[t].r(); + c = $t(c, e, f, 1, t, u, a, l.parentNode, vt, le, l, Kt); + for (let t = 0; t < c.length; t += 1) c[t].a(); + ft(); + } + }, + i(t) { + if (!i) { + for (let t = 0; t < u.length; t += 1) dt(c[t]); + i = !0; + } + }, + o(t) { + for (let t = 0; t < c.length; t += 1) pt(c[t]); + i = !1; + }, + d(t) { + t && w(e), t && w(o), t && w(r); + for (let e = 0; e < c.length; e += 1) c[e].d(t); + t && w(l); + }, + }; + } + function se(e, n) { + let o, + r, + i, + s, + c, + a, + u, + f, + d, + p, + h, + m, + g, + v = + n[74].path.slice(n[74].path.lastIndexOf("/") + 1, n[74].path.length) + + "", + $ = t; + function y() { + n[40].call(r, n[75], n[76]); + } + function x() { + return n[41](n[74]); + } + return { + key: e, + first: null, + c() { + (o = S("label")), + (r = S("input")), + (i = O()), + (s = j(v)), + (c = O()), + (a = S("button")), + (a.textContent = "?"), + (u = O()), + P(r, "type", "checkbox"), + P(r, "class", "svelte-185rejv"), + P(a, "class", "svelte-185rejv"), + P(o, "class", "svelte-185rejv"), + (this.first = o); + }, + m(t, e) { + _(t, o, e), + b(o, r), + (r.checked = n[74].active), + b(o, i), + b(o, s), + b(o, c), + b(o, a), + b(o, u), + (h = !0), + m || + ((g = [ + N(r, "change", y), + N(r, "click", n[17]()), + N(a, "click", x), + ]), + (m = !0)); + }, + p(t, e) { + (n = t), + 1 & e[0] && (r.checked = n[74].active), + (!h || 1 & e[0]) && + v !== + (v = + n[74].path.slice( + n[74].path.lastIndexOf("/") + 1, + n[74].path.length + ) + "") && + q(s, v); + }, + r() { + p = o.getBoundingClientRect(); + }, + f() { + L(o), $(), J(o, p); + }, + a() { + $(), ($ = F(o, p, Nt, {})); + }, + i(t) { + h || + (Z(() => { + d && d.end(1), (f = mt(o, n[11], { key: n[74].path })), f.start(); + }), + (h = !0)); + }, + o(t) { + f && f.invalidate(), (d = gt(o, n[10], { key: n[74].path })), (h = !1); + }, + d(t) { + t && w(o), t && d && d.end(), (m = !1), l(g); + }, + }; + } + function ce(t) { + let e, + n, + o, + r, + l, + i, + s = t[68] + "", + c = [], + a = new Map(), + u = t[0].modules[t[68]].filter(be); + const f = (t) => t[74].path; + for (let e = 0; e < u.length; e += 1) { + let n = Vt(t, u, e), + o = f(n); + a.set(o, (c[e] = se(o, n))); + } + return { + c() { + (e = S("b")), (n = j(s)), (o = S("br")), (r = O()); + for (let t = 0; t < c.length; t += 1) c[t].c(); + l = C(); + }, + m(t, s) { + _(t, e, s), b(e, n), _(t, o, s), _(t, r, s); + for (let e = 0; e < c.length; e += 1) c[e].m(t, s); + _(t, l, s), (i = !0); + }, + p(t, e) { + if ( + ((!i || 1 & e[0]) && s !== (s = t[68] + "") && q(n, s), 135169 & e[0]) + ) { + (u = t[0].modules[t[68]].filter(be)), ut(); + for (let t = 0; t < c.length; t += 1) c[t].r(); + c = $t(c, e, f, 1, t, u, a, l.parentNode, vt, se, l, Vt); + for (let t = 0; t < c.length; t += 1) c[t].a(); + ft(); + } + }, + i(t) { + if (!i) { + for (let t = 0; t < u.length; t += 1) dt(c[t]); + i = !0; + } + }, + o(t) { + for (let t = 0; t < c.length; t += 1) pt(c[t]); + i = !1; + }, + d(t) { + t && w(e), t && w(o), t && w(r); + for (let e = 0; e < c.length; e += 1) c[e].d(t); + t && w(l); + }, + }; + } + function ae(t) { + let e, n; + return ( + (e = new Gt({ + props: { $$slots: { default: [ge] }, $$scope: { ctx: t } }, + })), + e.$on("close", t[42]), + { + c() { + yt(e.$$.fragment); + }, + m(t, o) { + xt(e, t, o), (n = !0); + }, + p(t, n) { + const o = {}; + (60 & n[0]) | (4194304 & n[2]) && (o.$$scope = { dirty: n, ctx: t }), + e.$set(o); + }, + i(t) { + n || (dt(e.$$.fragment, t), (n = !0)); + }, + o(t) { + pt(e.$$.fragment, t), (n = !1); + }, + d(t) { + _t(e, t); + }, + } + ); + } + function ue(t) { + let e, + n, + o, + r, + l, + i = t[68] + "", + s = t[69] + ""; + return { + c() { + (e = S("p")), + (n = S("b")), + (o = j(i)), + (r = j(" - ")), + (l = j(s)), + I(e, "margin-left", "20px"); + }, + m(t, i) { + _(t, e, i), b(e, n), b(n, o), b(e, r), b(e, l); + }, + p(t, e) { + 32 & e[0] && i !== (i = t[68] + "") && q(o, i), + 32 & e[0] && s !== (s = t[69] + "") && q(l, s); + }, + d(t) { + t && w(e); + }, + }; + } + function fe(t) { + let e, + n, + o, + r, + l = t[4].funcInfo, + i = []; + for (let e = 0; e < l.length; e += 1) i[e] = he(At(t, l, e)); + return { + c() { + (e = j("Использование в сценариях: ")), (n = S("br")), (o = O()); + for (let t = 0; t < i.length; t += 1) i[t].c(); + r = C(); + }, + m(t, l) { + _(t, e, l), _(t, n, l), _(t, o, l); + for (let e = 0; e < i.length; e += 1) i[e].m(t, l); + _(t, r, l); + }, + p(t, e) { + if (16 & e[0]) { + let n; + for (l = t[4].funcInfo, n = 0; n < l.length; n += 1) { + const o = At(t, l, n); + i[n] + ? i[n].p(o, e) + : ((i[n] = he(o)), i[n].c(), i[n].m(r.parentNode, r)); + } + for (; n < i.length; n += 1) i[n].d(1); + i.length = l.length; + } + }, + d(t) { + t && w(e), t && w(n), t && w(o), k(i, t), t && w(r); + }, + }; + } + function de(t) { + let e, n, o; + return { + c() { + (e = S("br")), + (n = O()), + (o = S("lable")), + (o.textContent = "параметры:"), + I(o, "margin-left", "5px"); + }, + m(t, r) { + _(t, e, r), _(t, n, r), _(t, o, r); + }, + d(t) { + t && w(e), t && w(n), t && w(o); + }, + }; + } + function pe(t) { + let e, + n, + o, + r, + l, + i = t[65] + ""; + return { + c() { + (e = S("br")), + (n = O()), + (o = S("lable")), + (r = j("- ")), + (l = j(i)), + I(o, "margin-left", "40px"); + }, + m(t, i) { + _(t, e, i), _(t, n, i), _(t, o, i), b(o, r), b(o, l); + }, + p(t, e) { + 16 & e[0] && i !== (i = t[65] + "") && q(l, i); + }, + d(t) { + t && w(e), t && w(n), t && w(o); + }, + }; + } + function he(t) { + let e, + n, + o, + r, + l, + i, + s, + c, + a = (t[62].name ? t[62].name : "") + "", + u = (t[62].descr ? t[62].descr : "") + "", + f = JSON.stringify(t[62].params).length > 2, + d = f && de(), + p = t[62].params, + h = []; + for (let e = 0; e < p.length; e += 1) h[e] = pe(Ft(t, p, e)); + return { + c() { + (e = S("p")), + (n = S("b")), + (o = j(a)), + (r = j(" - ")), + (l = j(u)), + (i = O()), + d && d.c(), + (s = O()); + for (let t = 0; t < h.length; t += 1) h[t].c(); + (c = O()), I(e, "margin-left", "20px"); + }, + m(t, a) { + _(t, e, a), + b(e, n), + b(n, o), + b(e, r), + b(e, l), + b(e, i), + d && d.m(e, null), + b(e, s); + for (let t = 0; t < h.length; t += 1) h[t].m(e, null); + b(e, c); + }, + p(t, n) { + if ( + (16 & n[0] && + a !== (a = (t[62].name ? t[62].name : "") + "") && + q(o, a), + 16 & n[0] && + u !== (u = (t[62].descr ? t[62].descr : "") + "") && + q(l, u), + 16 & n[0] && (f = JSON.stringify(t[62].params).length > 2), + f ? d || ((d = de()), d.c(), d.m(e, s)) : d && (d.d(1), (d = null)), + 16 & n[0]) + ) { + let o; + for (p = t[62].params, o = 0; o < p.length; o += 1) { + const r = Ft(t, p, o); + h[o] ? h[o].p(r, n) : ((h[o] = pe(r)), h[o].c(), h[o].m(e, c)); + } + for (; o < h.length; o += 1) h[o].d(1); + h.length = p.length; + } + }, + d(t) { + t && w(e), d && d.d(), k(h, t); + }, + }; + } + function me(t) { + let e, n, o, r; + return { + c() { + (e = S("a")), + (n = j( + "Описание модуля в WIKI. Примеры подключения, использования." + )), + (r = S("br")), + P(e, "href", (o = t[4].exampleURL)); + }, + m(t, o) { + _(t, e, o), b(e, n), _(t, r, o); + }, + p(t, n) { + 16 & n[0] && o !== (o = t[4].exampleURL) && P(e, "href", o); + }, + d(t) { + t && w(e), t && w(r); + }, + }; + } + function ge(t) { + let e, + n, + o, + r, + l, + i, + s, + c, + a, + u, + f, + d, + p, + h, + m, + g, + v, + $, + y, + x, + C, + N, + M, + T, + E, + R, + G, + B, + U, + D, + A, + F, + L, + J, + V, + z, + K, + H, + Q, + W, + X, + Y, + Z, + tt, + et, + nt, + ot, + rt, + lt, + it, + st, + ct, + at, + ut = (t[4].title ? t[4].title : "") + "", + ft = (t[4].moduleName ? t[4].moduleName : "") + "", + dt = (t[3].name ? t[3].name : "") + "", + pt = (t[4].moduleDesc ? t[4].moduleDesc : "") + "", + ht = t[2].menuSection ? "Тип: " : "", + mt = (t[2].menuSection ? t[2].menuSection : "") + "", + gt = t[4].moduleVersion ? "Версия: " : "", + vt = (t[4].moduleVersion ? t[4].moduleVersion : "") + "", + $t = t[4].propInfo ? "Параметры: " : "", + bt = (t[4].authorName, ""), + yt = t[4].authorName ? "Автор: " : "", + xt = (t[4].authorName ? t[4].authorName : "") + "", + _t = (t[4].authorContact ? t[4].authorContact : "") + "", + wt = t[4].authorGit ? "GitHub: " : "", + kt = (t[4].authorGit ? t[4].authorGit : "") + "", + St = t[4].specialThanks ? "Благодарности: " : "", + jt = (t[4].specialThanks ? t[4].specialThanks : "") + "", + Ot = Object.entries(t[5]), + Ct = []; + for (let e = 0; e < Ot.length; e += 1) Ct[e] = ue(Lt(t, Ot, e)); + let Nt = t[4].funcInfo && fe(t), + Pt = t[4].exampleURL && me(t); + return { + c() { + (e = S("h2")), + (n = j(ut)), + (o = O()), + (r = S("strong")), + (l = j(ft)), + (i = j("\n(")), + (s = j(dt)), + (c = j(")\n")), + (a = S("div")), + (u = j(pt)), + (f = S("br")), + (d = O()), + (p = S("div")), + (h = j(ht)), + (m = O()), + (g = j(mt)), + (v = O()), + ($ = j(gt)), + (y = O()), + (x = j(vt)), + (C = S("br")), + (N = S("br")), + (M = O()), + (T = j($t)), + (E = S("br")), + (R = O()); + for (let t = 0; t < Ct.length; t += 1) Ct[t].c(); + (G = O()), + Nt && Nt.c(), + (B = O()), + (U = j(bt)), + (D = S("br")), + (A = O()), + Pt && Pt.c(), + (F = O()), + (L = j(yt)), + (J = O()), + (V = j(xt)), + (z = S("br")), + (K = O()), + (H = S("a")), + (Q = j(_t)), + (X = S("br")), + (Y = O()), + (Z = j(wt)), + (tt = O()), + (et = S("a")), + (nt = j(kt)), + (rt = S("br")), + (lt = O()), + (it = j(St)), + (st = O()), + (ct = j(jt)), + (at = S("br")), + P(e, "class", "svelte-185rejv"), + I(a, "margin-left", "20px"), + P(H, "href", (W = t[4].authorContact ? t[4].authorContact : "")), + P(et, "href", (ot = t[4].authorGit ? t[4].authorGit : "")); + }, + m(t, w) { + _(t, e, w), + b(e, n), + _(t, o, w), + _(t, r, w), + b(r, l), + _(t, i, w), + _(t, s, w), + _(t, c, w), + _(t, a, w), + b(a, u), + _(t, f, w), + _(t, d, w), + _(t, p, w), + b(p, h), + b(p, m), + b(p, g), + _(t, v, w), + _(t, $, w), + _(t, y, w), + _(t, x, w), + _(t, C, w), + _(t, N, w), + _(t, M, w), + _(t, T, w), + _(t, E, w), + _(t, R, w); + for (let e = 0; e < Ct.length; e += 1) Ct[e].m(t, w); + _(t, G, w), + Nt && Nt.m(t, w), + _(t, B, w), + _(t, U, w), + _(t, D, w), + _(t, A, w), + Pt && Pt.m(t, w), + _(t, F, w), + _(t, L, w), + _(t, J, w), + _(t, V, w), + _(t, z, w), + _(t, K, w), + _(t, H, w), + b(H, Q), + _(t, X, w), + _(t, Y, w), + _(t, Z, w), + _(t, tt, w), + _(t, et, w), + b(et, nt), + _(t, rt, w), + _(t, lt, w), + _(t, it, w), + _(t, st, w), + _(t, ct, w), + _(t, at, w); + }, + p(t, e) { + if ( + (16 & e[0] && + ut !== (ut = (t[4].title ? t[4].title : "") + "") && + q(n, ut), + 16 & e[0] && + ft !== (ft = (t[4].moduleName ? t[4].moduleName : "") + "") && + q(l, ft), + 8 & e[0] && + dt !== (dt = (t[3].name ? t[3].name : "") + "") && + q(s, dt), + 16 & e[0] && + pt !== (pt = (t[4].moduleDesc ? t[4].moduleDesc : "") + "") && + q(u, pt), + 4 & e[0] && ht !== (ht = t[2].menuSection ? "Тип: " : "") && q(h, ht), + 4 & e[0] && + mt !== (mt = (t[2].menuSection ? t[2].menuSection : "") + "") && + q(g, mt), + 16 & e[0] && + gt !== (gt = t[4].moduleVersion ? "Версия: " : "") && + q($, gt), + 16 & e[0] && + vt !== (vt = (t[4].moduleVersion ? t[4].moduleVersion : "") + "") && + q(x, vt), + 16 & e[0] && + $t !== ($t = t[4].propInfo ? "Параметры: " : "") && + q(T, $t), + 32 & e[0]) + ) { + let n; + for (Ot = Object.entries(t[5]), n = 0; n < Ot.length; n += 1) { + const o = Lt(t, Ot, n); + Ct[n] + ? Ct[n].p(o, e) + : ((Ct[n] = ue(o)), Ct[n].c(), Ct[n].m(G.parentNode, G)); + } + for (; n < Ct.length; n += 1) Ct[n].d(1); + Ct.length = Ot.length; + } + t[4].funcInfo + ? Nt + ? Nt.p(t, e) + : ((Nt = fe(t)), Nt.c(), Nt.m(B.parentNode, B)) + : Nt && (Nt.d(1), (Nt = null)), + 16 & e[0] && bt !== (t[4].authorName, (bt = "")) && q(U, bt), + t[4].exampleURL + ? Pt + ? Pt.p(t, e) + : ((Pt = me(t)), Pt.c(), Pt.m(F.parentNode, F)) + : Pt && (Pt.d(1), (Pt = null)), + 16 & e[0] && + yt !== (yt = t[4].authorName ? "Автор: " : "") && + q(L, yt), + 16 & e[0] && + xt !== (xt = (t[4].authorName ? t[4].authorName : "") + "") && + q(V, xt), + 16 & e[0] && + _t !== (_t = (t[4].authorContact ? t[4].authorContact : "") + "") && + q(Q, _t), + 16 & e[0] && + W !== (W = t[4].authorContact ? t[4].authorContact : "") && + P(H, "href", W), + 16 & e[0] && + wt !== (wt = t[4].authorGit ? "GitHub: " : "") && + q(Z, wt), + 16 & e[0] && + kt !== (kt = (t[4].authorGit ? t[4].authorGit : "") + "") && + q(nt, kt), + 16 & e[0] && + ot !== (ot = t[4].authorGit ? t[4].authorGit : "") && + P(et, "href", ot), + 16 & e[0] && + St !== (St = t[4].specialThanks ? "Благодарности: " : "") && + q(it, St), + 16 & e[0] && + jt !== (jt = (t[4].specialThanks ? t[4].specialThanks : "") + "") && + q(ct, jt); + }, + d(t) { + t && w(e), + t && w(o), + t && w(r), + t && w(i), + t && w(s), + t && w(c), + t && w(a), + t && w(f), + t && w(d), + t && w(p), + t && w(v), + t && w($), + t && w(y), + t && w(x), + t && w(C), + t && w(N), + t && w(M), + t && w(T), + t && w(E), + t && w(R), + k(Ct, t), + t && w(G), + Nt && Nt.d(t), + t && w(B), + t && w(U), + t && w(D), + t && w(A), + Pt && Pt.d(t), + t && w(F), + t && w(L), + t && w(J), + t && w(V), + t && w(z), + t && w(K), + t && w(H), + t && w(X), + t && w(Y), + t && w(Z), + t && w(tt), + t && w(et), + t && w(rt), + t && w(lt), + t && w(it), + t && w(st), + t && w(ct), + t && w(at); + }, + }; + } + function ve(t) { + let e, n, o, r, l, i, s, c, a, u, f, d, p, h; + n = new Dt({ props: { $$slots: { default: [re] }, $$scope: { ctx: t } } }); + let m = Object.entries(t[0].modules), + g = []; + for (let e = 0; e < m.length; e += 1) g[e] = ie(zt(t, m, e)); + const v = (t) => + pt(g[t], 1, 1, () => { + g[t] = null; + }); + let $ = Object.entries(t[0].modules), + y = []; + for (let e = 0; e < $.length; e += 1) y[e] = ce(Jt(t, $, e)); + const x = (t) => + pt(y[t], 1, 1, () => { + y[t] = null; + }); + let j = t[6] && ae(t); + return { + c() { + (e = S("p")), + yt(n.$$.fragment), + (o = O()), + (r = S("div")), + (l = S("div")), + (i = S("h2")), + (i.textContent = "доступные модули"), + (s = O()); + for (let t = 0; t < g.length; t += 1) g[t].c(); + (c = O()), + (a = S("div")), + (u = S("h2")), + (u.textContent = "в прошивке"), + (f = O()); + for (let t = 0; t < y.length; t += 1) y[t].c(); + (d = O()), + j && j.c(), + (p = C()), + P(e, "align", "center"), + P(i, "class", "svelte-185rejv"), + P(l, "class", "left svelte-185rejv"), + P(u, "class", "svelte-185rejv"), + P(a, "class", "right svelte-185rejv"), + P(r, "class", "board svelte-185rejv"); + }, + m(t, m) { + _(t, e, m), + xt(n, e, null), + b(e, o), + _(t, r, m), + b(r, l), + b(l, i), + b(l, s); + for (let t = 0; t < g.length; t += 1) g[t].m(l, null); + b(r, c), b(r, a), b(a, u), b(a, f); + for (let t = 0; t < y.length; t += 1) y[t].m(a, null); + _(t, d, m), j && j.m(t, m), _(t, p, m), (h = !0); + }, + p(t, e) { + const o = {}; + if ( + ((899 & e[0]) | (4194304 & e[2]) && + (o.$$scope = { dirty: e, ctx: t }), + n.$set(o), + 135169 & e[0]) + ) { + let n; + for (m = Object.entries(t[0].modules), n = 0; n < m.length; n += 1) { + const o = zt(t, m, n); + g[n] + ? (g[n].p(o, e), dt(g[n], 1)) + : ((g[n] = ie(o)), g[n].c(), dt(g[n], 1), g[n].m(l, null)); + } + for (ut(), n = m.length; n < g.length; n += 1) v(n); + ft(); + } + if (135169 & e[0]) { + let n; + for ($ = Object.entries(t[0].modules), n = 0; n < $.length; n += 1) { + const o = Jt(t, $, n); + y[n] + ? (y[n].p(o, e), dt(y[n], 1)) + : ((y[n] = ce(o)), y[n].c(), dt(y[n], 1), y[n].m(a, null)); + } + for (ut(), n = $.length; n < y.length; n += 1) x(n); + ft(); + } + t[6] + ? j + ? (j.p(t, e), 64 & e[0] && dt(j, 1)) + : ((j = ae(t)), j.c(), dt(j, 1), j.m(p.parentNode, p)) + : j && + (ut(), + pt(j, 1, 1, () => { + j = null; + }), + ft()); + }, + i(t) { + if (!h) { + dt(n.$$.fragment, t); + for (let t = 0; t < m.length; t += 1) dt(g[t]); + for (let t = 0; t < $.length; t += 1) dt(y[t]); + dt(j), (h = !0); + } + }, + o(t) { + pt(n.$$.fragment, t), (g = g.filter(Boolean)); + for (let t = 0; t < g.length; t += 1) pt(g[t]); + y = y.filter(Boolean); + for (let t = 0; t < y.length; t += 1) pt(y[t]); + pt(j), (h = !1); + }, + d(t) { + t && w(e), + _t(n), + t && w(r), + k(g, t), + k(y, t), + t && w(d), + j && j.d(t), + t && w(p); + }, + }; + } + const $e = (t) => !t.active, + be = (t) => t.active; + function ye(t, e, n) { + let o = + "https://raw.githubusercontent.com/IoTManagerProject/IoTManager/ver4dev/myProfile.json?1", + r = {}, + l = 0, + i = {}, + s = [], + c = [], + a = [], + u = [], + f = !1, + d = "dev", + p = {}; + async function h(t) { + try { + let e = await fetch(t, { mode: "cors", method: "GET" }); + e.ok ? n(0, (r = await e.json())) : console.log("error", e.statusText); + } catch (t) { + console.log(t); + } + } + (r = { + iotmSettings: {}, + projectProp: { platformio: {} }, + modules: { + "Виртуальные элементы": [], + Сенсоры: [], + executive_devices: [], + Экраны: [], + }, + }), + h(o), + (async function (t) { + try { + let e = await fetch(t, { mode: "cors", method: "GET" }); + e.ok ? (p = await e.json()) : console.log("error", e.statusText); + } catch (t) { + console.log(t); + } + })("https://iotmanager.org/firmwarebuilder/moduleSize.json?1"); + const [m, g] = Ct({ + fallback(t, e) { + const n = getComputedStyle(t), + o = "none" === n.transform ? "" : n.transform; + return { + duration: 600, + easing: Ot, + css: (t) => + `\n\t\t\t\t\ttransform: ${o} scale(${t});\n\t\t\t\t\topacity: ${t}\n\t\t\t\t`, + }; + }, + }); + function v(t) { + console.log(t.path), + (o = + "https://raw.githubusercontent.com/IoTManagerProject/IoTManager/ver4stable/" + + JSON.parse(JSON.stringify(t.path).replace(/\\\\/g, "/")) + + "/modinfo.json"), + (i = []), + n(2, (s = [])), + n(3, (c = [])), + n(3, (c.name = "Данные загружаются..."), c), + n(4, (a = [])), + n(5, (u = [])), + (async function (t) { + i = []; + try { + let e = await fetch(t, { mode: "cors", method: "GET" }); + e.ok + ? ((i = await e.json()), + n(2, (s = i)), + n(3, (c = i.configItem[0])), + n(4, (a = i.about)), + n(5, (u = a.propInfo))) + : console.log("error", e.statusText); + } catch (t) { + console.log(t); + } + })(o), + n(6, (f = !0)); + } + let $ = !0; + function b(t) { + n(8, ($ = t)); + } + function y() { + (o = + "dev" == d + ? "https://raw.githubusercontent.com/IoTManagerProject/IoTManager/ver4dev/myProfile.json?1" + : "https://raw.githubusercontent.com/IoTManagerProject/IoTManager/ver4stable/myProfile.json?1"), + h(o); + } + function x() { + n(1, (l = 0)), + n(0, (r.projectProp.platformio.default_envs = _.text), r), + k(); + } + let _ = [], + w = [ + { id: 1, text: "esp8266_4mb" }, + { id: 2, text: "esp32_4mb" }, + { id: 3, text: "esp8266_1mb" }, + { id: 4, text: "esp8266_1mb_ota" }, + ]; + function k() { + n(1, (l = 0)); + for (const [t, e] of Object.entries(r.modules)) + for (const [e, o] of Object.entries( + r.modules[t].filter((t) => t.active) + )) { + let t = o.path.slice(o.path.lastIndexOf("/") + 1, o.path.length); + p[t] && n(1, (l += Math.round(p[t][_.text]))); + } + "esp8266_4mb" == _.text && n(1, (l = Math.round(l / 6110))), + "esp32_4mb" == _.text && n(1, (l = Math.round(l / 3243))), + "esp8266_1mb" == _.text && n(1, (l = Math.round(l / 3237))), + "esp8266_1mb_ota" == _.text && n(1, (l = Math.round(l / 2601))); + } + function S() { + var t = document.createElement("a"); + (t.href = window.URL.createObjectURL( + new Blob([JSON.stringify(r)], { type: "text/plain" }) + )), + (t.download = "myProfile.json"), + console.log(JSON.stringify(r)); + } + return [ + r, + l, + s, + c, + a, + u, + f, + d, + $, + _, + m, + g, + v, + b, + y, + x, + w, + k, + S, + function (t) { + (l = t), n(1, l); + }, + function (t) { + (l = t), n(1, l); + }, + function (t) { + (l = t), n(1, l); + }, + function (t) { + (l = t), n(1, l); + }, + function () { + (d = E(this)), n(7, d); + }, + () => y(), + function () { + (_ = E(this)), n(9, _), n(16, w); + }, + () => x(), + () => b(!0), + () => b(!1), + function () { + (r.iotmSettings.routerssid = this.value), n(0, r); + }, + function () { + (r.iotmSettings.routerpass = this.value), n(0, r); + }, + function () { + (r.iotmSettings.mqttServer = this.value), n(0, r); + }, + function () { + (r.iotmSettings.mqttPort = this.value), n(0, r); + }, + function () { + (r.iotmSettings.mqttPrefix = this.value), n(0, r); + }, + function () { + (r.iotmSettings.mqttUser = this.value), n(0, r); + }, + function () { + (r.iotmSettings.mqttPass = this.value), n(0, r); + }, + function () { + (r = this.value), n(0, r); + }, + () => S(), + function (t, e) { + (t[e].active = this.checked), n(0, r); + }, + (t) => v(t), + function (t, e) { + (t[e].active = this.checked), n(0, r); + }, + (t) => v(t), + () => n(6, (f = !1)), + ]; + } + return new (class extends St { + constructor(t) { + super(), kt(this, t, ye, ve, s, {}, null, [-1, -1, -1]); + } + })({ target: document.body }); +})(); //# sourceMappingURL=bundle.js.map