diff --git a/data_svelte/build/bundle.css.gz b/data_svelte/build/bundle.css.gz index c7525827..54bc75e4 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 4baeb77d..271fc795 100644 Binary files a/data_svelte/build/bundle.js.gz and b/data_svelte/build/bundle.js.gz differ diff --git a/data_svelte/index.html b/data_svelte/index.html index 3366770d..b4164705 100644 --- a/data_svelte/index.html +++ b/data_svelte/index.html @@ -4,12 +4,12 @@ - IoT Manager 4.3.9 + IoT Manager 4.4.0 - + - + diff --git a/data_svelte/items.json b/data_svelte/items.json index dfc47a9c..9ac762bd 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -30,7 +30,8 @@ "num": 2, "int": 1, "logid": "t", - "points": 365 + "points": 365, + "test": 0 }, { "name": "3. Таймер", diff --git a/include/Const.h b/include/Const.h index ff961eba..bb82f3e8 100644 --- a/include/Const.h +++ b/include/Const.h @@ -1,7 +1,7 @@ #pragma once //Версия прошивки -#define FIRMWARE_VERSION 429 +#define FIRMWARE_VERSION 430 #ifdef esp8266_4mb #define FIRMWARE_NAME "esp8266_4mb" diff --git a/include/MqttClient.h b/include/MqttClient.h index 707fd4f0..02dce50e 100644 --- a/include/MqttClient.h +++ b/include/MqttClient.h @@ -24,6 +24,7 @@ boolean publishStatusMqtt(const String& topic, const String& data); boolean publishEvent(const String& topic, const String& data); boolean publishInfo(const String& topic, const String& data); boolean publishAnyJsonKey(const String& topic, const String& key, const String& data); +bool publishChartFileToMqtt(String path, String id, int maxCount); void publishWidgets(); void publishState(); diff --git a/include/UpgradeFirm.h b/include/UpgradeFirm.h index 25dd2140..0e669984 100644 --- a/include/UpgradeFirm.h +++ b/include/UpgradeFirm.h @@ -12,6 +12,7 @@ struct updateFirm { String configJson; String layoutJson; String scenarioTxt; + String chartsData; }; extern void upgradeInit(); diff --git a/include/WsServer.h b/include/WsServer.h index d09f671b..cc4116ef 100644 --- a/include/WsServer.h +++ b/include/WsServer.h @@ -18,6 +18,7 @@ void publishStatusWs(const String& topic, const String& data); void publishChartWs(int num, String& path); void periodicWsSend(); void sendStringToWs(const String& msg, uint8_t num, String name); +void publishChartToWs(String filename, int num, size_t frameSize, int maxCount, String id); // void sendMark(const char* filename, const char* mark, uint8_t num); // void sendFileToWs3(const String& filename, uint8_t num); diff --git a/include/utils/FileUtils.h b/include/utils/FileUtils.h index 24c203af..335e4e2c 100644 --- a/include/utils/FileUtils.h +++ b/include/utils/FileUtils.h @@ -24,6 +24,8 @@ extern void onFlashWrite(); String getFilesList8266(String& directory); String getFilesList32(String& directory); String getFilesList(String& directory); +String createDataBaseSting(); +void writeDataBaseSting(String input); struct IoTFSInfo { size_t totalBytes; diff --git a/src/Main.cpp b/src/Main.cpp index 6a24c9a1..8d4dede3 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -80,28 +80,6 @@ void setup() { // test Serial.println("-------test start--------"); - - // File dir = FileFS.open("/", "r"); - // String out; - // printDirectory(dir, out); - // Serial.println(out); - - //=======проверка очереди из структур================= - - // myDB = new IoTDB; - // QueueItems myItem; - // myItem.myword = "word1"; - // myDB->push(myItem); - // myItem.myword = "word2"; - // myDB->push(myItem); - // myItem.myword = "word3"; - // myDB->push(myItem); - // Serial.println(myDB->front().myword); - // Serial.println(myDB->front().myword); - // Serial.println(myDB->front().myword); - - // Serial.println(FileList("lg")); - Serial.println("--------test end---------"); // симуляция добавления внешних событий @@ -191,3 +169,24 @@ void loop() { // } //} } + +// File dir = FileFS.open("/", "r"); +// String out; +// printDirectory(dir, out); +// Serial.println(out); + +//=======проверка очереди из структур================= + +// myDB = new IoTDB; +// QueueItems myItem; +// myItem.myword = "word1"; +// myDB->push(myItem); +// myItem.myword = "word2"; +// myDB->push(myItem); +// myItem.myword = "word3"; +// myDB->push(myItem); +// Serial.println(myDB->front().myword); +// Serial.println(myDB->front().myword); +// Serial.println(myDB->front().myword); + +// Serial.println(FileList("lg")); diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index 8d9bfa88..89a2ba7e 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -305,6 +305,22 @@ void publishState() { } } +bool publishChartFileToMqtt(String path, String id, int maxCount) { + File configFile = FileFS.open(path, FILE_READ); + if (!configFile) { + SerialPrint("E", F("Loging"), path + " file reading error, json not created, return"); + return false; + } + String oneSingleJson = configFile.readString(); + configFile.close(); + String topic = mqttRootDevice + "/" + id; + oneSingleJson = "{\"maxCount\":" + String(maxCount) + ",\"topic\":\"" + topic + "\",\"status\":[" + oneSingleJson + "]}"; + oneSingleJson.replace("},]}", "}]}"); + SerialPrint("i", "Loging", "json size: " + String(oneSingleJson.length())); + publishChartMqtt(id, oneSingleJson); + return true; +} + void handleMqttStatus(bool send) { String stateStr = getStateStr(mqtt.state()); // Serial.println(stateStr); diff --git a/src/UpgradeFirm.cpp b/src/UpgradeFirm.cpp index 62ffc482..ec953ba7 100644 --- a/src/UpgradeFirm.cpp +++ b/src/UpgradeFirm.cpp @@ -119,6 +119,7 @@ void putUserDataToRam() { update.settingsFlashJson = readFile("settings.json", 4096); update.layoutJson = readFile("layout.json", 4096); update.scenarioTxt = readFile("scenario.txt", 4096); + update.chartsData = createDataBaseSting(); } void saveUserDataToFlash() { @@ -126,6 +127,7 @@ void saveUserDataToFlash() { writeFile("/settings.json", update.settingsFlashJson); writeFile("/layout.json", update.layoutJson); writeFile("/scenario.txt", update.scenarioTxt); + writeDataBaseSting(update.chartsData); } void handleUpdateStatus(bool send, int state) { diff --git a/src/WsServer.cpp b/src/WsServer.cpp index 7eafc283..79611e91 100644 --- a/src/WsServer.cpp +++ b/src/WsServer.cpp @@ -101,6 +101,10 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) standWebSocket.sendTXT(num, settingsFlashJson); } + //отправляем все графики в веб для экспорта + if (headerStr == "/expcharts|") { + } + //обработка кнопки сохранить if (headerStr == "/gifnoc|") { writeFileUint8tByFrames("config.json", payload, length, headerLenth, 256); @@ -353,6 +357,45 @@ void sendStringToWs(const String& msg, uint8_t num, String name) { standWebSocket.sendTXT(num, end); } +//особая функция отправки графиков в веб +void publishChartToWs(String filename, int num, size_t frameSize, int maxCount, String id) { + String json; + jsonWriteStr(json, "topic", mqttRootDevice + "/" + id); + jsonWriteInt(json, "maxCount", maxCount); + + String st = "/st/chart.json|" + 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 sendMark(const char* filename, const char* mark, uint8_t num) { // char outChar[strlen(filename) + strlen(mark) + 1]; // strcpy(outChar, mark); diff --git a/src/modules/virtual/Loging/Loging.cpp b/src/modules/virtual/Loging/Loging.cpp index ae048d25..d7649e1f 100644 --- a/src/modules/virtual/Loging/Loging.cpp +++ b/src/modules/virtual/Loging/Loging.cpp @@ -177,12 +177,12 @@ class Loging : public IoTItem { if (fileUnixTimeLocal > reqUnixTime && fileUnixTimeLocal < reqUnixTime + 86400) { noData = false; if (_publishType == TO_MQTT) { - publishChartFileToMqtt(path); + publishChartFileToMqtt(path, id, calculateMaxCount()); } else if (_publishType == TO_WS) { - publishChartToWs(path, _wsNum, 1000); + publishChartToWs(path, _wsNum, 1000, calculateMaxCount(), id); } else if (_publishType == TO_MQTT_WS) { - publishChartFileToMqtt(path); - publishChartToWs(path, _wsNum, 1000); + publishChartFileToMqtt(path, id, calculateMaxCount()); + publishChartToWs(path, _wsNum, 1000, calculateMaxCount(), id); } SerialPrint("i", F("Loging"), String(f) + ") " + path + ", " + getDateTimeDotFormatedFromUnix(fileUnixTimeLocal) + ", sent"); } else { @@ -224,61 +224,6 @@ class Loging : public IoTItem { } } - bool publishChartFileToMqtt(String path) { - File configFile = FileFS.open(path, FILE_READ); - if (!configFile) { - SerialPrint("E", F("Loging"), 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", "Loging", "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 clearValue() { String topic = mqttRootDevice + "/" + id; String json = "{\"maxCount\":0,\"topic\":\"" + topic + "\",\"status\":[]}"; diff --git a/src/modules/virtual/LogingDaily/LogingDaily.cpp b/src/modules/virtual/LogingDaily/LogingDaily.cpp index 62e82e0d..fa4d5f59 100644 --- a/src/modules/virtual/LogingDaily/LogingDaily.cpp +++ b/src/modules/virtual/LogingDaily/LogingDaily.cpp @@ -14,6 +14,8 @@ class LogingDaily : public IoTItem { int points; + int testMode; + IoTItem *dateIoTItem; String prevDate = ""; @@ -26,6 +28,7 @@ class LogingDaily : public IoTItem { jsonRead(parameters, F("logid"), logid); jsonRead(parameters, F("id"), id); jsonRead(parameters, F("points"), points); + jsonRead(parameters, F("test"), testMode); if (points > 365) { points = 365; @@ -36,7 +39,7 @@ class LogingDaily : public IoTItem { } void doByInterval() { - if (hasDayChanged()) { + if (hasDayChanged() || testMode == 1) { execute(); } } @@ -72,7 +75,7 @@ class LogingDaily : public IoTItem { float difference = currentValue - prevValue; - jsonWriteInt(logData, "x", unixTime); + jsonWriteInt(logData, "x", unixTime - 120); jsonWriteFloat(logData, "y1", difference); //прочитаем путь к файлу последнего сохранения @@ -167,12 +170,12 @@ class LogingDaily : public IoTItem { f++; if (_publishType == TO_MQTT) { - publishChartFileToMqtt(path); + publishChartFileToMqtt(path, id, calculateMaxCount()); } else if (_publishType == TO_WS) { - publishChartToWs(path, _wsNum, 1000); + publishChartToWs(path, _wsNum, 1000, calculateMaxCount(), id); } else if (_publishType == TO_MQTT_WS) { - publishChartFileToMqtt(path); - publishChartToWs(path, _wsNum, 1000); + publishChartFileToMqtt(path, id, calculateMaxCount()); + publishChartToWs(path, _wsNum, 1000, calculateMaxCount(), id); } SerialPrint("i", F("LogingDaily"), String(f) + ") " + path + ", sent"); @@ -185,61 +188,6 @@ class LogingDaily : public IoTItem { 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 + "}]}"; diff --git a/src/modules/virtual/LogingDaily/modinfo.json b/src/modules/virtual/LogingDaily/modinfo.json index ed6fe3c3..f335c474 100644 --- a/src/modules/virtual/LogingDaily/modinfo.json +++ b/src/modules/virtual/LogingDaily/modinfo.json @@ -12,7 +12,8 @@ "num": 1, "int": 1, "logid": "t", - "points": 365 + "points": 365, + "test": 0 } ], "about": { @@ -28,7 +29,8 @@ "propInfo": { "int": "Интервал логирования в мнутах, частота проверки смены суток в минутах. Не рекомендуется менять", "logid": "ID накопительной величины которую будем логировать", - "points": "Максимальное количество точек" + "points": "Максимальное количество точек", + "test": "Режим тестирования - график будет обновляться не раз в сутки, а кадый заданный в int интервал" } }, "defActive": true, diff --git a/src/utils/FileUtils.cpp b/src/utils/FileUtils.cpp index 7602abc0..f6c128db 100644 --- a/src/utils/FileUtils.cpp +++ b/src/utils/FileUtils.cpp @@ -323,3 +323,30 @@ IoTFSInfo getFSInfo() { return myFSInfo; } #endif + +String createDataBaseSting() { + String out; + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + if ((*it)->getSubtype() == "LogingDaily") { + String id = (*it)->getID(); + id = "/lgd/" + id + "/" + id + ".txt"; + String fileContent = readFile(id, 10000); + if (fileContent == "failed") { + SerialPrint("i", "Export", "file not exist " + id); + } else { + out += "=>" + fileContent + "\r\n"; + } + } + } + return out; +} + +void writeDataBaseSting(String input) { + while (input.length()) { + String line = selectToMarker(input, "\r\n"); + String path = selectToMarker(line, "=>"); + String content = deleteBeforeDelimiter(line, "=>"); + writeFile(path, content); + input = deleteBeforeDelimiter(input, "\r\n"); + } +}