diff --git a/.vscode/settings.json b/.vscode/settings.json index 63657b48..b1ad7d05 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,48 @@ "files.associations": { "*.tcc": "cpp", "string": "cpp", - "functional": "cpp" - } + "functional": "cpp", + "array": "cpp", + "atomic": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "cpp", + "numeric": "cpp", + "ratio": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "system_error": "cpp", + "cinttypes": "cpp", + "regex": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "typeinfo": "cpp" + }, + "cmake.configureOnOpen": true } \ No newline at end of file diff --git a/data/config.json b/data/config.json index 228b2ecc..8c8b402a 100644 --- a/data/config.json +++ b/data/config.json @@ -3,8 +3,8 @@ "chipID": "", "apssid": "IoTmanager", "appass": "", - "routerssid": "rise", - "routerpass": "hostel3333", + "routerssid": "VOLODYA", + "routerpass": "BELCHENKO", "timezone": 2, "ntp": "pool.ntp.org", "mqttServer": "91.204.228.124", @@ -18,5 +18,6 @@ "webpass": "admin", "udponoff": "1", "blink": "0", - "oneWirePin": "2" + "oneWirePin": "2", + "serverip": "http://206.189.49.244" } \ No newline at end of file diff --git a/data/items/logging.txt b/data/items/logging.txt new file mode 100644 index 00000000..8253774f --- /dev/null +++ b/data/items/logging.txt @@ -0,0 +1 @@ +0;logging;id;chart;Графики;История;order;val[any];int[60];cnt[100] \ No newline at end of file diff --git a/data/js/function.js.gz b/data/js/function.js.gz index 10c9953a..b3e5ea56 100644 Binary files a/data/js/function.js.gz and b/data/js/function.js.gz differ diff --git a/data/set.dev.json b/data/set.dev.json new file mode 100644 index 00000000..fb697b50 --- /dev/null +++ b/data/set.dev.json @@ -0,0 +1,46 @@ +{ + "configs": [ + "/config.setup.json", + "/lang/lang.ru.json" + ], + "title": "Конфигурация", + "class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", + "content": [ + { + "type": "h5", + "title": "{{name}}", + "class": "alert-default" + }, + { + "type": "link", + "title": "{{ButMainPage}}", + "action": "/", + "class": "btn btn-block btn-default" + }, + { + "type": "hr" + }, + { + "type": "h3", + "title": "Адрес сервера обновлений" + }, + { + "type": "input", + "title": "ip address", + "name": "serverip-arg", + "state": "{{serverip}}" + }, + { + "type": "button", + "title": "{{ButSave}}", + "action": "set?serverip=[[serverip-arg]]", + "class": "btn btn-block btn-default" + }, + { + "type": "link", + "title": "Перезагрузить устройство", + "action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/set?device=ok');}", + "class": "btn btn-block btn-danger" + } + ] + } \ No newline at end of file diff --git a/data/set.device.json b/data/set.device.json index 93f7c3fa..1a94ee8d 100644 --- a/data/set.device.json +++ b/data/set.device.json @@ -43,7 +43,7 @@ }, { "type": "h4", - "title": "LittleFS version: 261" + "title": "LittleFS version: 262" }, { "type": "hr" @@ -75,9 +75,11 @@ "/set?addItem=bmp280-temp": "18.Датчик температуры bmp280", "/set?addItem=bmp280-press": "19.Датчик давления bmp280", "/set?addItem=modbus": "20.Прочитать регистр modbus устройства", - "/set?addItem=uptime": "a.Отобразить время работы устройства" + "/set?addItem=logging": "a.Логгирование и вывод в график любой величины", + "/set?addItem=uptime": "b.Отобразить время работы устройства" } }, + { "type": "hr" }, @@ -112,6 +114,10 @@ "action": "/set?delAllItems", "class": "btn btn-block btn-default" }, + { + "type": "text", + "title": "

После любого изменения таблицы элементов, включая удаление/добавление строк, необходимо нажать кнопку СОХРАНИТЬ ТАБЛИЦУ

" + }, { "type": "h2", "title": "Сценарии" @@ -147,7 +153,7 @@ "class": "btn btn-block btn-default" }, { - "type": "link", + "type": "button", "title": "Очистить логи сенсоров", "action": "/set?cleanlog", "class": "btn btn-block btn-default" diff --git a/data/widgets/chart.json b/data/widgets/chart.json index 47c6473b..9ecc61e3 100644 --- a/data/widgets/chart.json +++ b/data/widgets/chart.json @@ -1,5 +1,4 @@ { "widget": "chart", - "series": "Temperature, °C", "dateFormat": "HH:mm" } \ No newline at end of file diff --git a/include/Class/LineParsing.h b/include/Class/LineParsing.h index fa117948..3543b581 100644 --- a/include/Class/LineParsing.h +++ b/include/Class/LineParsing.h @@ -12,7 +12,6 @@ class LineParsing { String _page; String _descr; String _order; - String _addr; String _reg; String _pin; @@ -22,6 +21,9 @@ class LineParsing { String _state; String _db; String _type; + String _int; + String _cnt; + String _val; public: LineParsing() : @@ -39,7 +41,10 @@ class LineParsing { _inv{""}, _state{""}, _db{""}, - _type{""} + _type{""}, + _int{""}, + _cnt{""}, + _val{""} {}; @@ -84,6 +89,15 @@ class LineParsing { if (arg.indexOf("reg[") != -1) { _reg = extractInner(arg); } + if (arg.indexOf("int[") != -1) { + _int = extractInner(arg); + } + if (arg.indexOf("cnt[") != -1) { + _cnt = extractInner(arg); + } + if (arg.indexOf("val[") != -1) { + _val = extractInner(arg); + } } } @@ -94,7 +108,7 @@ class LineParsing { _descr.replace("%ver%", String(FIRMWARE_VERSION)); _descr.replace("%name%", jsonReadStr(configSetupJson, F("name"))); - createWidgetClass(_descr, _page, _order, _file, _key); + createWidget(_descr, _page, _order, _file, _key); } //jsonWriteStr(configOptionJson, _key + "_pin", _pin); @@ -115,10 +129,10 @@ class LineParsing { return _order; } String gpin() { - return _pin; // + return _pin; } String ginv() { - return _inv; // + return _inv; } String gstate() { return _state; @@ -138,6 +152,15 @@ class LineParsing { String gregaddr() { return _reg; } + String gint() { + return _int; + } + String gmaxcnt() { + return _cnt; + } + String gvalue() { + return _val; + } void clear() { _key = ""; @@ -154,6 +177,9 @@ class LineParsing { _state = ""; _db = ""; _type = ""; + _int = ""; + _cnt = ""; + _val = ""; } String extractInnerDigit(String str) { @@ -162,13 +188,15 @@ class LineParsing { return str.substring(p1 + 1, p2); } - void createWidgetClass(String descr, String page, String order, String filename, String topic) { + void createWidget(String descr, String page, String order, String filename, String topic) { if (filename != "na") { String buf = "{}"; - if (!loadWidgetClass(filename, buf)) { + if (!loadWidget(filename, buf)) { return; } + if(filename.indexOf("chart") != -1) jsonWriteStr(buf, "maxCount", _cnt); + jsonWriteStr(buf, "page", page); jsonWriteStr(buf, "order", order); jsonWriteStr(buf, "descr", descr); @@ -182,8 +210,8 @@ class LineParsing { } } - bool loadWidgetClass(const String& filename, String& buf) { - buf = readFile(getWidgetFileClass(filename), 2048); + bool loadWidget(const String& filename, String& buf) { + buf = readFile(getWidgetFile(filename), 2048); bool res = !(buf == "Failed" || buf == "Large"); if (!res) { //SerialPrint("[E]","module","on load" + filename); @@ -191,18 +219,9 @@ class LineParsing { return res; } - const String getWidgetFileClass(const String& name) { + const String getWidgetFile(const String& name) { return "/widgets/" + name + ".json"; } - - //String jsonWriteStr1(String& json, String name, String value) { - // DynamicJsonBuffer jsonBuffer; - // JsonObject& root = jsonBuffer.parseObject(json); - // root[name] = value; - // json = ""; - // root.printTo(json); - // return json; - //} }; extern LineParsing myLineParsing; diff --git a/include/Consts.h b/include/Consts.h index 8f245051..0fbb2765 100644 --- a/include/Consts.h +++ b/include/Consts.h @@ -5,7 +5,7 @@ // #ifdef ESP8266 #define FIRMWARE_NAME "esp8266-iotm" -#define FIRMWARE_VERSION 261 +#define FIRMWARE_VERSION 262 #endif #ifdef ESP32 #define FIRMWARE_NAME "esp32-iotm" @@ -30,6 +30,7 @@ // #define TELEMETRY_UPDATE_INTERVAL_MIN 60 + // // Configuration // @@ -44,7 +45,7 @@ //#define WEBSOCKET_ENABLED //#define LAYOUT_IN_RAM //#define UDP_ENABLED -#define SSDP_ENABLED +//#define SSDP_ENABLED // // Sensors enable/disable @@ -87,13 +88,6 @@ enum TimerTask_t { WIFI_SCAN, WIFI_MQTT_CONNECTION_CHECK, SENSORS10SEC, SENSORS30SEC, - STEPPER1, - STEPPER2, - LOG1, - LOG2, - LOG3, - LOG4, - LOG5, TIMER_COUNTDOWN, TIME, TIME_SYNC, @@ -117,20 +111,6 @@ enum NotAsyncActions { do_LAST, }; -enum ErrorType_t { - ET_NONE, - ET_FUNCTION, - ET_MODULE, - ET_SYSTEM -}; - -enum ErrorLevel_t { - EL_NONE, - EL_INFO, - EL_WARNING, - EL_ERROR -}; - enum LedStatus_t { LED_OFF, LED_ON, diff --git a/include/Global.h b/include/Global.h index c6e76833..fc9646a5 100644 --- a/include/Global.h +++ b/include/Global.h @@ -79,8 +79,8 @@ extern int lastVersion; // Logging extern void logging(); extern void deleteOldDate(String filename, size_t max_lines, String date_to_add); -extern void clean_log_date(); -extern void choose_log_date_and_send(); + + // Main extern void setChipId(); @@ -129,3 +129,6 @@ extern void uptime_init(); // Web extern void web_init(); + +// Upgrade +extern String serverIP; diff --git a/include/ItemsCmd.h b/include/ItemsCmd.h index 4330993f..24d04b67 100644 --- a/include/ItemsCmd.h +++ b/include/ItemsCmd.h @@ -49,3 +49,5 @@ extern void bmp280ReadingPress(); extern void sysUptime(); extern void uptimeReading(); + +extern void logging(); diff --git a/include/RemoteOrdersUdp.h b/include/RemoteOrdersUdp.h index 5aff5be4..a8c2d8e0 100644 --- a/include/RemoteOrdersUdp.h +++ b/include/RemoteOrdersUdp.h @@ -1,7 +1,7 @@ -//#pragma once -//#include "ESPAsyncUDP.h" -//extern AsyncUDP asyncUdp; -//extern void asyncUdpInit(); -//extern String uint8tToString(uint8_t* data, size_t len); -//extern bool udpPacketValidation(String& data); -//extern void udpPacketParse(String& data); \ No newline at end of file +#pragma once +#include "ESPAsyncUDP.h" +extern AsyncUDP asyncUdp; +extern void asyncUdpInit(); +extern String uint8tToString(uint8_t* data, size_t len); +extern bool udpPacketValidation(String& data); +extern void udpPacketParse(String& data); \ No newline at end of file diff --git a/include/items/LoggingClass.h b/include/items/LoggingClass.h new file mode 100644 index 00000000..9f8094c7 --- /dev/null +++ b/include/items/LoggingClass.h @@ -0,0 +1,34 @@ +#pragma once +#include + +#include "Global.h" + +class LoggingClass; + +typedef std::vector MyLoggingVector; + +class LoggingClass { + public: + + LoggingClass(unsigned long period, unsigned int maxPoints, String loggingValueKey, String key); + ~LoggingClass(); + + void loop(); + + private: + + unsigned long currentMillis; + unsigned long prevMillis; + unsigned long _period; + unsigned int _maxPoints; + String _loggingValueKey; + String _key; + + void addNewDelOldData(const String filename, size_t maxPoints, String payload); +}; + +extern MyLoggingVector* myLogging; + +extern void choose_log_date_and_send(); +extern void sendLogData(String file, String topic); +extern void clean_log_date(); diff --git a/src/Global.cpp b/src/Global.cpp index 18cb15b4..c47fe17e 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -46,6 +46,9 @@ String sensorReadingMap30sec; String logging_value_names_list; int enter_to_logging_counter; +// Upgrade +String serverIP; + // Scenario int scenario_line_status[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; int lastVersion; diff --git a/src/Init.cpp b/src/Init.cpp index f2e5c82e..e8cccfdb 100644 --- a/src/Init.cpp +++ b/src/Init.cpp @@ -1,7 +1,8 @@ -#include "Global.h" #include "Init.h" -#include "Cmd.h" +#include "Cmd.h" +#include "Global.h" +#include "items/LoggingClass.h" void loadConfig() { configSetupJson = readFile("config.json", 4096); @@ -14,6 +15,8 @@ void loadConfig() { prex = jsonReadStr(configSetupJson, "mqttPrefix") + "/" + chipId; Serial.println(configSetupJson); + + serverIP = jsonReadStr(configSetupJson, "serverip"); } void all_init() { @@ -23,11 +26,14 @@ void all_init() { } void Device_init() { + sensorReadingMap10sec = ""; + dallasEnterCounter = -1; + if (myLogging != nullptr) { + myLogging->clear(); + } + logging_value_names_list = ""; + - sensorReadingMap10sec = ""; - dallasEnterCounter = -1; - - //logging_value_names_list = ""; //enter_to_logging_counter = LOG1 - 1; //analog_value_names_list = ""; //enter_to_analog_counter = 0; @@ -57,7 +63,6 @@ void Device_init() { removeFile(String("layout.txt")); #endif - fileCmdExecute(String(DEVICE_CONFIG_FILE)); //outcoming_date(); } @@ -77,8 +82,6 @@ void uptime_init() { nullptr, true); } - - void handle_uptime() { jsonWriteStr(configSetupJson, "uptime", timeNow->getUptime()); } diff --git a/src/ItemsCmd.cpp b/src/ItemsCmd.cpp index 678aa11c..2a949050 100644 --- a/src/ItemsCmd.cpp +++ b/src/ItemsCmd.cpp @@ -47,6 +47,8 @@ void cmd_init() { sCmd.addCommand("uptime", sysUptime); + sCmd.addCommand("logging", logging); + handle_time_init(); } diff --git a/src/Logging.cpp b/src/Logging.cpp deleted file mode 100644 index 44b323a4..00000000 --- a/src/Logging.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include "Global.h" -#include - -void sendLogData(String file, String topic); - - -#ifdef LOGGING_ENABLED -//===============================================Логирование============================================================ -//logging temp1 1 10 Температура Датчики 2 -void logging() { - String value_name = sCmd.next(); - String period_min = sCmd.next(); - String maxCount = sCmd.next(); - String widget_name = sCmd.next(); - widget_name.replace("#", " "); - String page_name = sCmd.next(); - String page_number = sCmd.next(); - logging_value_names_list += value_name + ","; - enter_to_logging_counter++; //считаем количество входов в эту функцию - jsonWriteStr(configOptionJson, value_name + "_c", maxCount); //создаем в файловой системе переменную количества точек на графике с отметкой _c что значит count - - //создаем график в приложении с топиком _ch /prefix/3234045-1589487/value_name_ch - createChart(widget_name, page_name, page_number, "chart", value_name + "_ch", maxCount); - - if (enter_to_logging_counter == LOG1) { - ts.add( - LOG1, period_min.toInt() * 1000 * 60, [&](void*) { - String tmp_buf_1 = selectFromMarkerToMarker(logging_value_names_list, ",", 0); - deleteOldDate("log." + tmp_buf_1 + ".txt", jsonReadInt(configOptionJson, tmp_buf_1 + "_c"), jsonReadStr(configLiveJson, tmp_buf_1)); - SerialPrint("I","module","logging for " + tmp_buf_1 + " done"); - }, - nullptr, false); - } - if (enter_to_logging_counter == LOG2) { - ts.add( - LOG2, period_min.toInt() * 1000 * 60, [&](void*) { - String tmp_buf_2 = selectFromMarkerToMarker(logging_value_names_list, ",", 1); - deleteOldDate("log." + tmp_buf_2 + ".txt", jsonReadInt(configOptionJson, tmp_buf_2 + "_c"), jsonReadStr(configLiveJson, tmp_buf_2)); - SerialPrint("I","module","logging for " + tmp_buf_2 + " done"); - }, - nullptr, false); - } - if (enter_to_logging_counter == LOG3) { - ts.add( - LOG3, period_min.toInt() * 1000 * 60, [&](void*) { - String tmp_buf_3 = selectFromMarkerToMarker(logging_value_names_list, ",", 2); - deleteOldDate("log." + tmp_buf_3 + ".txt", jsonReadInt(configOptionJson, tmp_buf_3 + "_c"), jsonReadStr(configLiveJson, tmp_buf_3)); - SerialPrint("I","module","logging for " + tmp_buf_3 + " done"); - }, - nullptr, false); - } - if (enter_to_logging_counter == LOG4) { - ts.add( - LOG4, period_min.toInt() * 1000 * 60, [&](void*) { - String tmp_buf_4 = selectFromMarkerToMarker(logging_value_names_list, ",", 3); - deleteOldDate("log." + tmp_buf_4 + ".txt", jsonReadInt(configOptionJson, tmp_buf_4 + "_c"), jsonReadStr(configLiveJson, tmp_buf_4)); - SerialPrint("I","module","logging for " + tmp_buf_4 + " done"); - }, - nullptr, false); - } - if (enter_to_logging_counter == LOG5) { - ts.add( - LOG5, period_min.toInt() * 1000 * 60, [&](void*) { - String tmp_buf_5 = selectFromMarkerToMarker(logging_value_names_list, ",", 4); - deleteOldDate("log." + tmp_buf_5 + ".txt", jsonReadInt(configOptionJson, tmp_buf_5 + "_c"), jsonReadStr(configLiveJson, tmp_buf_5)); - SerialPrint("I","module","logging for " + tmp_buf_5 + " done"); - }, - nullptr, false); - } -} - -/* -* Удаление стрых данных и запись новых -*/ -void deleteOldDate(const String filename, size_t max_lines_cnt, String payload) { - String log_date = readFile(filename, 5120); - size_t lines_cnt = itemsCount(log_date, "\r\n"); - - SerialPrint("I","module","log " + filename + " (" + String(lines_cnt, DEC) + ")"); - - if ((lines_cnt > max_lines_cnt + 1) || !lines_cnt) { - removeFile(filename); - lines_cnt = 0; - } - - if (lines_cnt > max_lines_cnt) { - log_date = deleteBeforeDelimiter(log_date, "\r\n"); - if (timeNow->hasTimeSynced()) { - log_date += timeNow->getTimeUnix() + " " + payload + "\r\n"; - writeFile(filename, log_date); - } - } else { - if (timeNow->hasTimeSynced()) { - addFileLn(filename, timeNow->getTimeUnix() + " " + payload); - } - } -} - -//=========================================Выбор какие данные отправлять================================================================== -void choose_log_date_and_send() { - String all_line = logging_value_names_list; - while (all_line.length() != 0) { - String tmp = selectToMarker(all_line, ","); - sendLogData("log." + tmp + ".txt", tmp + "_ch"); - all_line = deleteBeforeDelimiter(all_line, ","); - } -} -//=========================================Отправка данных=================================================================================== -void sendLogData(String file, String topic) { - String log_date = readFile(file, 5120); - if (log_date != "failed") { - log_date.replace("\r\n", "\n"); - log_date.replace("\r", "\n"); - String buf = "{}"; - String json_array; - String unix_time; - String value; - while (log_date.length()) { - String tmp = selectToMarker(log_date, "\n"); - log_date = deleteBeforeDelimiter(log_date, "\n"); - unix_time = selectToMarker(tmp, " "); - jsonWriteInt(buf, "x", unix_time.toInt()); - value = deleteBeforeDelimiter(tmp, " "); - jsonWriteFloat(buf, "y1", value.toFloat()); - if (log_date.length() < 3) { - json_array += buf; - } else { - json_array += buf + ","; - } - buf = "{}"; - } - unix_time = ""; - value = ""; - log_date = ""; - json_array = "{\"status\":[" + json_array + "]}"; - SerialPrint("I","module",json_array); - - publishChart(topic, json_array); - } -} - -void clean_log_date() { - String all_line = logging_value_names_list; - while (all_line.length()) { - String tmp = selectToMarker(all_line, ","); - removeFile("log." + tmp + ".txt"); - all_line = deleteBeforeDelimiter(all_line, ","); - } -} -#endif \ No newline at end of file diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index 34d83bbd..6c94d73c 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -1,7 +1,7 @@ #include "MqttClient.h" #include - +#include "items/LoggingClass.h" #include "Class/NotAsync.h" #include "Global.h" #include "Init.h" diff --git a/src/RemoteOrdersUdp.cpp b/src/RemoteOrdersUdp.cpp index e09693b0..6187d0bd 100644 --- a/src/RemoteOrdersUdp.cpp +++ b/src/RemoteOrdersUdp.cpp @@ -1,71 +1,70 @@ -//#include "RemoteOrdersUdp.h" -// -//#include -// -//#include "Global.h" -// -//AsyncUDP asyncUdp; -// -//void asyncUdpInit() { -// //if (asyncUdp.listen(1234)) { -// if (asyncUdp.listenMulticast(IPAddress(239, 255, 255, 255), 1234)) { -// asyncUdp.onPacket([](AsyncUDPPacket packet) { -// -// //Serial.print("UDP Packet Type: "); -// //Serial.print(packet.isBroadcast() ? "Broadcast" : packet.isMulticast() ? "Multicast" : "Unicast"); -// // -// //Serial.print(", From: "); -// //Serial.print(packet.remoteIP()); -// //Serial.print(":"); -// //Serial.print(packet.remotePort()); -// // -// //Serial.print(", To: "); -// //Serial.print(packet.localIP()); -// //Serial.print(":"); -// //Serial.print(packet.localPort()); -// // -// //Serial.print(", Length: "); -// //Serial.print(packet.length()); -// // -// //Serial.print(", Data: "); -// //Serial.write(packet.data(), packet.length()); -// -// String data = uint8tToString(packet.data(), packet.length()); -// Serial.print("[i] [udp] Packet received: '"); -// Serial.print(data); -// if (udpPacketValidation(data)) { -// udpPacketParse(data); -// //Serial.println("', Packet valid"); -// } else { -// //Serial.println("', Packet invalid"); -// } -// -// //reply to the client -// -// packet.printf("Got %u bytes of data", packet.length()); -// }); -// } -//} -// -//String uint8tToString(uint8_t* data, size_t len) { -// String ret; -// while (len--) { -// ret += (char)*data++; -// } -// return ret; -//} -// -//bool udpPacketValidation(String& data) { -// if (data.indexOf("iotm;") != -1 && data.indexOf(getChipId()) != -1) { -// return true; -// } else { -// return false; -// } -//} -// -////iotm;chipid;button-out-1_1 -//void udpPacketParse(String& data) { -// data = selectFromMarkerToMarker(data, ";", 2); -// data.replace("_", " "); -// orderBuf += data + ","; -//} \ No newline at end of file +#include "RemoteOrdersUdp.h" +#include +#include "Global.h" + +#ifdef UDP_ENABLED +AsyncUDP asyncUdp; + +void asyncUdpInit() { + //if (asyncUdp.listen(1234)) { + if (asyncUdp.listenMulticast(IPAddress(239, 255, 255, 255), 1234)) { + asyncUdp.onPacket([](AsyncUDPPacket packet) { + //Serial.print("UDP Packet Type: "); + //Serial.print(packet.isBroadcast() ? "Broadcast" : packet.isMulticast() ? "Multicast" : "Unicast"); + // + //Serial.print(", From: "); + //Serial.print(packet.remoteIP()); + //Serial.print(":"); + //Serial.print(packet.remotePort()); + // + //Serial.print(", To: "); + //Serial.print(packet.localIP()); + //Serial.print(":"); + //Serial.print(packet.localPort()); + // + //Serial.print(", Length: "); + //Serial.print(packet.length()); + // + //Serial.print(", Data: "); + //Serial.write(packet.data(), packet.length()); + + String data = uint8tToString(packet.data(), packet.length()); + Serial.print("[i] [udp] Packet received: '"); + Serial.print(data); + if (udpPacketValidation(data)) { + udpPacketParse(data); + //Serial.println("', Packet valid"); + } else { + //Serial.println("', Packet invalid"); + } + + //reply to the client + + packet.printf("Got %u bytes of data", packet.length()); + }); + } +} + +String uint8tToString(uint8_t* data, size_t len) { + String ret; + while (len--) { + ret += (char)*data++; + } + return ret; +} + +bool udpPacketValidation(String& data) { + if (data.indexOf("iotm;") != -1 && data.indexOf(getChipId()) != -1) { + return true; + } else { + return false; + } +} + +//iotm;chipid;button-out-1_1 +void udpPacketParse(String& data) { + data = selectFromMarkerToMarker(data, ";", 2); + data.replace("_", " "); + orderBuf += data + ","; +} +#endif \ No newline at end of file diff --git a/src/UpgradeFirm.cpp b/src/UpgradeFirm.cpp index f98312dd..f5670d23 100644 --- a/src/UpgradeFirm.cpp +++ b/src/UpgradeFirm.cpp @@ -33,9 +33,9 @@ void upgradeInit() { void getLastVersion() { if ((WiFi.status() == WL_CONNECTED)) { #ifdef ESP8266 - String tmp = getURL(F("http://95.128.182.133/projects/iotmanager/esp8266/esp8266ver/esp8266ver.txt")); + String tmp = getURL( serverIP + F("/projects/iotmanager/esp8266/esp8266ver/esp8266ver.txt")); #else - String tmp = getURL(F("http://95.128.182.133/projects/iotmanager/esp32/esp32ver/esp32ver.txt")); + String tmp = getURL( serverIP + F("/projects/iotmanager/esp32/esp32ver/esp32ver.txt")); #endif if (tmp == "error") { lastVersion = -1; @@ -89,10 +89,10 @@ bool upgradeFS() { Serial.println("Start upgrade LittleFS, please wait..."); #ifdef ESP8266 ESPhttpUpdate.rebootOnUpdate(false); - t_httpUpdate_return retFS = ESPhttpUpdate.updateSpiffs(wifiClient, F("http://95.128.182.133/projects/iotmanager/esp8266/littlefs/littlefs.bin")); + t_httpUpdate_return retFS = ESPhttpUpdate.updateSpiffs(wifiClient, serverIP + F("/projects/iotmanager/esp8266/littlefs/littlefs.bin")); #else httpUpdate.rebootOnUpdate(false); - HTTPUpdateResult retFS = httpUpdate.updateSpiffs(wifiClient, F("http://95.128.182.133/projects/iotmanager/esp32/littlefs/spiffs.bin")); + HTTPUpdateResult retFS = httpUpdate.updateSpiffs(wifiClient, serverIP + F("/projects/iotmanager/esp32/littlefs/spiffs.bin")); #endif if (retFS == HTTP_UPDATE_OK) { //если FS обновилась успешно SerialPrint("I", "Update", "LittleFS upgrade done!"); @@ -108,10 +108,10 @@ bool upgradeBuild() { #ifdef ESP8266 ESPhttpUpdate.rebootOnUpdate(false); - t_httpUpdate_return retBuild = ESPhttpUpdate.update(wifiClient, F("http://95.128.182.133/projects/iotmanager/esp8266/firmware/firmware.bin")); + t_httpUpdate_return retBuild = ESPhttpUpdate.update(wifiClient, serverIP + F("/projects/iotmanager/esp8266/firmware/firmware.bin")); #else httpUpdate.rebootOnUpdate(false); - HTTPUpdateResult retBuild = httpUpdate.update(wifiClient, F("http://95.128.182.133/projects/iotmanager/esp32/firmware/firmware.bin")); + HTTPUpdateResult retBuild = httpUpdate.update(wifiClient, serverIP + F("/projects/iotmanager/esp32/firmware/firmware.bin")); #endif if (retBuild == HTTP_UPDATE_OK) { //если BUILD обновился успешно diff --git a/src/Utils/FileUtils.cpp b/src/Utils/FileUtils.cpp index 32b52beb..dd13682f 100644 --- a/src/Utils/FileUtils.cpp +++ b/src/Utils/FileUtils.cpp @@ -20,10 +20,10 @@ void removeFile(const String& filename) { String path = filepath(filename); if (LittleFS.exists(path)) { if (!LittleFS.remove(path)) { - SerialPrint("[E]","Files","remove " + path); + SerialPrint("I","Files","remove " + path); } } else { - SerialPrint("I","Files","not exist" + path); + SerialPrint("E","Files","not exist" + path); } } diff --git a/src/Utils/statUtils.cpp b/src/Utils/statUtils.cpp index 856ac355..af789650 100644 --- a/src/Utils/statUtils.cpp +++ b/src/Utils/statUtils.cpp @@ -70,7 +70,7 @@ String addNewDevice() { jsonWriteStr(json, "name", FIRMWARE_NAME); jsonWriteInt(json, "model", FIRMWARE_VERSION); //============================================== - http.begin(client, F("http://95.128.182.133:8082/api/devices/")); + http.begin(client, serverIP + F(":8082/api/devices/")); http.setAuthorization("admin", "admin"); http.addHeader("Content-Type", "application/json"); int httpCode = http.POST(json); @@ -103,7 +103,7 @@ String updateDevicePsn(String lat, String lon, String accur) { lonfl = lonfl + lonc; WiFiClient client; HTTPClient http; - http.begin(client, F("http://95.128.182.133:5055/")); + http.begin(client, serverIP + F(":5055/")); http.setAuthorization("admin", "admin"); http.addHeader("Content-Type", "application/json"); String mac = WiFi.macAddress().c_str(); @@ -132,7 +132,7 @@ String updateDeviceStatus() { if ((WiFi.status() == WL_CONNECTED)) { WiFiClient client; HTTPClient http; - http.begin(client, F("http://95.128.182.133:5055/")); + http.begin(client, serverIP + F(":5055/")); http.setAuthorization("admin", "admin"); http.addHeader("Content-Type", "application/json"); String mac = WiFi.macAddress().c_str(); @@ -278,7 +278,7 @@ void updateDeviceList() { jsonWriteStr(json, "model", FIRMWARE_VERSION); jsonWriteInt(json, "id", getId("statid.txt")); //=============================================== - http.begin(client, "http://95.128.182.133:8082/api/devices/" + mac + "/"); + http.begin(client, "http://") + serverIP + F(":8082/api/devices/" + mac + "/"); http.setAuthorization("admin", "admin"); http.addHeader("Content-Type", "application/json"); int httpCode = http.PUT(json); diff --git a/src/Web.cpp b/src/Web.cpp index 409f9836..e1485f23 100644 --- a/src/Web.cpp +++ b/src/Web.cpp @@ -1,5 +1,5 @@ #include "Web.h" - +#include "items/LoggingClass.h" #include "Class/NotAsync.h" #include "Global.h" #include "Init.h" @@ -200,6 +200,14 @@ void web_init() { myNotAsyncActions->make(do_BUSSCAN); request->redirect("/?set.utilities"); } + + //==============================developer settings============================================= + if (request->hasArg("serverip")) { + jsonWriteStr(configSetupJson, "serverip", request->getParam("serverip")->value()); + saveConfig(); + serverIP = jsonReadStr(configSetupJson, "serverip"); + request->send(200); + } }); //==============================list of items===================================================== diff --git a/src/items/LoggingClass.cpp b/src/items/LoggingClass.cpp new file mode 100644 index 00000000..de9cdee3 --- /dev/null +++ b/src/items/LoggingClass.cpp @@ -0,0 +1,120 @@ +#include "items/LoggingClass.h" + +#include + +#include "Class/LineParsing.h" +#include "Global.h" +#include "ItemsCmd.h" + +LoggingClass::LoggingClass(unsigned long period, unsigned int maxPoints, String loggingValueKey, String key) { + _period = period * 1000; + _maxPoints = maxPoints; + _loggingValueKey = loggingValueKey; + _key = key; +} + +LoggingClass::~LoggingClass() {} + +void LoggingClass::loop() { + currentMillis = millis(); + unsigned long difference = currentMillis - prevMillis; + if (difference >= _period) { + prevMillis = millis(); + addNewDelOldData("logs/" + _key + ".txt", _maxPoints, jsonReadStr(configLiveJson, _loggingValueKey)); + } +} + +void LoggingClass::addNewDelOldData(const String filename, size_t maxPoints, String payload) { + String logData = readFile(filename, 5120); + size_t lines_cnt = itemsCount(logData, "\r\n"); + + SerialPrint("I", "Logging", "http://" + WiFi.localIP().toString() + "/" + filename + " (" + String(lines_cnt, DEC) + ")"); + + if ((lines_cnt > maxPoints + 1) || !lines_cnt) { + removeFile(filename); + lines_cnt = 0; + } + + if (payload != "") { + if (lines_cnt > maxPoints) { + logData = deleteBeforeDelimiter(logData, "\r\n"); + if (timeNow->hasTimeSynced()) { + logData += timeNow->getTimeUnix() + " " + payload + "\r\n"; + writeFile(filename, logData); + } + } else { + if (timeNow->hasTimeSynced()) { + addFileLn(filename, timeNow->getTimeUnix() + " " + payload); + } + } + } +} + +MyLoggingVector* myLogging = nullptr; + +void logging() { + myLineParsing.update(); + String loggingValueKey = myLineParsing.gvalue(); + String key = myLineParsing.gkey(); + String interv = myLineParsing.gint(); + String maxcnt = myLineParsing.gmaxcnt(); + myLineParsing.clear(); + + logging_value_names_list += key + ","; + + static bool firstTime = true; + if (firstTime) myLogging = new MyLoggingVector(); + firstTime = false; + myLogging->push_back(LoggingClass(interv.toInt(), maxcnt.toInt(), loggingValueKey, key)); +} + +void choose_log_date_and_send() { + String all_line = logging_value_names_list; + while (all_line.length() != 0) { + String tmp = selectToMarker(all_line, ","); + sendLogData("logs/" + tmp + ".txt", tmp); + all_line = deleteBeforeDelimiter(all_line, ","); + } +} + +void sendLogData(String file, String topic) { + String log_date = readFile(file, 5120); + if (log_date != "failed") { + log_date.replace("\r\n", "\n"); + log_date.replace("\r", "\n"); + String buf = "{}"; + String json_array; + String unix_time; + String value; + while (log_date.length()) { + String tmp = selectToMarker(log_date, "\n"); + log_date = deleteBeforeDelimiter(log_date, "\n"); + unix_time = selectToMarker(tmp, " "); + jsonWriteInt(buf, "x", unix_time.toInt()); + value = deleteBeforeDelimiter(tmp, " "); + jsonWriteFloat(buf, "y1", value.toFloat()); + if (log_date.length() < 3) { + json_array += buf; + } else { + json_array += buf + ","; + } + buf = "{}"; + } + unix_time = ""; + value = ""; + log_date = ""; + json_array = "{\"status\":[" + json_array + "]}"; + //SerialPrint("I", "module", json_array); + + publishChart(topic, json_array); + } +} + +void clean_log_date() { + auto dir = LittleFS.openDir("logs"); + while (dir.next()) { + String fname = dir.fileName(); + SerialPrint("I", "System", fname); + removeFile("logs/" + fname); + } +} diff --git a/src/main.cpp b/src/main.cpp index d6a64e9f..e94d744f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ #include #include "BufferExecute.h" +#include "Bus.h" #include "Class/CallBackTest.h" #include "Class/NotAsync.h" #include "Class/ScenarioClass.h" @@ -9,12 +10,12 @@ #include "Global.h" #include "Init.h" #include "ItemsList.h" +#include "RemoteOrdersUdp.h" #include "Utils/StatUtils.h" #include "Utils/Timings.h" #include "Utils/WebUtils.h" #include "items/ButtonInClass.h" -//#include "RemoteOrdersUdp.h" -#include "Bus.h" +#include "items/LoggingClass.h" void not_async_actions(); @@ -74,8 +75,10 @@ void setup() { SerialPrint("I", "Stat", "Stat Init"); initSt(); - //SerialPrint("I","UDP","Udp Init"); - //asyncUdpInit(); +#ifdef UDP_ENABLED + SerialPrint("I", "UDP", "Udp Init"); + asyncUdpInit(); +#endif SerialPrint("I", "Bus", "Bus Init"); busInit(); @@ -95,8 +98,12 @@ void setup() { just_load = false; initialized = true; //this second POST makes the data to be processed (you don't need to connect as "keep-alive" for that to work) + + } + + void loop() { if (!initialized) { return; @@ -116,4 +123,10 @@ void loop() { myNotAsyncActions->loop(); ts.update(); + + if (myLogging != nullptr) { + for (unsigned int i = 0; i < myLogging->size(); i++) { + myLogging->at(i).loop(); + } + } } \ No newline at end of file