From 162545559486154fb8af4a64d559547c66ea99ec Mon Sep 17 00:00:00 2001 From: Dmitry Borisenko <49808844+DmitryBorisenko33@users.noreply.github.com> Date: Wed, 28 Sep 2022 17:55:35 +0200 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B4=D0=BD=D0=B5=D0=B2=D0=BD=D0=BE=D0=B3=D0=BE=20?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D1=85=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +- data_svelte/build/bundle.css.gz | Bin 5478 -> 5478 bytes data_svelte/build/bundle.js.gz | Bin 46614 -> 46623 bytes data_svelte/index.html | 6 +- data_svelte/items.json | 191 ++++++------ data_svelte/widgets.json | 21 +- include/Const.h | 2 +- myProfile.json | 6 +- platformio.ini | 3 +- src/MqttClient.cpp | 3 +- src/WsServer.cpp | 3 +- src/modules/API.cpp | 2 + .../virtual/{Logging => Loging}/Loging.cpp | 0 .../virtual/{Logging => Loging}/modinfo.json | 4 +- .../virtual/LogingDaily/LogingDaily.cpp | 282 ++++++++++++++++++ src/modules/virtual/LogingDaily/modinfo.json | 39 +++ src/utils/FileUtils.cpp | 3 +- 17 files changed, 453 insertions(+), 115 deletions(-) rename src/modules/virtual/{Logging => Loging}/Loging.cpp (100%) rename src/modules/virtual/{Logging => Loging}/modinfo.json (79%) create mode 100644 src/modules/virtual/LogingDaily/LogingDaily.cpp create mode 100644 src/modules/virtual/LogingDaily/modinfo.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 89f6be4b..61cd5f78 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,7 @@ "vector": "cpp", "string_view": "cpp", "initializer_list": "cpp", - "ranges": "cpp" + "ranges": "cpp", + "thread": "cpp" } } \ No newline at end of file diff --git a/data_svelte/build/bundle.css.gz b/data_svelte/build/bundle.css.gz index c361c2f9029184fd5d7f1858751ace55ea7190e7..bf923a9905ecbde9f112060839eb8bc54b357696 100644 GIT binary patch delta 16 XcmaE+^-POhzMF%CFT-Rbd%P$BF1-Y} delta 16 XcmaE+^-POhzMF$X*2HKdd%P$BE#w4| diff --git a/data_svelte/build/bundle.js.gz b/data_svelte/build/bundle.js.gz index 06ffd07e8462b5a6eb02175d434ff21fcdc9c157..52ed0f7738a4299aeb4327e0a3391fa7193a5009 100644 GIT binary patch delta 28824 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 delta 28795 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 CST8I9 diff --git a/data_svelte/index.html b/data_svelte/index.html index b036526e..f9d231aa 100644 --- a/data_svelte/index.html +++ b/data_svelte/index.html @@ -4,12 +4,12 @@ - IoT Manager 4.3.4 + IoT Manager 4.3.5 - + - + diff --git a/data_svelte/items.json b/data_svelte/items.json index 01d93319..dfc47a9c 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -7,7 +7,7 @@ "header": "Виртуальные элементы" }, { - "name": "1. Логирование в график", + "name": "1. График", "type": "Writing", "subtype": "Loging", "id": "log", @@ -20,7 +20,20 @@ "points": 300 }, { - "name": "2. Таймер", + "name": "2. График дневного расхода", + "type": "Writing", + "subtype": "LogingDaily", + "id": "log", + "widget": "chart3", + "page": "Графики", + "descr": "Температура", + "num": 2, + "int": 1, + "logid": "t", + "points": 365 + }, + { + "name": "3. Таймер", "type": "Writing", "subtype": "Timer", "id": "timer", @@ -32,10 +45,10 @@ "ticker": 1, "repeat": 1, "needSave": 0, - "num": 2 + "num": 3 }, { - "name": "3. Окно ввода числа (переменная)", + "name": "4. Окно ввода числа (переменная)", "type": "Reading", "subtype": "Variable", "id": "value", @@ -44,10 +57,10 @@ "descr": "Введите число", "int": "0", "val": "0.0", - "num": 3 + "num": 4 }, { - "name": "4. Окно ввода времени", + "name": "5. Окно ввода времени", "type": "Reading", "subtype": "Variable", "id": "time", @@ -56,10 +69,10 @@ "descr": "Введите время", "int": "0", "val": "02:00", - "num": 4 + "num": 5 }, { - "name": "5. Окно ввода даты", + "name": "6. Окно ввода даты", "type": "Reading", "subtype": "Variable", "id": "time", @@ -68,10 +81,10 @@ "descr": "Введите дату", "int": "0", "val": "24.05.2022", - "num": 5 + "num": 6 }, { - "name": "6. Окно ввода текста", + "name": "7. Окно ввода текста", "type": "Reading", "subtype": "Variable", "id": "txt", @@ -80,10 +93,10 @@ "descr": "Введите текст", "int": "0", "val": "текст", - "num": 6 + "num": 7 }, { - "name": "7. Виртуальная кнопка", + "name": "8. Виртуальная кнопка", "type": "Reading", "subtype": "VButton", "id": "vbtn", @@ -92,13 +105,13 @@ "descr": "Кнопка", "int": "0", "val": "0", - "num": 7 + "num": 8 }, { "header": "Сенсоры" }, { - "name": "8. Acs712 Ток", + "name": "9. Acs712 Ток", "type": "Reading", "subtype": "Acs712", "id": "amp", @@ -108,10 +121,10 @@ "round": 3, "pin": 39, "int": 5, - "num": 8 + "num": 9 }, { - "name": "9. AHT20 Температура", + "name": "10. AHT20 Температура", "type": "Reading", "subtype": "Aht20t", "id": "Temp20", @@ -121,10 +134,10 @@ "int": 15, "addr": "0x38", "round": 1, - "num": 9 + "num": 10 }, { - "name": "10. AHT20 Влажность", + "name": "11. AHT20 Влажность", "type": "Reading", "subtype": "Aht20h", "id": "Hum20", @@ -134,10 +147,10 @@ "int": 15, "addr": "0x38", "round": 1, - "num": 10 + "num": 11 }, { - "name": "11. Аналоговый сенсор", + "name": "12. Аналоговый сенсор", "type": "Reading", "subtype": "AnalogAdc", "id": "t", @@ -151,10 +164,10 @@ "pin": 0, "int": 15, "avgSteps": 1, - "num": 11 + "num": 12 }, { - "name": "12. BME280 Температура", + "name": "13. BME280 Температура", "type": "Reading", "subtype": "Bme280t", "id": "tmp3", @@ -164,10 +177,10 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 12 + "num": 13 }, { - "name": "13. BME280 Давление", + "name": "14. BME280 Давление", "type": "Reading", "subtype": "Bme280p", "id": "Press3", @@ -177,10 +190,10 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 13 + "num": 14 }, { - "name": "14. BME280 Влажность", + "name": "15. BME280 Влажность", "type": "Reading", "subtype": "Bme280h", "id": "Hum3", @@ -190,10 +203,10 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 14 + "num": 15 }, { - "name": "15. BMP280 Температура", + "name": "16. BMP280 Температура", "type": "Reading", "subtype": "Bmp280t", "id": "tmp3", @@ -203,10 +216,10 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 15 + "num": 16 }, { - "name": "16. BMP280 Давление", + "name": "17. BMP280 Давление", "type": "Reading", "subtype": "Bmp280p", "id": "Press3", @@ -216,10 +229,10 @@ "int": 15, "addr": "0x77", "round": 1, - "num": 16 + "num": 17 }, { - "name": "17. DHT11 Температура", + "name": "18. DHT11 Температура", "type": "Reading", "subtype": "Dht1122t", "id": "tmp3", @@ -229,10 +242,10 @@ "int": 15, "pin": 0, "senstype": "dht11", - "num": 17 + "num": 18 }, { - "name": "18. DHT11 Влажность", + "name": "19. DHT11 Влажность", "type": "Reading", "subtype": "Dht1122h", "id": "Hum3", @@ -242,10 +255,10 @@ "int": 15, "pin": 0, "senstype": "dht11", - "num": 18 + "num": 19 }, { - "name": "19. DS18B20 Температура", + "name": "20. DS18B20 Температура", "type": "Reading", "subtype": "Ds18b20", "id": "dstmp", @@ -257,10 +270,10 @@ "index": 0, "addr": "", "round": 1, - "num": 19 + "num": 20 }, { - "name": "20. GY21 Температура", + "name": "21. GY21 Температура", "type": "Reading", "subtype": "GY21t", "id": "tmp4", @@ -269,10 +282,10 @@ "descr": "Температура", "round": 1, "int": 15, - "num": 20 + "num": 21 }, { - "name": "21. GY21 Влажность", + "name": "22. GY21 Влажность", "type": "Reading", "subtype": "GY21h", "id": "Hum4", @@ -281,10 +294,10 @@ "descr": "Влажность", "round": 1, "int": 15, - "num": 21 + "num": 22 }, { - "name": "22. HDC1080 Температура", + "name": "23. HDC1080 Температура", "type": "Reading", "subtype": "Hdc1080t", "id": "Temp1080", @@ -294,10 +307,10 @@ "int": 15, "addr": "0x40", "round": 1, - "num": 22 + "num": 23 }, { - "name": "23. HDC1080 Влажность", + "name": "24. HDC1080 Влажность", "type": "Reading", "subtype": "Hdc1080h", "id": "Hum1080", @@ -307,10 +320,10 @@ "int": 15, "addr": "0x40", "round": 1, - "num": 23 + "num": 24 }, { - "name": "24. MAX6675 Температура", + "name": "25. MAX6675 Температура", "type": "Reading", "subtype": "Max6675t", "id": "maxtmp", @@ -321,10 +334,10 @@ "DO": 12, "CS": 13, "CLK": 14, - "num": 24 + "num": 25 }, { - "name": "25. PZEM 004t Напряжение", + "name": "26. PZEM 004t Напряжение", "type": "Reading", "subtype": "Pzem004v", "id": "v", @@ -333,10 +346,10 @@ "descr": "Напряжение", "int": 15, "addr": "0xF8", - "num": 25 + "num": 26 }, { - "name": "26. PZEM 004t Сила тока", + "name": "27. PZEM 004t Сила тока", "type": "Reading", "subtype": "Pzem004a", "id": "a", @@ -345,10 +358,10 @@ "descr": "Сила тока", "int": 15, "addr": "0xF8", - "num": 26 + "num": 27 }, { - "name": "27. PZEM 004t Мощность", + "name": "28. PZEM 004t Мощность", "type": "Reading", "subtype": "Pzem004w", "id": "w", @@ -357,10 +370,10 @@ "descr": "Мощность", "int": 15, "addr": "0xF8", - "num": 27 + "num": 28 }, { - "name": "28. PZEM 004t Энергия", + "name": "29. PZEM 004t Энергия", "type": "Reading", "subtype": "Pzem004wh", "id": "wh", @@ -369,10 +382,10 @@ "descr": "Энергия", "int": 15, "addr": "0xF8", - "num": 28 + "num": 29 }, { - "name": "29. PZEM 004t Частота", + "name": "30. PZEM 004t Частота", "type": "Reading", "subtype": "Pzem004hz", "id": "hz", @@ -381,11 +394,11 @@ "descr": "Частота", "int": 15, "addr": "0xF8", - "num": 29 + "num": 30 }, { - "name": "30. Сканер кнопок 433 MHz", - "num": 30, + "name": "31. Сканер кнопок 433 MHz", + "num": 31, "type": "Reading", "subtype": "RCswitch", "id": "rsw", @@ -394,7 +407,7 @@ "pinTx": 12 }, { - "name": "31. Sht20 Температура", + "name": "32. Sht20 Температура", "type": "Reading", "subtype": "Sht20t", "id": "tmp2", @@ -403,10 +416,10 @@ "descr": "Температура", "int": 15, "round": 1, - "num": 31 + "num": 32 }, { - "name": "32. Sht20 Влажность", + "name": "33. Sht20 Влажность", "type": "Reading", "subtype": "Sht20h", "id": "Hum2", @@ -415,10 +428,10 @@ "descr": "Влажность", "int": 15, "round": 1, - "num": 32 + "num": 33 }, { - "name": "33. Sht30 Температура", + "name": "34. Sht30 Температура", "type": "Reading", "subtype": "Sht30t", "id": "tmp30", @@ -427,10 +440,10 @@ "descr": "SHT30 Температура", "int": 15, "round": 1, - "num": 33 + "num": 34 }, { - "name": "34. Sht30 Влажность", + "name": "35. Sht30 Влажность", "type": "Reading", "subtype": "Sht30h", "id": "Hum30", @@ -439,11 +452,11 @@ "descr": "SHT30 Влажность", "int": 15, "round": 1, - "num": 34 + "num": 35 }, { - "name": "35. HC-SR04 Ультразвуковой дальномер", - "num": 35, + "name": "36. HC-SR04 Ультразвуковой дальномер", + "num": 36, "type": "Reading", "subtype": "Sonar", "id": "sonar", @@ -455,7 +468,7 @@ "int": 5 }, { - "name": "36. UART", + "name": "37. UART", "type": "Reading", "subtype": "UART", "page": "", @@ -465,13 +478,13 @@ "tx": 12, "rx": 13, "speed": 9600, - "num": 36 + "num": 37 }, { "header": "Исполнительные устройства" }, { - "name": "37. Кнопка подключенная к пину", + "name": "38. Кнопка подключенная к пину", "type": "Writing", "subtype": "ButtonIn", "id": "btn", @@ -484,10 +497,10 @@ "pinMode": "INPUT", "debounceDelay": 50, "fixState": 0, - "num": 37 + "num": 38 }, { - "name": "38. Управление пином", + "name": "39. Управление пином", "type": "Writing", "subtype": "ButtonOut", "id": "btn", @@ -497,10 +510,10 @@ "int": 0, "inv": 0, "pin": 2, - "num": 38 + "num": 39 }, { - "name": "39. Сервопривод", + "name": "40. Сервопривод", "type": "Writing", "subtype": "IoTServo", "id": "servo", @@ -511,10 +524,10 @@ "pin": 12, "apin": -1, "amap": "0, 4096, 0, 180", - "num": 39 + "num": 40 }, { - "name": "40. Расширитель портов Mcp23017", + "name": "41. Расширитель портов Mcp23017", "type": "Reading", "subtype": "Mcp23017", "id": "Mcp", @@ -524,10 +537,10 @@ "int": "0", "addr": "0x20", "index": 1, - "num": 40 + "num": 41 }, { - "name": "41. MP3 плеер", + "name": "42. MP3 плеер", "type": "Reading", "subtype": "Mp3", "id": "mp3", @@ -537,10 +550,10 @@ "int": 1, "pins": "14,12", "volume": 20, - "num": 41 + "num": 42 }, { - "name": "42. PWM ESP8266", + "name": "43. PWM ESP8266", "type": "Writing", "subtype": "Pwm8266", "id": "pwm", @@ -552,10 +565,10 @@ "freq": 5000, "val": 0, "apin": -1, - "num": 42 + "num": 43 }, { - "name": "43. Телеграм-Лайт", + "name": "44. Телеграм-Лайт", "type": "Writing", "subtype": "TelegramLT", "id": "tg", @@ -564,13 +577,13 @@ "descr": "", "token": "", "chatID": "", - "num": 43 + "num": 44 }, { "header": "Экраны" }, { - "name": "44. LCD экран 2004", + "name": "45. LCD экран 2004", "type": "Reading", "subtype": "Lcd2004", "id": "Lcd", @@ -582,10 +595,10 @@ "size": "20,4", "coord": "0,0", "id2show": "id датчика", - "num": 44 + "num": 45 }, { - "name": "45. LCD экран 1602", + "name": "46. LCD экран 1602", "type": "Reading", "subtype": "Lcd2004", "id": "Lcd", @@ -597,6 +610,6 @@ "size": "16,2", "coord": "0,0", "id2show": "id датчика", - "num": 45 + "num": 46 } ] \ No newline at end of file diff --git a/data_svelte/widgets.json b/data_svelte/widgets.json index b4cf75cd..cab0dbe2 100644 --- a/data_svelte/widgets.json +++ b/data_svelte/widgets.json @@ -47,7 +47,7 @@ "name": "anydataWth", "label": "Энергия", "widget": "anydata", - "after": "Wt/Hr", + "after": "kWt/Hr", "icon": "speedometer" }, { @@ -103,34 +103,27 @@ }, { "name": "chart1", - "label": "График1", + "label": "График без точек", "widget": "chart", "dateFormat": "HH:mm", - "maxCount": 255, + "maxCount": 86400, "pointRadius": 0 }, { "name": "chart2", - "label": "График2", + "label": "График с точками", "widget": "chart", - "maxCount": 255, + "maxCount": 86400, "dateFormat": "HH:mm" }, { "name": "chart3", - "label": "График3", + "label": "График Дневной", "widget": "chart", "dateFormat": "DD.MM.YYYY", - "maxCount": 255, + "maxCount": 86400, "type": "bar" }, - { - "name": "chart4", - "label": "График4", - "widget": "chart", - "maxCount": 255, - "dateFormat": "DD.MM.YYYY" - }, { "name": "fillgauge", "label": "Бочка", diff --git a/include/Const.h b/include/Const.h index a164f11a..6e328d7d 100644 --- a/include/Const.h +++ b/include/Const.h @@ -1,7 +1,7 @@ #pragma once //Версия прошивки -#define FIRMWARE_VERSION 426 +#define FIRMWARE_VERSION 427 #ifdef esp8266_4mb #define FIRMWARE_NAME "esp8266_4mb" diff --git a/myProfile.json b/myProfile.json index 80009947..5a5f56cd 100644 --- a/myProfile.json +++ b/myProfile.json @@ -28,7 +28,11 @@ "modules": { "Виртуальные элементы": [ { - "path": "src\\modules\\virtual\\Logging", + "path": "src\\modules\\virtual\\Loging", + "active": true + }, + { + "path": "src\\modules\\virtual\\LogingDaily", "active": true }, { diff --git a/platformio.ini b/platformio.ini index 44b4403e..49db09ca 100644 --- a/platformio.ini +++ b/platformio.ini @@ -71,7 +71,8 @@ lib_deps = dfrobot/DFRobotDFPlayerMini @ ^1.0.5 marcoschwartz/LiquidCrystal_I2C@^1.1.4 build_src_filter = - + + + + + + + + diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index 52902620..8d9bfa88 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -134,9 +134,10 @@ void mqttCallback(char* topic, uint8_t* payload, size_t length) { publishWidgets(); publishState(); + //обращение к логированию из ядра //отправка данных графиков for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->getSubtype() == "Loging") { + if ((*it)->getSubtype() == "Loging" || "LogingDaily") { (*it)->setPublishDestination(TO_MQTT); (*it)->publishValue(); } diff --git a/src/WsServer.cpp b/src/WsServer.cpp index 256f0a8b..80f09870 100644 --- a/src/WsServer.cpp +++ b/src/WsServer.cpp @@ -73,13 +73,14 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) //отвечаем на запрос графиков 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") { + if ((*it)->getSubtype() == "Loging" || "LogingDaily") { (*it)->setPublishDestination(TO_WS, num); (*it)->publishValue(); } diff --git a/src/modules/API.cpp b/src/modules/API.cpp index 98f4489d..467f8588 100644 --- a/src/modules/API.cpp +++ b/src/modules/API.cpp @@ -1,6 +1,7 @@ #include "ESPConfiguration.h" void* getAPI_Loging(String subtype, String params); +void* getAPI_LogingDaily(String subtype, String params); void* getAPI_Timer(String subtype, String params); void* getAPI_Variable(String subtype, String params); void* getAPI_VButton(String subtype, String params); @@ -32,6 +33,7 @@ void* getAPI_Lcd2004(String subtype, String params); void* getAPI(String subtype, String params) { void* tmpAPI; if ((tmpAPI = getAPI_Loging(subtype, params)) != nullptr) return tmpAPI; +if ((tmpAPI = getAPI_LogingDaily(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_VButton(subtype, params)) != nullptr) return tmpAPI; diff --git a/src/modules/virtual/Logging/Loging.cpp b/src/modules/virtual/Loging/Loging.cpp similarity index 100% rename from src/modules/virtual/Logging/Loging.cpp rename to src/modules/virtual/Loging/Loging.cpp diff --git a/src/modules/virtual/Logging/modinfo.json b/src/modules/virtual/Loging/modinfo.json similarity index 79% rename from src/modules/virtual/Logging/modinfo.json rename to src/modules/virtual/Loging/modinfo.json index 42f2e768..354fb517 100644 --- a/src/modules/virtual/Logging/modinfo.json +++ b/src/modules/virtual/Loging/modinfo.json @@ -2,7 +2,7 @@ "menuSection": "Виртуальные элементы", "configItem": [ { - "name": "Логирование в график", + "name": "График", "type": "Writing", "subtype": "Loging", "id": "log", @@ -24,7 +24,7 @@ "moduleVersion": "3.0", "usedRam": 15, "title": "Логирование в график", - "moduleDesc": "Расширение позволяющее логировать любую величину в график. Графики доступны в мобильном приложении и в веб интерфейсе. Данные графиков хранятся в встроенной памяти esp. В окне ввода даты нужно выбрать день, историю которого вы хотите посмотреть. Старые файлы будут удаляться автоматически после того как объем оставшейся flesh памяти устройства будет менее 20 процентов", + "moduleDesc": "Расширение позволяющее логировать любую величину в график. Графики доступны в мобильном приложении и в веб интерфейсе. Данные графиков хранятся в встроенной памяти esp. В окне ввода даты можно выбирать день, историю которого вы хотите посмотреть. Старые файлы будут удаляться автоматически после того как объем оставшейся flesh памяти устройства будет менее 20 процентов", "propInfo": { "int": "Интервал логирования в мнутах, рекомендуется для esp8266 использоать интервал не менее 5-ти минут", "logid": "ID величины которую будем логировать", diff --git a/src/modules/virtual/LogingDaily/LogingDaily.cpp b/src/modules/virtual/LogingDaily/LogingDaily.cpp new file mode 100644 index 00000000..62e82e0d --- /dev/null +++ b/src/modules/virtual/LogingDaily/LogingDaily.cpp @@ -0,0 +1,282 @@ +#include "Global.h" +#include "classes/IoTItem.h" +#include "ESPConfiguration.h" +#include "NTP.h" + +class LogingDaily : public IoTItem { + private: + String logid; + String id; + String filesList = ""; + + int _publishType = -2; + int _wsNum = -1; + + int points; + + IoTItem *dateIoTItem; + + String prevDate = ""; + bool firstTimeDate = true; + + unsigned long interval; + + public: + LogingDaily(String parameters) : IoTItem(parameters) { + jsonRead(parameters, F("logid"), logid); + jsonRead(parameters, F("id"), id); + jsonRead(parameters, F("points"), points); + + if (points > 365) { + points = 365; + SerialPrint("E", F("LogingDaily"), "'" + id + "' user set more points than allowed, value reset to 365"); + } + jsonRead(parameters, F("int"), interval); + interval = interval * 1000 * 60; //приводим к милисекундам + } + + void doByInterval() { + if (hasDayChanged()) { + execute(); + } + } + + void execute() { + //если объект логгирования не был создан + if (!isItemExist(logid)) { + SerialPrint("E", F("LogingDaily"), "'" + id + "' LogingDaily object not exist, return"); + return; + } + + String value = getItemValue(logid); + + //если значение логгирования пустое + if (value == "") { + SerialPrint("E", F("LogingDaily"), "'" + id + "' LogingDaily value is empty, return"); + return; + } + + //если время не было получено из интернета + if (!isTimeSynch) { + SerialPrint("E", F("LogingDaily"), "'" + id + "' Сant LogingDaily - time not synchronized, return"); + return; + } + + String logData; + + float currentValue = value.toFloat(); + //прочитаем предудущее значение + float prevValue = readDataDB(id + "-v").toFloat(); + //сохраним в базу данных текущее значение, понадобится в следующие сутки + saveDataDB(id + "-v", value); + + float difference = currentValue - prevValue; + + jsonWriteInt(logData, "x", unixTime); + jsonWriteFloat(logData, "y1", difference); + + //прочитаем путь к файлу последнего сохранения + String filePath = readDataDB(id); + + //если данные о файле отсутствуют, создадим новый + if (filePath == "failed" || filePath == "") { + SerialPrint("E", F("LogingDaily"), "'" + id + "' file path not found, start create new file"); + createNewFileWithData(logData); + return; + } + + //считаем количество строк и определяем размер файла + size_t size = 0; + int lines = countJsonObj(filePath, size); + SerialPrint("i", F("LogingDaily"), "'" + id + "' " + "lines = " + String(lines) + ", size = " + String(size)); + + //если количество строк до заданной величины и дата не менялась + if (lines <= points && !hasDayChanged()) { + //просто добавим в существующий файл новые данные + addNewDataToExistingFile(filePath, logData); + //если больше или поменялась дата то создадим следующий файл + } else { + createNewFileWithData(logData); + } + } + + void createNewFileWithData(String &logData) { + logData = logData + ","; + + String path = "/lgd/" + id + "/" + id + ".txt"; //создадим путь вида /lgd/id/id.txt + //создадим пустой файл + if (writeEmptyFile(path) != "sucсess") { + SerialPrint("E", F("LogingDaily"), "'" + id + "' file writing error, return"); + return; + } + + //запишем в него данные + if (addFile(path, logData) != "sucсess") { + SerialPrint("E", F("LogingDaily"), "'" + id + "' data writing error, return"); + return; + } + //запишем путь к нему в базу данных + if (saveDataDB(id, path) != "sucсess") { + SerialPrint("E", F("LogingDaily"), "'" + id + "' db file writing error, return"); + return; + } + SerialPrint("i", F("LogingDaily"), "'" + id + "' file created http://" + WiFi.localIP().toString() + path); + } + + void addNewDataToExistingFile(String &path, String &logData) { + logData = logData + ","; + if (addFile(path, logData) != "sucсess") { + SerialPrint("i", F("LogingDaily"), "'" + id + "' file writing error, return"); + return; + }; + SerialPrint("i", F("LogingDaily"), "'" + id + "' LogingDaily in file http://" + WiFi.localIP().toString() + path); + } + + bool hasDayChanged() { + bool changed = false; + String currentDate = getTodayDateDotFormated(); + if (!firstTimeDate) { + if (prevDate != currentDate) { + changed = true; + SerialPrint("i", F("NTP"), "Change day event"); +#if defined(ESP8266) + FileFS.gc(); +#endif +#if defined(ESP32) +#endif + } + } + firstTimeDate = false; + prevDate = currentDate; + return changed; + } + + void publishValue() { + String dir = "/lgd/" + id; + filesList = getFilesList(dir); + + SerialPrint("i", F("LogingDaily"), "file list: " + filesList); + + int f = 0; + + while (filesList.length()) { + String path = selectToMarker(filesList, ";"); + + path = "/lgd/" + id + path; + + f++; + + if (_publishType == TO_MQTT) { + publishChartFileToMqtt(path); + } else if (_publishType == TO_WS) { + publishChartToWs(path, _wsNum, 1000); + } else if (_publishType == TO_MQTT_WS) { + publishChartFileToMqtt(path); + publishChartToWs(path, _wsNum, 1000); + } + SerialPrint("i", F("LogingDaily"), String(f) + ") " + path + ", sent"); + + filesList = deleteBeforeDelimiter(filesList, ";"); + } + } + + void clearHistory() { + String dir = "/lgd/" + id; + cleanDirectory(dir); + } + + bool publishChartFileToMqtt(String path) { + File configFile = FileFS.open(path, FILE_READ); + if (!configFile) { + SerialPrint("E", F("LogingDaily"), path + " file reading error, json not created, return"); + return false; + } + String oneSingleJson = configFile.readString(); + configFile.close(); + String topic = mqttRootDevice + "/" + id; + oneSingleJson = "{\"maxCount\":" + String(calculateMaxCount()) + ",\"topic\":\"" + topic + "\",\"status\":[" + oneSingleJson + "]}"; + oneSingleJson.replace("},]}", "}]}"); + SerialPrint("i", "LogingDaily", "json size: " + String(oneSingleJson.length())); + publishChartMqtt(id, oneSingleJson); + return true; + } + + //особая функция отправки графиков в веб + void publishChartToWs(String filename, int num, size_t frameSize) { + String json; + jsonWriteStr(json, "topic", mqttRootDevice + "/" + id); + jsonWriteInt(json, "maxCount", calculateMaxCount()); + + String st = "/st/chart.json|"; + if (num == -1) { + standWebSocket.broadcastTXT(st); + } else { + standWebSocket.sendTXT(num, st); + } + String path = filepath(filename); + auto file = FileFS.open(path, "r"); + if (!file) { + SerialPrint(F("E"), F("FS"), F("reed file error")); + return; + } + size_t fileSize = file.size(); + SerialPrint(F("i"), F("FS"), "Send file '" + String(filename) + "', file size: " + String(fileSize)); + uint8_t payload[frameSize]; + int countRead = file.read(payload, sizeof(payload)); + while (countRead > 0) { + if (num == -1) { + standWebSocket.broadcastBIN(payload, countRead); + } else { + standWebSocket.sendBIN(num, payload, countRead); + } + countRead = file.read(payload, sizeof(payload)); + } + file.close(); + String end = "/end/chart.json|" + json; + if (num == -1) { + standWebSocket.broadcastTXT(end); + } else { + standWebSocket.sendTXT(num, end); + } + } + + void publishChartToWsSinglePoint(String value) { + String topic = mqttRootDevice + "/" + id; + String json = "{\"maxCount\":" + String(calculateMaxCount()) + ",\"topic\":\"" + topic + "\",\"status\":[{\"x\":" + String(unixTime) + ",\"y1\":" + value + "}]}"; + String pk = "/string/chart.json|" + json; + standWebSocket.broadcastTXT(pk); + } + + void setPublishDestination(int publishType, int wsNum = -1) { + _publishType = publishType; + _wsNum = wsNum; + } + + String getValue() { + return ""; + } + + void loop() { + if (enableDoByInt) { + currentMillis = millis(); + difference = currentMillis - prevMillis; + if (difference >= interval) { + prevMillis = millis(); + this->doByInterval(); + } + } + } + + //просто максимальное количество точек + int calculateMaxCount() { + return 86400; + } +}; + +void *getAPI_LogingDaily(String subtype, String param) { + if (subtype == F("LogingDaily")) { + return new LogingDaily(param); + } else { + return nullptr; + } +} diff --git a/src/modules/virtual/LogingDaily/modinfo.json b/src/modules/virtual/LogingDaily/modinfo.json new file mode 100644 index 00000000..ed6fe3c3 --- /dev/null +++ b/src/modules/virtual/LogingDaily/modinfo.json @@ -0,0 +1,39 @@ +{ + "menuSection": "Виртуальные элементы", + "configItem": [ + { + "name": "График дневного расхода", + "type": "Writing", + "subtype": "LogingDaily", + "id": "log", + "widget": "chart3", + "page": "Графики", + "descr": "Температура", + "num": 1, + "int": 1, + "logid": "t", + "points": 365 + } + ], + "about": { + "authorName": "Dmitry Borisenko", + "authorContact": "https://t.me/Dmitry_Borisenko", + "authorGit": "https://github.com/DmitryBorisenko33", + "specialThanks": "@itsid1 @Valiuhaaa Serg", + "moduleName": "LogingDaily", + "moduleVersion": "3.0", + "usedRam": 15, + "title": "График дневного расхода", + "moduleDesc": "Расширение позволяющее логировать накопительные величины и видеть их дневное изменение. Графики доступны в мобильном приложении и в веб интерфейсе. Данные графиков хранятся в встроенной памяти esp", + "propInfo": { + "int": "Интервал логирования в мнутах, частота проверки смены суток в минутах. Не рекомендуется менять", + "logid": "ID накопительной величины которую будем логировать", + "points": "Максимальное количество точек" + } + }, + "defActive": true, + "devices": { + "esp32_4mb": [], + "esp8266_4mb": [] + } +} \ No newline at end of file diff --git a/src/utils/FileUtils.cpp b/src/utils/FileUtils.cpp index f9698874..f7f33332 100644 --- a/src/utils/FileUtils.cpp +++ b/src/utils/FileUtils.cpp @@ -214,9 +214,10 @@ String readDataDB(String id) { void cleanLogs() { SerialPrint("i", "Files", "cleanLogs"); cleanDirectory("/db"); + //обращение к логированию из ядра //очистка данных всех экземпляров графиков for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->getSubtype() == "Loging") { + if ((*it)->getSubtype() == "Loging" || "LogingDaily") { (*it)->clearHistory(); } }