diff --git a/compilerProfile.json b/compilerProfile.json index baec7668..0e4c8536 100644 --- a/compilerProfile.json +++ b/compilerProfile.json @@ -130,7 +130,7 @@ }, { "path": "src/modules/virtual/owmWeather", - "active": true + "active": false }, { "path": "src/modules/virtual/Timer", @@ -422,6 +422,10 @@ "path": "src/modules/display/Oled128", "active": false }, + { + "path": "src/modules/display/Oled64", + "active": true + }, { "path": "src/modules/display/Smi2_m", "active": true diff --git a/data_full/build/bundle.css.gz b/data_full/build/bundle.css.gz index 1cf84b11..d7558d9b 100644 Binary files a/data_full/build/bundle.css.gz and b/data_full/build/bundle.css.gz differ diff --git a/data_full/build/bundle.js.gz b/data_full/build/bundle.js.gz index 04dc22a5..63218540 100644 Binary files a/data_full/build/bundle.js.gz and b/data_full/build/bundle.js.gz differ diff --git a/data_full/index.html b/data_full/index.html index 8b97c0b8..4dc7d628 100644 --- a/data_full/index.html +++ b/data_full/index.html @@ -4,12 +4,12 @@ - IoT Manager 4.5.2 + IoT Manager 4.5.4 - + - + diff --git a/data_svelte/build/bundle.css.gz b/data_svelte/build/bundle.css.gz index 1cf84b11..d7558d9b 100644 Binary files a/data_svelte/build/bundle.css.gz and b/data_svelte/build/bundle.css.gz differ diff --git a/data_svelte/build/bundle.js.gz b/data_svelte/build/bundle.js.gz index 04dc22a5..63218540 100644 Binary files a/data_svelte/build/bundle.js.gz and b/data_svelte/build/bundle.js.gz differ diff --git a/data_svelte/flashProfile.json b/data_svelte/flashProfile.json index 4c908db4..bc38fdf5 100644 --- a/data_svelte/flashProfile.json +++ b/data_svelte/flashProfile.json @@ -24,7 +24,7 @@ }, { "path": "src/modules/virtual/owmWeather", - "active": true + "active": false }, { "path": "src/modules/virtual/Timer", @@ -316,6 +316,10 @@ "path": "src/modules/display/Oled128", "active": false }, + { + "path": "src/modules/display/Oled64", + "active": true + }, { "path": "src/modules/display/Smi2_m", "active": true diff --git a/data_svelte/index.html b/data_svelte/index.html index 8b97c0b8..4dc7d628 100644 --- a/data_svelte/index.html +++ b/data_svelte/index.html @@ -4,12 +4,12 @@ - IoT Manager 4.5.2 + IoT Manager 4.5.4 - + - + diff --git a/data_svelte/items.json b/data_svelte/items.json index e796d869..e31d2a50 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -68,29 +68,7 @@ }, { "global": 0, - "name": "5. Погода OWM", - "type": "Reading", - "subtype": "owmWeather", - "id": "owm", - "needSave": 0, - "widget": "nil", - "page": "Погода", - "descr": "Температура на улице", - "int": 30, - "API_key": "", - "сity": "Moscow", - "lon": "37.54", - "lat": "57.74", - "lang": "ru", - "param": "", - "round": 1, - "val": "...", - "debug": 0, - "num": 5 - }, - { - "global": 0, - "name": "6. Таймер", + "name": "5. Таймер", "type": "Writing", "subtype": "Timer", "id": "timer", @@ -102,11 +80,11 @@ "ticker": 1, "repeat": 1, "needSave": 0, - "num": 6 + "num": 5 }, { "global": 0, - "name": "7. Окно ввода числа (переменная)", + "name": "6. Окно ввода числа (переменная)", "type": "Reading", "subtype": "Variable", "id": "value", @@ -120,11 +98,11 @@ "plus": 0, "multiply": 1, "round": 0, - "num": 7 + "num": 6 }, { "global": 0, - "name": "8. Окно ввода времени", + "name": "7. Окно ввода времени", "type": "Reading", "subtype": "Variable", "id": "time", @@ -134,11 +112,11 @@ "descr": "Введите время", "int": "0", "val": "02:00", - "num": 8 + "num": 7 }, { "global": 0, - "name": "9. Окно ввода даты", + "name": "8. Окно ввода даты", "type": "Reading", "subtype": "Variable", "id": "time", @@ -148,11 +126,11 @@ "descr": "Введите дату", "int": "0", "val": "24.05.2022", - "num": 9 + "num": 8 }, { "global": 0, - "name": "10. Окно ввода текста", + "name": "9. Окно ввода текста", "type": "Reading", "subtype": "Variable", "id": "txt", @@ -162,11 +140,11 @@ "descr": "Введите текст", "int": "0", "val": "текст", - "num": 10 + "num": 9 }, { "global": 0, - "name": "11. Вывод значения", + "name": "10. Вывод значения", "type": "Reading", "subtype": "Variable", "id": "vout", @@ -180,11 +158,11 @@ "plus": 0, "multiply": 1, "round": 0, - "num": 11 + "num": 10 }, { "global": 0, - "name": "12. Цветной текст", + "name": "11. Цветной текст", "type": "Reading", "subtype": "VariableColor", "id": "color", @@ -194,11 +172,11 @@ "descr": "Цветной текст", "val": "...", "round": 0, - "num": 12 + "num": 11 }, { "global": 0, - "name": "13. Виртуальная кнопка", + "name": "12. Виртуальная кнопка", "type": "Reading", "subtype": "VButton", "id": "vbtn", @@ -208,13 +186,13 @@ "descr": "Кнопка", "int": "0", "val": "0", - "num": 13 + "num": 12 }, { "header": "sensors" }, { - "name": "14. A02 Дальность", + "name": "13. A02 Дальность", "type": "Reading", "subtype": "A02Distance", "id": "dist", @@ -223,10 +201,10 @@ "descr": "Дальность", "int": 5, "round": 1, - "num": 14 + "num": 13 }, { - "name": "15. Acs712 Ток", + "name": "14. Acs712 Ток", "type": "Reading", "subtype": "Acs712", "id": "amp", @@ -241,11 +219,11 @@ "sens": 100, "adczero": 512, "btn-setZero": "nil", - "num": 15 + "num": 14 }, { "global": 0, - "name": "16. AHTXX Температура", + "name": "15. AHTXX Температура", "type": "Reading", "subtype": "AhtXXt", "id": "Temp20", @@ -256,11 +234,11 @@ "addr": "0x38", "shtType": 1, "round": 1, - "num": 16 + "num": 15 }, { "global": 0, - "name": "17. AHTXX Влажность", + "name": "16. AHTXX Влажность", "type": "Reading", "subtype": "AhtXXh", "id": "Hum20", @@ -271,11 +249,11 @@ "addr": "0x38", "shtType": 1, "round": 1, - "num": 17 + "num": 16 }, { "global": 0, - "name": "18. Аналоговый сенсор", + "name": "17. Аналоговый сенсор", "type": "Reading", "subtype": "AnalogAdc", "id": "t", @@ -289,11 +267,11 @@ "pin": 0, "int": 15, "avgSteps": 1, - "num": 18 + "num": 17 }, { "global": 0, - "name": "19. BME280 Температура", + "name": "18. BME280 Температура", "type": "Reading", "subtype": "Bme280t", "id": "Tmp3", @@ -303,11 +281,11 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 19 + "num": 18 }, { "global": 0, - "name": "20. BME280 Давление", + "name": "19. BME280 Давление", "type": "Reading", "subtype": "Bme280p", "id": "Press3", @@ -317,11 +295,11 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 20 + "num": 19 }, { "global": 0, - "name": "21. BME280 Влажность", + "name": "20. BME280 Влажность", "type": "Reading", "subtype": "Bme280h", "id": "Hum3", @@ -331,11 +309,11 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 21 + "num": 20 }, { "global": 0, - "name": "22. BME280 Tочка росы", + "name": "21. BME280 Tочка росы", "type": "Reading", "subtype": "Bme280dp", "id": "Dew3", @@ -345,11 +323,11 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 22 + "num": 21 }, { "global": 0, - "name": "23. BMP280 Температура", + "name": "22. BMP280 Температура", "type": "Reading", "subtype": "Bmp280t", "id": "tmp3", @@ -359,11 +337,11 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 23 + "num": 22 }, { "global": 0, - "name": "24. BMP280 Давление", + "name": "23. BMP280 Давление", "type": "Reading", "subtype": "Bmp280p", "id": "Press3", @@ -373,11 +351,11 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 24 + "num": 23 }, { "global": 0, - "name": "25. DHT11 Температура", + "name": "24. DHT11 Температура", "type": "Reading", "subtype": "Dht1122t", "id": "tmp3", @@ -387,11 +365,11 @@ "int": 15, "pin": 0, "senstype": "dht11", - "num": 25 + "num": 24 }, { "global": 0, - "name": "26. DHT11 Влажность", + "name": "25. DHT11 Влажность", "type": "Reading", "subtype": "Dht1122h", "id": "Hum3", @@ -401,11 +379,11 @@ "int": 15, "pin": 0, "senstype": "dht11", - "num": 26 + "num": 25 }, { "global": 0, - "name": "27. DS18B20 Температура", + "name": "26. DS18B20 Температура", "type": "Reading", "subtype": "Ds18b20", "id": "dstmp", @@ -417,11 +395,11 @@ "index": 0, "addr": "", "round": 1, - "num": 27 + "num": 26 }, { "global": 0, - "name": "28. Аналоговый счетчик импульсов", + "name": "27. Аналоговый счетчик импульсов", "type": "Writing", "subtype": "Impulse", "id": "impulse", @@ -434,11 +412,11 @@ "pinMode": "INPUT", "debounceDelay": 3, "multiply": 1, - "num": 28 + "num": 27 }, { "global": 0, - "name": "29. PZEM 004t Напряжение", + "name": "28. PZEM 004t Напряжение", "type": "Reading", "subtype": "Pzem004v", "id": "v", @@ -448,11 +426,11 @@ "int": 15, "addr": "0xF8", "round": 1, - "num": 29 + "num": 28 }, { "global": 0, - "name": "30. PZEM 004t Сила тока", + "name": "29. PZEM 004t Сила тока", "type": "Reading", "subtype": "Pzem004a", "id": "a", @@ -462,11 +440,11 @@ "int": 15, "addr": "0xF8", "round": 1, - "num": 30 + "num": 29 }, { "global": 0, - "name": "31. PZEM 004t Мощность", + "name": "30. PZEM 004t Мощность", "type": "Reading", "subtype": "Pzem004w", "id": "w", @@ -476,11 +454,11 @@ "int": 15, "addr": "0xF8", "round": 1, - "num": 31 + "num": 30 }, { "global": 0, - "name": "32. PZEM 004t Энергия", + "name": "31. PZEM 004t Энергия", "type": "Reading", "subtype": "Pzem004wh", "id": "wh", @@ -490,11 +468,11 @@ "int": 15, "addr": "0xF8", "round": 1, - "num": 32 + "num": 31 }, { "global": 0, - "name": "33. PZEM 004t Частота", + "name": "32. PZEM 004t Частота", "type": "Reading", "subtype": "Pzem004hz", "id": "hz", @@ -504,11 +482,11 @@ "int": 15, "addr": "0xF8", "round": 1, - "num": 33 + "num": 32 }, { "global": 0, - "name": "34. PZEM 004t Косинус", + "name": "33. PZEM 004t Косинус", "type": "Reading", "subtype": "Pzem004pf", "id": "pf", @@ -518,11 +496,11 @@ "int": 15, "addr": "0xF8", "round": 1, - "num": 34 + "num": 33 }, { "global": 0, - "name": "35. PZEM настройка", + "name": "34. PZEM настройка", "type": "Reading", "subtype": "Pzem004cmd", "id": "set", @@ -534,11 +512,11 @@ "changeaddr": 0, "setaddr": "0x01", "reset": 0, - "num": 35 + "num": 34 }, { "global": 0, - "name": "36. Часы реального времени", + "name": "35. Часы реального времени", "type": "Reading", "subtype": "RTC", "id": "rtc", @@ -554,11 +532,11 @@ "int": 5, "btn-setUTime": "0", "btn-setSysTime": "nil", - "num": 36 + "num": 35 }, { - "name": "37. (S8) Cенсор качества воздуха", - "num": 37, + "name": "36. (S8) Cенсор качества воздуха", + "num": 36, "type": "Reading", "subtype": "S8co", "id": "s8co", @@ -572,7 +550,7 @@ }, { "global": 0, - "name": "38. Sht20 Температура", + "name": "37. Sht20 Температура", "type": "Reading", "subtype": "Sht20t", "id": "tmp2", @@ -581,11 +559,11 @@ "descr": "Температура", "int": 15, "round": 1, - "num": 38 + "num": 37 }, { "global": 0, - "name": "39. Sht20 Влажность", + "name": "38. Sht20 Влажность", "type": "Reading", "subtype": "Sht20h", "id": "Hum2", @@ -594,11 +572,11 @@ "descr": "Влажность", "int": 15, "round": 1, - "num": 39 + "num": 38 }, { "global": 0, - "name": "40. Sht30 Температура", + "name": "39. Sht30 Температура", "type": "Reading", "subtype": "Sht30t", "id": "tmp30", @@ -607,11 +585,11 @@ "descr": "SHT30 Температура", "int": 15, "round": 1, - "num": 40 + "num": 39 }, { "global": 0, - "name": "41. Sht30 Влажность", + "name": "40. Sht30 Влажность", "type": "Reading", "subtype": "Sht30h", "id": "Hum30", @@ -620,12 +598,12 @@ "descr": "SHT30 Влажность", "int": 15, "round": 1, - "num": 41 + "num": 40 }, { "global": 0, - "name": "42. HC-SR04 Ультразвуковой дальномер", - "num": 42, + "name": "41. HC-SR04 Ультразвуковой дальномер", + "num": 41, "type": "Reading", "subtype": "Sonar", "id": "sonar", @@ -637,7 +615,7 @@ "int": 5 }, { - "name": "43. UART", + "name": "42. UART", "type": "Reading", "subtype": "UART", "page": "", @@ -649,14 +627,14 @@ "line": 2, "speed": 9600, "eventFormat": 0, - "num": 43 + "num": 42 }, { "header": "executive_devices" }, { "global": 0, - "name": "44. Кнопка подключенная к пину", + "name": "43. Кнопка подключенная к пину", "type": "Writing", "subtype": "ButtonIn", "id": "btn", @@ -671,11 +649,11 @@ "debounceDelay": 50, "fixState": 0, "inv": 0, - "num": 44 + "num": 43 }, { "global": 0, - "name": "45. Управление пином", + "name": "44. Управление пином", "type": "Writing", "subtype": "ButtonOut", "needSave": 0, @@ -686,11 +664,11 @@ "int": 0, "inv": 0, "pin": 2, - "num": 45 + "num": 44 }, { "global": 0, - "name": "46. Пассивный звуковой извещатель", + "name": "45. Пассивный звуковой извещатель", "type": "Writing", "subtype": "Buzzer", "id": "buzzer", @@ -709,11 +687,11 @@ "cycle": 0, "indication": 1, "val": 0, - "num": 46 + "num": 45 }, { "global": 0, - "name": "47. Энкодер", + "name": "46. Энкодер", "type": "Writing", "subtype": "Encoder", "id": "enc", @@ -726,11 +704,11 @@ "step": 1, "stepOnPress": 5, "pins": "4,5,2", - "num": 47 + "num": 46 }, { "global": 0, - "name": "48. Сервопривод", + "name": "47. Сервопривод", "type": "Writing", "subtype": "IoTServo", "id": "servo", @@ -741,11 +719,11 @@ "pin": 12, "apin": -1, "amap": "0, 4096, 0, 180", - "num": 48 + "num": 47 }, { "global": 0, - "name": "49. Расширитель портов Mcp23017", + "name": "48. Расширитель портов Mcp23017", "type": "Reading", "subtype": "Mcp23017", "id": "Mcp", @@ -755,11 +733,11 @@ "int": "0", "addr": "0x20", "index": 1, - "num": 49 + "num": 48 }, { "global": 0, - "name": "50. MP3 плеер", + "name": "49. MP3 плеер", "type": "Reading", "subtype": "Mp3", "id": "mp3", @@ -769,11 +747,11 @@ "int": 1, "pins": "14,12", "volume": 20, - "num": 50 + "num": 49 }, { "global": 0, - "name": "51. Сенсорная кнопка", + "name": "50. Сенсорная кнопка", "type": "Writing", "subtype": "Multitouch", "id": "impulse", @@ -787,11 +765,11 @@ "pinMode": "INPUT", "debounceDelay": 50, "PWMDelay": 500, - "num": 51 + "num": 50 }, { "global": 0, - "name": "52. Расширитель портов Pcf8574", + "name": "51. Расширитель портов Pcf8574", "type": "Reading", "subtype": "Pcf8574", "id": "Pcf", @@ -801,11 +779,11 @@ "int": "0", "addr": "0x20", "index": 1, - "num": 52 + "num": 51 }, { "global": 0, - "name": "53. PWM ESP8266", + "name": "52. PWM ESP8266", "type": "Writing", "subtype": "Pwm8266", "id": "pwm", @@ -817,11 +795,11 @@ "freq": 5000, "val": 0, "apin": -1, - "num": 53 + "num": 52 }, { "global": 0, - "name": "54. Телеграм-Лайт", + "name": "53. Телеграм-Лайт", "type": "Writing", "subtype": "TelegramLT", "id": "tg", @@ -830,14 +808,14 @@ "descr": "", "token": "", "chatID": "", - "num": 54 + "num": 53 }, { "header": "screens" }, { "global": 0, - "name": "55. LCD экран 2004", + "name": "54. LCD экран 2004", "type": "Reading", "subtype": "Lcd2004", "id": "Lcd", @@ -850,10 +828,10 @@ "id2show": "", "prefix": "", "postfix": "", - "num": 55 + "num": 54 }, { - "name": "56. LCD экран 1602", + "name": "55. LCD экран 1602", "type": "Reading", "subtype": "Lcd2004", "id": "Lcd", @@ -866,6 +844,23 @@ "id2show": "", "prefix": "", "postfix": "", + "num": 55 + }, + { + "global": 0, + "name": "56. OLED экран 64 8266", + "type": "Reading", + "subtype": "Oled64", + "id": "Oled", + "widget": "inputTxt", + "page": "screens", + "descr": "OLED Экран", + "addr": "0x3C", + "coord": "0,0", + "size": "1", + "id2show": "", + "prefix": "", + "postfix": "", "num": 56 }, { diff --git a/data_svelte/ota.json b/data_svelte/ota.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/data_svelte/ota.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/include/Const.h b/include/Const.h index 9be4bd94..2865cd60 100644 --- a/include/Const.h +++ b/include/Const.h @@ -2,7 +2,7 @@ #include "BuildTime.h" // Версия прошивки -#define FIRMWARE_VERSION 452 +#define FIRMWARE_VERSION 454 #ifdef esp8266_1mb_ota #define FIRMWARE_NAME "esp8266_1mb_ota" @@ -45,7 +45,7 @@ #endif // Размер буфера json -#define JSON_BUFFER_SIZE 4096 // держим 2 кб не меняем +#define JSON_BUFFER_SIZE 4096 // держим 2 кб не меняем /* WEB_SOCKETS_FRAME_SIZE создан для того что бы не загружать оперативку. @@ -74,22 +74,24 @@ WEB_SOCKETS_FRAME_SIZE создан для того что бы не загру #define USE_LITTLEFS true -#define START_DATETIME 1661990400 // 01.09.2022 00:00:00 константа для сокращения unix time +#define START_DATETIME 1661990400 // 01.09.2022 00:00:00 константа для сокращения unix time #define MIN_DATETIME 1575158400 #define LEAP_YEAR(Y) (((1970 + Y) > 0) && !((1970 + Y) % 4) && (((1970 + Y) % 100) || !((1970 + Y) % 400))) // задачи таскера -enum TimerTask_t { WIFI_SCAN, +enum TimerTask_t { + WIFI_SCAN, WIFI_MQTT_CONNECTION_CHECK, TIME, TIME_SYNC, UPTIME, - UDP, // UDPP - TIMES, // периодические секундные проверки + UDP, // UDPP + TIMES, // периодические секундные проверки PTASK, ST, - END }; + END +}; // задачи которые надо протащить через loop enum NotAsyncActions { @@ -99,15 +101,7 @@ enum NotAsyncActions { }; // состояния обновления -enum UpdateStates { NOT_STARTED, - UPDATE_FS_IN_PROGRESS, - UPDATE_FS_COMPLETED, - UPDATE_FS_FAILED, - UPDATE_BUILD_IN_PROGRESS, - UPDATE_BUILD_COMPLETED, - UPDATE_BUILD_FAILED, - PATH_ERROR -}; +enum UpdateStates { UPDATE_COMPLETED, UPDATE_FAILED, PATH_ERROR }; enum distination { TO_MQTT, diff --git a/include/UpgradeFirm.h b/include/UpgradeFirm.h index 63ddb167..c7b8d120 100644 --- a/include/UpgradeFirm.h +++ b/include/UpgradeFirm.h @@ -25,4 +25,4 @@ extern void restartEsp(); extern const String getBinPath(String file); extern void putUserDataToRam(); extern void saveUserDataToFlash(); -extern void handleUpdateStatus(bool send, int state); \ No newline at end of file +extern void saveUpdeteStatus(String key, int val); \ No newline at end of file diff --git a/myProfile.json b/myProfile.json index baec7668..0e4c8536 100644 --- a/myProfile.json +++ b/myProfile.json @@ -130,7 +130,7 @@ }, { "path": "src/modules/virtual/owmWeather", - "active": true + "active": false }, { "path": "src/modules/virtual/Timer", @@ -422,6 +422,10 @@ "path": "src/modules/display/Oled128", "active": false }, + { + "path": "src/modules/display/Oled64", + "active": true + }, { "path": "src/modules/display/Smi2_m", "active": true diff --git a/platformio.ini b/platformio.ini index 9a569937..10eae1e1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -501,6 +501,8 @@ lib_deps = adafruit/Adafruit BusIO @ ^1.13.2 https://github.com/robotclass/RobotClass_LiquidCrystal_I2C marcoschwartz/LiquidCrystal_I2C@^1.1.4 + https://github.com/stblassitude/Adafruit_SSD1306_Wemos_OLED + https://github.com/adafruit/Adafruit-GFX-Library https://github.com/maxint-rd/TM16xx adafruit/Adafruit GFX Library @ ^1.11.5 adafruit/Adafruit BusIO @ ^1.13.2 @@ -508,7 +510,6 @@ build_src_filter = + + + - + + + + @@ -541,6 +542,7 @@ build_src_filter = + + + + + + [env:esp32_4mb_fromitems] @@ -562,8 +564,11 @@ lib_deps = adafruit/Adafruit BusIO @ ^1.13.2 https://github.com/robotclass/RobotClass_LiquidCrystal_I2C marcoschwartz/LiquidCrystal_I2C@^1.1.4 + https://github.com/stblassitude/Adafruit_SSD1306_Wemos_OLED + https://github.com/adafruit/Adafruit-GFX-Library https://github.com/maxint-rd/TM16xx adafruit/Adafruit GFX Library @ ^1.11.5 + adafruit/Adafruit BusIO @ ^1.13.2 build_src_filter = + + @@ -599,6 +604,7 @@ build_src_filter = + + + + + + + diff --git a/src/UpgradeFirm.cpp b/src/UpgradeFirm.cpp index 05934011..37f3fe9c 100644 --- a/src/UpgradeFirm.cpp +++ b/src/UpgradeFirm.cpp @@ -4,6 +4,8 @@ updateFirm update; void upgrade_firmware(int type, String path) { putUserDataToRam(); + // сбросим файл статуса последнего обновления + writeFile("ota.json", "{}"); // only build if (type == 1) { @@ -36,10 +38,10 @@ bool upgradeFS(String path) { bool ret = false; WiFiClient wifiClient; SerialPrint("!!!", F("Update"), "Start upgrade FS... " + path); - handleUpdateStatus(true, UPDATE_FS_IN_PROGRESS); + if (path == "") { SerialPrint("E", F("Update"), F("FS Path error")); - handleUpdateStatus(true, PATH_ERROR); + saveUpdeteStatus("fs", PATH_ERROR); return ret; } #ifdef ESP8266 @@ -55,10 +57,10 @@ bool upgradeFS(String path) { // если FS обновилась успешно if (retFS == HTTP_UPDATE_OK) { SerialPrint("!!!", F("Update"), F("FS upgrade done!")); - handleUpdateStatus(true, UPDATE_FS_COMPLETED); + saveUpdeteStatus("fs", UPDATE_COMPLETED); ret = true; } else { - handleUpdateStatus(true, UPDATE_FS_FAILED); + saveUpdeteStatus("fs", UPDATE_FAILED); if (retFS == HTTP_UPDATE_FAILED) { SerialPrint("E", F("Update"), "HTTP_UPDATE_FAILED"); } else if (retFS == HTTP_UPDATE_NO_UPDATES) { @@ -72,10 +74,10 @@ bool upgradeBuild(String path) { bool ret = false; WiFiClient wifiClient; SerialPrint("!!!", F("Update"), "Start upgrade BUILD... " + path); - handleUpdateStatus(true, UPDATE_BUILD_IN_PROGRESS); + if (path == "") { SerialPrint("E", F("Update"), F("Build Path error")); - handleUpdateStatus(true, PATH_ERROR); + saveUpdeteStatus("build", PATH_ERROR); return ret; } #if defined(esp8266_4mb) || defined(esp8266_16mb) || defined(esp8266_1mb) || defined(esp8266_1mb_ota) || defined(esp8266_2mb) || defined(esp8266_2mb_ota) @@ -90,10 +92,10 @@ bool upgradeBuild(String path) { // если BUILD обновился успешно if (retBuild == HTTP_UPDATE_OK) { SerialPrint("!!!", F("Update"), F("BUILD upgrade done!")); - handleUpdateStatus(true, UPDATE_BUILD_COMPLETED); + saveUpdeteStatus("build", UPDATE_COMPLETED); ret = true; } else { - handleUpdateStatus(true, UPDATE_BUILD_FAILED); + saveUpdeteStatus("build", UPDATE_FAILED); if (retBuild == HTTP_UPDATE_FAILED) { SerialPrint("E", F("Update"), "HTTP_UPDATE_FAILED"); } else if (retBuild == HTTP_UPDATE_NO_UPDATES) { @@ -132,7 +134,7 @@ void putUserDataToRam() { update.settingsFlashJson = readFile("settings.json", 4096); update.layoutJson = readFile("layout.json", 4096); update.scenarioTxt = readFile("scenario.txt", 4096); - update.chartsData = createDataBaseSting(); + // update.chartsData = createDataBaseSting(); } void saveUserDataToFlash() { @@ -140,10 +142,13 @@ void saveUserDataToFlash() { writeFile("/settings.json", update.settingsFlashJson); writeFile("/layout.json", update.layoutJson); writeFile("/scenario.txt", update.scenarioTxt); - writeDataBaseSting(update.chartsData); + // writeDataBaseSting(update.chartsData); } -void handleUpdateStatus(bool send, int state) { - jsonWriteInt_(errorsHeapJson, F("upd"), state); - if (send) sendStringToWs("errors", errorsHeapJson, -1); +void saveUpdeteStatus(String key, int val) { + const String path = "ota.json"; + String json = readFile(path, 1024); + if (json == "failed") json = "{}"; + jsonWriteInt_(json, key, val); + writeFile(path, json); } \ No newline at end of file diff --git a/src/WsServer.cpp b/src/WsServer.cpp index 4030baef..0965338d 100644 --- a/src/WsServer.cpp +++ b/src/WsServer.cpp @@ -3,339 +3,331 @@ extern IoTScenario iotScen; #ifdef STANDARD_WEB_SOCKETS -void standWebSocketsInit() -{ +void standWebSocketsInit() { 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) -{ +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_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(); - } - // 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; + 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(); } - } - if (!endOfHeaderFound) { - SerialPrint("E", "WS " + String(num), "Package without header"); - } + // 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; - //----------------------------------------------------------------------// - // Страница веб интерфейса dashboard - //----------------------------------------------------------------------// + 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"); + } - // публикация всех виджетов - if (headerStr == "/|") { - sendFileToWsByFrames("/layout.json", "layout", "", num, WEB_SOCKETS_FRAME_SIZE); - } + //----------------------------------------------------------------------// + // Страница веб интерфейса dashboard + //----------------------------------------------------------------------// - 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()); + // публикация всех виджетов + 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()); + } + } + } + sendStringToWs("params", params, num); + + // генерация события подключения в модулях + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + if ((*it)->iAmLocal) (*it)->onMqttWsAppConnectEvent(); + } + } + + // отвечаем на запрос графиков + 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(); } } } - sendStringToWs("params", params, num); - // генерация события подключения в модулях - for (std::list::iterator it = IoTItems.begin(); - it != IoTItems.end(); ++it) { - if ((*it)->iAmLocal) - (*it)->onMqttWsAppConnectEvent(); + //----------------------------------------------------------------------// + // Страница веб интерфейса configutation + //----------------------------------------------------------------------// + + // отвечаем данными на запрос страницы + 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); } - } - // отвечаем на запрос графиков - 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 == "/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); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса connection + //----------------------------------------------------------------------// + + // отвечаем данными на запрос страницы + if (headerStr == "/connection|") { + sendFileToWsByFrames("/widgets.json", "widget", "", num, WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/config.json", "config", "", num, WEB_SOCKETS_FRAME_SIZE); + sendStringToWs("settin", settingsFlashJson, num); + sendStringToWs("ssidli", ssidListHeapJson, num); + sendStringToWs("errors", errorsHeapJson, num); + // запуск асинхронного сканирования wifi сетей при переходе на страницу + // соединений RouterFind(jsonReadStr(settingsFlashJson, + // F("routerssid"))); + } + + // обработка кнопки сохранить settings.json + if (headerStr == "/sgnittes|") { + writeUint8tToString(payload, length, headerLenth, settingsFlashJson); + writeFileUint8tByFrames("settings.json", payload, length, headerLenth, 256); + sendStringToWs("errors", errorsHeapJson, num); + // если не было создано приема данных по udp - то создадим его + addThisDeviceToList(); + } + + // обработка кнопки сохранить настройки mqtt + if (headerStr == "/mqtt|") { + sendStringToWs("settin", settingsFlashJson, + num); // отправляем в ответ новые полученные настройки + handleMqttStatus(false, 8); // меняем статус на неопределенный + mqttReconnect(); // начинаем переподключение + sendStringToWs("errors", errorsHeapJson, + num); // отправляем что статус неопределен + sendStringToWs("ssidli", ssidListHeapJson, num); + } + + // запуск асинхронного сканирования wifi сетей при нажатии выпадающего + // списка + if (headerStr == "/scan|") { + std::vector jArray; + jsonReadArray(settingsFlashJson, "routerssid", jArray); + RouterFind(jArray); + sendStringToWs("ssidli", ssidListHeapJson, num); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса list + //----------------------------------------------------------------------// + + // отвечаем данными на запрос страницы list + if (headerStr == "/list|") { + sendStringToWs("settin", settingsFlashJson, num); + // отправим список устройств в зависимости от того что выбрал user + // sendDeviceList(num); + } + + // отвечаем на запрос списка устройств (это отдельный запрос который + // делает приложение при подключении) + if (headerStr == "/devlist|") { + // отправим список устройств в зависимости от того что выбрал user + sendDeviceList(num); + } + + // сохраняем данные листа + if (headerStr == "/tsil|") { + writeFileUint8tByFrames("devlist.json", payload, length, headerLenth, 256); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса system + //----------------------------------------------------------------------// + + // отвечаем данными на запрос страницы + if (headerStr == "/system|") { + sendStringToWs("errors", errorsHeapJson, num); + sendStringToWs("settin", settingsFlashJson, 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); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса update + //----------------------------------------------------------------------// + if (headerStr == "/profile|") { + // для версии 451 отдаем myProfile.json + sendFileToWsByFrames("/ota.json", "otaupd", "", num, WEB_SOCKETS_FRAME_SIZE); + if (FileFS.exists("/myProfile.json")) { + sendFileToWsByFrames("/myProfile.json", "prfile", "", num, WEB_SOCKETS_FRAME_SIZE); + // для версии 452 и более отдаем flashProfile.json + } else if (FileFS.exists("/flashProfile.json")) { + sendFileToWsByFrames("/flashProfile.json", "prfile", "", num, WEB_SOCKETS_FRAME_SIZE); } } - } - //----------------------------------------------------------------------// - // Страница веб интерфейса configutation - //----------------------------------------------------------------------// + //----------------------------------------------------------------------// + // отдельные команды веб интерфейса + //----------------------------------------------------------------------// - // отвечаем данными на запрос страницы - 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); - } + // переписать любое поле в errors json + if (headerStr == "/rorre|") { + writeUint8tValueToJsonString(payload, length, headerLenth, errorsHeapJson); + } - // обработка кнопки сохранить - 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); - } + // команда перезагрузки esp + if (headerStr == "/reboot|") { + ESP.restart(); + } - //----------------------------------------------------------------------// - // Страница веб интерфейса connection - //----------------------------------------------------------------------// + // команда очистки всех логов esp + if (headerStr == "/clean|") { + cleanLogs(); + } - // отвечаем данными на запрос страницы - if (headerStr == "/connection|") { - sendFileToWsByFrames("/widgets.json", "widget", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/config.json", "config", "", num, WEB_SOCKETS_FRAME_SIZE); - sendStringToWs("settin", settingsFlashJson, num); - sendStringToWs("ssidli", ssidListHeapJson, num); - sendStringToWs("errors", errorsHeapJson, num); - // запуск асинхронного сканирования wifi сетей при переходе на страницу - // соединений RouterFind(jsonReadStr(settingsFlashJson, - // F("routerssid"))); - } + // команда обновления прошивки esp + if (headerStr == "/update|") { + String path; + writeUint8tToString(payload, length, headerLenth, path); + upgrade_firmware(3, path); + } - // обработка кнопки сохранить settings.json - if (headerStr == "/sgnittes|") { - writeUint8tToString(payload, length, headerLenth, settingsFlashJson); - writeFileUint8tByFrames("settings.json", payload, length, headerLenth, 256); - sendStringToWs("errors", errorsHeapJson, num); - // если не было создано приема данных по udp - то создадим его - addThisDeviceToList(); - } + // Прием команд 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); + } - // обработка кнопки сохранить настройки mqtt - if (headerStr == "/mqtt|") { - sendStringToWs("settin", settingsFlashJson, - num); // отправляем в ответ новые полученные настройки - handleMqttStatus(false, 8); // меняем статус на неопределенный - mqttReconnect(); // начинаем переподключение - sendStringToWs("errors", errorsHeapJson, - num); // отправляем что статус неопределен - sendStringToWs("ssidli", ssidListHeapJson, num); - } + if (headerStr == "/tst|") { + standWebSocket.sendTXT(num, "/tstr|"); + } - // запуск асинхронного сканирования wifi сетей при нажатии выпадающего - // списка - if (headerStr == "/scan|") { - std::vector jArray; - jsonReadArray(settingsFlashJson, "routerssid", jArray); - RouterFind(jArray); - sendStringToWs("ssidli", ssidListHeapJson, num); - } + // получаем команду посланную из модуля + if (headerStr == "/order|") { + String json; + writeUint8tToString(payload, length, headerLenth, json); - //----------------------------------------------------------------------// - // Страница веб интерфейса list - //----------------------------------------------------------------------// + String id, key, value; + jsonRead(json, "id", id); + jsonRead(json, "key", key); + jsonRead(json, "value", value); - // отвечаем данными на запрос страницы list - if (headerStr == "/list|") { - sendStringToWs("settin", settingsFlashJson, num); - // отправим список устройств в зависимости от того что выбрал user - // sendDeviceList(num); - } + SerialPrint("i", F("=>WS"), "Msg from module, id: " + id); - // отвечаем на запрос списка устройств (это отдельный запрос который - // делает приложение при подключении) - if (headerStr == "/devlist|") { - // отправим список устройств в зависимости от того что выбрал user - sendDeviceList(num); - } - - // сохраняем данные листа - if (headerStr == "/tsil|") { - writeFileUint8tByFrames("devlist.json", payload, length, headerLenth, - 256); - } - - //----------------------------------------------------------------------// - // Страница веб интерфейса system - //----------------------------------------------------------------------// - - // отвечаем данными на запрос страницы - if (headerStr == "/system|") { - sendStringToWs("errors", errorsHeapJson, num); - sendStringToWs("settin", settingsFlashJson, 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); - } - - //----------------------------------------------------------------------// - // Страница веб интерфейса update - //----------------------------------------------------------------------// - if (headerStr == "/profile|") { - sendFileToWsByFrames("/myProfile.json", "prfile", "", num, - WEB_SOCKETS_FRAME_SIZE); - } - - //----------------------------------------------------------------------// - // отдельные команды веб интерфейса - //----------------------------------------------------------------------// - - // переписать любое поле в errors json - if (headerStr == "/rorre|") { - writeUint8tValueToJsonString(payload, length, headerLenth, errorsHeapJson); - } - - // команда перезагрузки esp - if (headerStr == "/reboot|") { - ESP.restart(); - } - - // команда очистки всех логов esp - if (headerStr == "/clean|") { - cleanLogs(); - } - - // команда обновления прошивки esp - if (headerStr == "/update|") { - String path; - writeUint8tToString(payload, length, headerLenth, path); - upgrade_firmware(3, path); - } - - // Прием команд 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); - } - - if (headerStr == "/tst|") { - standWebSocket.sendTXT(num, "/tstr|"); - } - - // получаем команду посланную из модуля - if (headerStr == "/order|") { - String json; - writeUint8tToString(payload, length, headerLenth, json); - - String id, key, value; - jsonRead(json, "id", id); - jsonRead(json, "key", key); - jsonRead(json, "value", value); - - SerialPrint("i", F("=>WS"), "Msg from module, id: " + id); - - for (std::list::iterator it = IoTItems.begin(); - it != IoTItems.end(); ++it) { - if ((*it)->getID() == id) { - (*it)->onModuleOrder(key, value); + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + if ((*it)->getID() == id) { + (*it)->onModuleOrder(key, value); + } } } - } - } break; + } 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_BIN: { + Serial.printf("[%u] get binary length: %u\n", num, length); + // hexdump(payload, length); + // standWebSocket.sendBIN(num, payload, length); + } break; - case WStype_FRAGMENT_TEXT_START: { - Serial.printf("[%u] fragment test start: %u\n", num, length); - } break; + case WStype_FRAGMENT_TEXT_START: { + Serial.printf("[%u] fragment test start: %u\n", num, length); + } break; - case WStype_FRAGMENT_BIN_START: { - Serial.printf("[%u] fragment bin start: %u\n", num, length); - } break; + case WStype_FRAGMENT_BIN_START: { + Serial.printf("[%u] fragment bin start: %u\n", num, length); + } break; - case WStype_FRAGMENT: { - Serial.printf("[%u] fragment: %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_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_PING: { + Serial.printf("[%u] ping: %u\n", num, length); + } break; - case WStype_PONG: { - Serial.printf("[%u] pong: %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 (недостаток в том что делаем бродкаст всем // клиентам поднятым в свелте!!!) -void publishStatusWs(const String& topic, const String& data) -{ +void publishStatusWs(const String& topic, const String& data) { String path = mqttRootDevice + "/" + topic; String json = "{}"; jsonWriteStr(json, "status", data); @@ -344,8 +336,7 @@ void publishStatusWs(const String& topic, const String& data) } // публикация дополнительных json сообщений в ws -void publishJsonWs(const String& topic, String& json) -{ +void publishJsonWs(const String& topic, String& json) { String path = mqttRootDevice + "/" + topic; jsonWriteStr(json, "topic", path); // TO DO отправка полей в веб @@ -353,8 +344,7 @@ void publishJsonWs(const String& topic, String& json) } // данные которые мы отправляем в сокеты переодически -void periodicWsSend() -{ +void periodicWsSend() { sendStringToWs("ssidli", ssidListHeapJson, -1); sendStringToWs("errors", errorsHeapJson, -1); // отправляем переодичестки только в авто режиме @@ -364,11 +354,9 @@ void periodicWsSend() } #ifdef ESP32 -void hexdump(const void* mem, uint32_t len, uint8_t cols = 16) -{ +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); + 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); @@ -381,9 +369,7 @@ void hexdump(const void* mem, uint32_t len, uint8_t cols = 16) #endif #endif -void sendFileToWsByFrames(const String& filename, const String& header, - const String& json, int client_id, size_t frameSize) -{ +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; @@ -456,8 +442,7 @@ void sendFileToWsByFrames(const String& filename, const String& header, file.close(); } -void sendStringToWs(const String& header, String& payload, int client_id) -{ +void sendStringToWs(const String& header, String& payload, int client_id) { if ((!getNumAPClients() && !isNetworkActive()) || !getNumWSClients()) { // standWebSocket.disconnect(); // это и ниже надо сделать при - // standWebSocket.close(); // - отключении AP И WiFi(STA), надо менять ядро WiFi. Сейчас не закрывается сессия клиента при пропаже AP И WiFi(STA) @@ -481,21 +466,16 @@ void sendStringToWs(const String& header, String& payload, int client_id) } } -void sendDeviceList(uint8_t num) -{ +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); + sendFileToWsByFrames("/devlist.json", "devlis", "", num, WEB_SOCKETS_FRAME_SIZE); SerialPrint("i", "FS", "flash list"); } } -int getNumWSClients() -{ - return standWebSocket.connectedClients(false); -} \ No newline at end of file +int getNumWSClients() { return standWebSocket.connectedClients(false); } \ No newline at end of file diff --git a/src/modules/API.cpp b/src/modules/API.cpp index 532ec78a..fa6af247 100644 --- a/src/modules/API.cpp +++ b/src/modules/API.cpp @@ -3,7 +3,6 @@ void* getAPI_Cron(String subtype, String params); void* getAPI_Loging(String subtype, String params); void* getAPI_LogingDaily(String subtype, String params); -void* getAPI_owmWeather(String subtype, String params); void* getAPI_Timer(String subtype, String params); void* getAPI_Variable(String subtype, String params); void* getAPI_VariableColor(String subtype, String params); @@ -36,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_Oled64(String subtype, String params); void* getAPI_TM16XX(String subtype, String params); void* getAPI(String subtype, String params) { @@ -43,7 +43,6 @@ void* tmpAPI; if ((tmpAPI = getAPI_Cron(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Loging(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_LogingDaily(subtype, params)) != nullptr) return tmpAPI; -if ((tmpAPI = getAPI_owmWeather(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Timer(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Variable(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_VariableColor(subtype, params)) != nullptr) return tmpAPI; @@ -76,6 +75,7 @@ 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_Oled64(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/Lcd2004/Lcd2004.cpp b/src/modules/display/Lcd2004/Lcd2004.cpp index 5ddd92b5..4580c49c 100644 --- a/src/modules/display/Lcd2004/Lcd2004.cpp +++ b/src/modules/display/Lcd2004/Lcd2004.cpp @@ -2,7 +2,7 @@ #include "classes/IoTItem.h" #include -RobotClass_LiquidCrystal_I2C *LCDI2C; +RobotClass_LiquidCrystal_I2C* LCDI2C; class Lcd2004 : public IoTItem { private: @@ -12,7 +12,7 @@ class Lcd2004 : public IoTItem { int _prevStrSize; String _addr; - bool _isShow = true; // экран показывает + bool _isShow = true; // экран показывает public: Lcd2004(String parameters) : IoTItem(parameters) { @@ -26,9 +26,9 @@ class Lcd2004 : public IoTItem { } jsonRead(parameters, "size", size); - int w = selectFromMarkerToMarker(size, ",", 0).toInt(); //количество столбцов - int h = selectFromMarkerToMarker(size, ",", 1).toInt(); //количество строк - if (LCDI2C == nullptr) { //инициализации экрана еще не было + int w = selectFromMarkerToMarker(size, ",", 0).toInt(); // количество столбцов + int h = selectFromMarkerToMarker(size, ",", 1).toInt(); // количество строк + if (LCDI2C == nullptr) { // инициализации экрана еще не было LCDI2C = new RobotClass_LiquidCrystal_I2C(hexStringToUint8(_addr), w, h, CP_UTF8); if (LCDI2C != nullptr) { LCDI2C->init(); @@ -46,7 +46,7 @@ class Lcd2004 : public IoTItem { jsonRead(parameters, "postfix", _postfix); } - void drawItem(IoTItem* item) { + void drawItem(IoTItem* item) { String tmpStr = _prefix; tmpStr += item->getValue(); tmpStr += _postfix; @@ -66,15 +66,18 @@ class Lcd2004 : public IoTItem { } void onRegEvent(IoTItem* eventItem) { - if (LCDI2C == nullptr) { scanI2C(); return;} - if (!eventItem || _id2show == "") return; + if (LCDI2C == nullptr) { + scanI2C(); + return; + } + if (!eventItem || _id2show == "") return; if (_id2show == eventItem->getID()) { setValue(eventItem->value, false); } } - IoTValue execute(String command, std::vector ¶m) { + IoTValue execute(String command, std::vector& param) { if (command == "noBacklight") LCDI2C->noBacklight(); else if (command == "backlight") @@ -89,7 +92,7 @@ class Lcd2004 : public IoTItem { if (_isShow) { LCDI2C->noDisplay(); _isShow = false; - } else { + } else { LCDI2C->display(); _isShow = true; } @@ -119,7 +122,7 @@ class Lcd2004 : public IoTItem { return {}; } - //печать пустой строки нужной длинны для затирания предыдущего значения на экране + // печать пустой строки нужной длинны для затирания предыдущего значения на экране void printBlankStr(int strSize) { String tmpStr = ""; for (int i = 0; i < strSize; i++) tmpStr += " "; @@ -127,13 +130,13 @@ class Lcd2004 : public IoTItem { LCDI2C->print(tmpStr); } - ~Lcd2004(){ + ~Lcd2004() { if (LCDI2C) delete LCDI2C; LCDI2C = nullptr; }; }; -void *getAPI_Lcd2004(String subtype, String param) { +void* getAPI_Lcd2004(String subtype, String param) { if (subtype == F("Lcd2004")) { return new Lcd2004(param); } else { diff --git a/src/modules/display/Oled64/Oled64.cpp b/src/modules/display/Oled64/Oled64.cpp new file mode 100644 index 00000000..1a69e073 --- /dev/null +++ b/src/modules/display/Oled64/Oled64.cpp @@ -0,0 +1,134 @@ + + +#include "Global.h" +#include "classes/IoTItem.h" + +#include +#include +#include +#include + +#define OLED_RESET 0 +Adafruit_SSD1306 display(OLED_RESET); + +class Oled64 : public IoTItem { + private: + unsigned int _x; + unsigned int _y; + String _id2show, _prefix = "", _postfix = ""; + String _size = "1"; + String _addr; + + int _prevStrSize; + + bool _isShow = true; + + public: + Oled64(String parameters) : IoTItem(parameters) { + String size, xy; + _prevStrSize = 0; + + jsonRead(parameters, "addr", _addr); + if (_addr == "") { + scanI2C(); + return; + } + + display.begin(SSD1306_SWITCHCAPVCC, hexStringToUint8(_addr)); + + display.display(); + + display.clearDisplay(); + + jsonRead(parameters, "coord", xy); + _x = selectFromMarkerToMarker(xy, ",", 0).toInt(); + _y = selectFromMarkerToMarker(xy, ",", 1).toInt(); + jsonRead(parameters, "id2show", _id2show); + jsonRead(parameters, "prefix", _prefix); + jsonRead(parameters, "postfix", _postfix); + jsonRead(parameters, "size", _size); + } + + void drawItem(IoTItem *item) { + String tmpStr = _prefix; + tmpStr += item->getValue(); + tmpStr += _postfix; + + display.setRotation(0); + display.setCursor(_x, _y); + display.setTextColor(WHITE, BLACK); + display.setTextSize(_size.toInt()); + + printBlankStr(_prevStrSize); + + display.setCursor(_x, _y); + + display.print(tmpStr); + _prevStrSize = tmpStr.length(); + display.display(); + _prevStrSize = tmpStr.length(); + } + + void setValue(const IoTValue &Value, bool genEvent = true) { + value = Value; + drawItem(this); + IoTItem::setValue(Value, genEvent); + } + + void onRegEvent(IoTItem *eventItem) { + if (!eventItem || _id2show == "") return; + + if (_id2show == eventItem->getID()) { + setValue(eventItem->value, false); + } + } + + IoTValue execute(String command, std::vector ¶m) { + if (command == "display") { + _isShow = true; + } else if (command == "noDisplay") { + _isShow = false; + } 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 == "prefix") { + if (param.size()) { + _prefix = param[0].valS; + } + } else if (command == "postfix") { + if (param.size()) { + _postfix = 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 += " "; + display.setCursor(_x, _y); + display.print(tmpStr); + } + + ~Oled64(){}; +}; + +void *getAPI_Oled64(String subtype, String param) { + if (subtype == F("Oled64")) { + return new Oled64(param); + } else { + return nullptr; + } +} \ No newline at end of file diff --git a/src/modules/display/Oled64/modinfo.json b/src/modules/display/Oled64/modinfo.json new file mode 100644 index 00000000..39f0395a --- /dev/null +++ b/src/modules/display/Oled64/modinfo.json @@ -0,0 +1,97 @@ +{ + "menuSection": "screens", + "configItem": [ + { + "global": 0, + "name": "OLED экран 64 8266", + "type": "Reading", + "subtype": "Oled64", + "id": "Oled", + "widget": "inputTxt", + "page": "screens", + "descr": "OLED Экран", + "addr": "0x3C", + "coord": "0,0", + "size": "1", + "id2show": "", + "prefix": "", + "postfix": "" + } + ], + "about": { + "authorName": "Serghei Crasnicov", + "authorContact": "https://t.me/Serghei63", + "authorGit": "https://github.com/Serghei63", + "specialThanks": "Valentin Khandriga @Valiuhaaa", + "moduleName": "Oled64", + "moduleVersion": "1.0", + "usedRam": { + "esp32_4mb": 15, + "esp8266_4mb": 15 + }, + "title": "Модуль отображения на экранах OLED 64*48", + "moduleDesc": "Позволяет выводить на OLED экраны по указанным позициям значения других элементов конфигурации.", + "propInfo": { + "addr": "Адрес устройства на шине, обычно 0x3C.", + "coord": "Координата позиции для вывода данных элемента конфигурации.", + "id2show": "id элемента конфигурации.", + "size": "Размер шрифта. Допускается 1, 2, 3, 4" + }, + "funcInfo": [ + { + "name": "x", + "descr": "Устанавливает первую координату", + "params": [ + "Номер строки первого символа" + ] + }, + { + "name": "y", + "descr": "Устанавливает вторую координату", + "params": [ + "Номер столбца первого символа" + ] + }, + { + "name": "descr", + "descr": "Задает приставку слева от значения", + "params": [ + "Строка" + ] + }, + { + "name": "descr1", + "descr1": "Задает приставку справа от значения", + "params": [ + "Строка" + ] + }, + { + "name": "id2show", + "descr": "Задает ИД элемента, значение которого хотим отображать на экране", + "params": [ + "Имя элемента конфигурации" + ] + } + ] + }, + "defActive": true, + "usedLibs": { + "esp32_4mb": [ + "https://github.com/stblassitude/Adafruit_SSD1306_Wemos_OLED", + "https://github.com/adafruit/Adafruit-GFX-Library" + ], + "esp8266_4mb": [ + "https://github.com/stblassitude/Adafruit_SSD1306_Wemos_OLED", + "https://github.com/adafruit/Adafruit-GFX-Library" + ], + "esp8266_1mb": [ + "https://github.com/stblassitude/Adafruit_SSD1306_Wemos_OLED", + "https://github.com/adafruit/Adafruit-GFX-Library" + ], + "esp8266_1mb_ota": [ + "https://github.com/stblassitude/Adafruit_SSD1306_Wemos_OLED", + "https://github.com/adafruit/Adafruit-GFX-Library" + ] + } +} \ No newline at end of file diff --git a/src/modules/exec/HttpGet/HttpGet.cpp b/src/modules/exec/HttpGet/HttpGet.cpp index 180d9099..269cedd5 100644 --- a/src/modules/exec/HttpGet/HttpGet.cpp +++ b/src/modules/exec/HttpGet/HttpGet.cpp @@ -1,18 +1,12 @@ #include "Global.h" #include "classes/IoTItem.h" -class HttpGet : public IoTItem -{ -public: - HttpGet(String parameters) : IoTItem(parameters) - { - } - - void sendHttpPOST(String url, String msg) - { - if (isNetworkActive()) - { +class HttpGet : public IoTItem { + public: + HttpGet(String parameters) : IoTItem(parameters) {} + void sendHttpPOST(String url, String msg) { + if (isNetworkActive()) { WiFiClient client; HTTPClient http; http.begin(client, url); @@ -23,26 +17,23 @@ public: SerialPrint("<-", F("HttpPOST"), "URL: " + url + ", msg: " + msg); SerialPrint("->", F("HttpPOST"), "URL: " + url + ", server: " + httpResponseCode); - if (httpResponseCode > 0) - { + if (httpResponseCode > 0) { value.valS = payload; + value.isDecimal = false; SerialPrint("->", F("HttpPOST"), "msg from server: " + (String)payload.c_str()); - value.valS = payload; regEvent(value.valS, "HttpGet"); } http.end(); } } - void sendHttpGET(String url) - { + + void sendHttpGET(String url) { WiFiClient client; HTTPClient http; #if defined ESP8266 - if (!http.begin(client, url)) - { + if (!http.begin(client, url)) { #elif defined ESP32 - if (!http.begin(url)) - { + if (!http.begin(url)) { #endif SerialPrint("I", F("HttpGet"), "connection failed "); @@ -52,31 +43,23 @@ public: String payload = http.getString(); SerialPrint("<-", F("HttpGET"), "URL: " + url); SerialPrint("->", F("HttpGET"), "URL: " + url + ", server: " + httpResponseCode); - if (httpResponseCode > 0) - { + if (httpResponseCode > 0) { value.valS = payload; + value.isDecimal = false; SerialPrint("->", F("HttpGET"), "msg from server: " + (String)payload.c_str()); - value.valS = payload; regEvent(value.valS, "HttpGet"); } http.end(); } - IoTValue execute(String command, std::vector ¶m) - { - if (param.size() > 0) - { - if (command == "get") - { - if (param.size()) - { + IoTValue execute(String command, std::vector ¶m) { + if (param.size() > 0) { + if (command == "get") { + if (param.size()) { sendHttpGET(param[0].valS); } - } - else if (command == "post") - { - if (param.size()) - { + } else if (command == "post") { + if (param.size()) { sendHttpPOST(param[0].valS, param[1].valS); } } @@ -87,14 +70,10 @@ public: ~HttpGet(){}; }; -void *getAPI_HttpGet(String subtype, String param) -{ - if (subtype == F("HttpGet")) - { +void *getAPI_HttpGet(String subtype, String param) { + if (subtype == F("HttpGet")) { return new HttpGet(param); - } - else - { + } else { return nullptr; } } \ No newline at end of file diff --git a/src/modules/virtual/owmWeather/modinfo.json b/src/modules/virtual/owmWeather/modinfo.json index 778c0fd7..520e0761 100644 --- a/src/modules/virtual/owmWeather/modinfo.json +++ b/src/modules/virtual/owmWeather/modinfo.json @@ -1,6 +1,5 @@ { "menuSection": "virtual_elments", - "configItem": [ { "global": 0, @@ -24,7 +23,6 @@ "debug": 0 } ], - "about": { "authorName": "Serghei Crasnicov, v2.0 Mikhail Bubnov", "authorContact": "https://t.me/Serghei63", @@ -60,24 +58,14 @@ "lon": "Долгота, при использовании координат, будет автоматически выбран ближайший город", "lat": "Широта, при использовании координат, будет автоматически выбран ближайший город", "lang": "Язык используемый в ответах OpenWetaherMap", - "debug":"1 - выводить дополнительный лог в сериал" + "debug": "1 - выводить дополнительный лог в сериал" } }, - - "defActive": true, - + "defActive": false, "usedLibs": { "esp32_4mb": [], "esp32_4mb3f": [], "esp32s2_4mb": [], - "esp32_16mb": [], - "esp8266_4mb": [], - "esp8266_16mb": [], - "esp8266_1mb": [], - "esp8266_1mb_ota": [], - "esp8285_1mb": [], - "esp8285_1mb_ota": [], - "esp8266_2mb": [], - "esp8266_2mb_ota": [] + "esp32_16mb": [] } -} +} \ No newline at end of file diff --git a/src/utils/FileUtils.cpp b/src/utils/FileUtils.cpp index f59316d5..c12bffbe 100644 --- a/src/utils/FileUtils.cpp +++ b/src/utils/FileUtils.cpp @@ -124,8 +124,8 @@ const String readFile(const String& filename, size_t max_size) { size_t size = file.size(); if (size > max_size) { file.close(); - if (path == "/config.json") - return "[]"; + // что это за бред! + if (path == "/config.json") return "[]"; return "large"; } String temp = file.readString(); @@ -133,9 +133,7 @@ const String readFile(const String& filename, size_t max_size) { return temp; } -const String filepath(const String& filename) { - return filename.startsWith("/") ? filename : "/" + filename; -} +const String filepath(const String& filename) { return filename.startsWith("/") ? filename : "/" + filename; } bool cutFile(const String& src, const String& dst) { String srcPath = filepath(src); @@ -288,9 +286,7 @@ String getFilesList(String& directory) { } #if defined(ESP8266) -bool getInfo(FSInfo& info) { - return FileFS.info(info); -} +bool getInfo(FSInfo& info) { return FileFS.info(info); } // Информация о ФС IoTFSInfo getFSInfo() { diff --git a/src/utils/JsonUtils.cpp b/src/utils/JsonUtils.cpp index 845c1179..9a616d26 100644 --- a/src/utils/JsonUtils.cpp +++ b/src/utils/JsonUtils.cpp @@ -2,13 +2,9 @@ #include "utils/FileUtils.h" // new================================================================================ -String jsonReadStrDoc(DynamicJsonDocument &doc, String name) { - return doc[name].as(); -} +String jsonReadStrDoc(DynamicJsonDocument &doc, String name) { return doc[name].as(); } -void jsonWriteStrDoc(DynamicJsonDocument &doc, String name, String value) { - doc[name] = value; -} +void jsonWriteStrDoc(DynamicJsonDocument &doc, String name, String value) { doc[name] = value; } // new============================================================================== bool jsonRead(const String &json, String key, long &value, bool e) { @@ -114,21 +110,14 @@ bool jsonReadArray(const String &json, String key, std::vector &jArray, } 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()); + for (int8_t i = 0; i < doc[key].size(); i++) jArray.push_back(doc[key][i].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; }