diff --git a/data/conf/001c.txt b/data/conf/c001.txt similarity index 100% rename from data/conf/001c.txt rename to data/conf/c001.txt diff --git a/data/conf/002c.txt b/data/conf/c002.txt similarity index 100% rename from data/conf/002c.txt rename to data/conf/c002.txt diff --git a/data/conf/003c.txt b/data/conf/c003.txt similarity index 100% rename from data/conf/003c.txt rename to data/conf/c003.txt diff --git a/data/conf/004c.txt b/data/conf/c004.txt similarity index 100% rename from data/conf/004c.txt rename to data/conf/c004.txt diff --git a/data/conf/005c.txt b/data/conf/c005.txt similarity index 100% rename from data/conf/005c.txt rename to data/conf/c005.txt diff --git a/data/conf/006c.txt b/data/conf/c006.txt similarity index 100% rename from data/conf/006c.txt rename to data/conf/c006.txt diff --git a/data/conf/007c.txt b/data/conf/c007.txt similarity index 100% rename from data/conf/007c.txt rename to data/conf/c007.txt diff --git a/data/conf/008c.txt b/data/conf/c008.txt similarity index 100% rename from data/conf/008c.txt rename to data/conf/c008.txt diff --git a/data/conf/009c.txt b/data/conf/c009.txt similarity index 68% rename from data/conf/009c.txt rename to data/conf/c009.txt index ce8ec1a8..496b4761 100644 --- a/data/conf/009c.txt +++ b/data/conf/c009.txt @@ -1,5 +1,5 @@ -dhtT t 2 dht11 Температура#DHT,#t°C Датчики any-data 1 -dhtH h 2 dht11 Влажность#DHT,#t°C Датчики any-data 2 +dhtT t 2 dht11 Температура#DHT,#t°C Датчики anydata 1 +dhtH h 2 dht11 Влажность#DHT,#t°C Датчики anydata 2 dhtComfort Степень#комфорта: Датчики 3 dhtPerception Восприятие: Датчики 4 dhtDewpoint Точка#росы: Датчики 5 diff --git a/data/conf/010c.txt b/data/conf/c010.txt similarity index 68% rename from data/conf/010c.txt rename to data/conf/c010.txt index a0124e41..0972be00 100644 --- a/data/conf/010c.txt +++ b/data/conf/c010.txt @@ -1,5 +1,5 @@ -dhtT t 2 dht22 Температура#DHT,#t°C Датчики any-data 1 -dhtH h 2 dht22 Влажность#DHT,#t°C Датчики any-data 2 +dhtT t 2 dht22 Температура#DHT,#t°C Датчики anydata 1 +dhtH h 2 dht22 Влажность#DHT,#t°C Датчики anydata 2 dhtComfort Степень#комфорта: Датчики 3 dhtPerception Восприятие: Датчики 4 dhtDewpoint Точка#росы: Датчики 5 diff --git a/data/conf/011c.txt b/data/conf/c011.txt similarity index 87% rename from data/conf/011c.txt rename to data/conf/c011.txt index 429ccada..acf8f5e3 100644 --- a/data/conf/011c.txt +++ b/data/conf/c011.txt @@ -5,4 +5,4 @@ logging adc 5 100 Аналоговый#вход Датчики 2 //значение чтения аналогового входа будут примерно равным //при 1 вольте - 310, а при 2 вольтах - 620 (считаем по пропорции) //данная строка переведет диапазон 310-620 в диапазон 1-100 и отобразит в приложении -//варианты отображения: any-data, progress-round, progress-line, fill-gauge +//варианты отображения: anydata, progress-round, progress-line, fillgauge diff --git a/data/conf/012c.txt b/data/conf/c012.txt similarity index 76% rename from data/conf/012c.txt rename to data/conf/c012.txt index 16956455..3793a877 100644 --- a/data/conf/012c.txt +++ b/data/conf/c012.txt @@ -1,5 +1,5 @@ -bmp280T temp1 0x76 Температура#bmp280 Датчики any-data 1 -bmp280P press1 0x76 Давление#bmp280 Датчики any-data 2 +bmp280T temp1 0x76 Температура#bmp280 Датчики anydata 1 +bmp280P press1 0x76 Давление#bmp280 Датчики anydata 2 logging temp1 1 100 Температура Датчики 3 logging press1 1 100 Давление Датчики 4 diff --git a/data/conf/013c.txt b/data/conf/c013.txt similarity index 61% rename from data/conf/013c.txt rename to data/conf/c013.txt index e8414f61..78630cfe 100644 --- a/data/conf/013c.txt +++ b/data/conf/c013.txt @@ -1,7 +1,7 @@ -bme280T temp1 0x76 Температура#bmp280 Датчики any-data 1 -bme280P pres1 0x76 Давление#bmp280 Датчики any-data 2 -bme280H hum1 0x76 Влажность#bmp280 Датчики any-data 3 -bme280A altit1 0x76 Высота#bmp280 Датчики any-data 4 +bme280T temp1 0x76 Температура#bmp280 Датчики anydata 1 +bme280P pres1 0x76 Давление#bmp280 Датчики anydata 2 +bme280H hum1 0x76 Влажность#bmp280 Датчики anydata 3 +bme280A altit1 0x76 Высота#bmp280 Датчики anydata 4 logging temp1 1 100 Температура Датчики 5 logging press1 1 100 Давление Датчики 6 logging hum1 1 100 Влажность Датчики 7 diff --git a/data/conf/014c.txt b/data/conf/c014.txt similarity index 59% rename from data/conf/014c.txt rename to data/conf/c014.txt index e76ce5d6..92c9346c 100644 --- a/data/conf/014c.txt +++ b/data/conf/c014.txt @@ -1,5 +1,5 @@ -dallas temp1 2 123456 Водонагреватель,#t°C Датчики any-data 1 +dallas temp1 2 123456 Водонагреватель,#t°C Датчики anydata 1 logging dallas 1 100 Температура Датчики 2 //2 - номер пина датчика -//варианты отображения: any-data, progress-round, progress-line, fill-gauge \ No newline at end of file +//варианты отображения: anydata, progress-round, progress-line, fillgauge \ No newline at end of file diff --git a/data/conf/015c.txt b/data/conf/c015.txt similarity index 98% rename from data/conf/015c.txt rename to data/conf/c015.txt index af75deeb..6567cf6d 100644 --- a/data/conf/015c.txt +++ b/data/conf/c015.txt @@ -1,4 +1,4 @@ -dallas 2 Водонагреватель,#t°C Термостат any-data 1 +dallas 2 Водонагреватель,#t°C Термостат anydata 1 logging dallas 5 100 Температура Термостат 2 inputDigit digit1 При#скольки#выключить? Термостат 40 3 inputDigit digit2 При#скольки#включить? Термостат 20 4 diff --git a/data/conf/016c.txt b/data/conf/c016.txt similarity index 87% rename from data/conf/016c.txt rename to data/conf/c016.txt index 1d460a0b..0b82f2b9 100644 --- a/data/conf/016c.txt +++ b/data/conf/c016.txt @@ -1,5 +1,5 @@ -levelPr p 14 12 Уровень#в#баке,#% Датчики fill-gauge 125 25 1 -ultrasonicCm cm 14 12 Дистанция,#см Датчики any-data 2 +levelPr p 14 12 Уровень#в#баке,#% Датчики fillgauge 125 25 1 +ultrasonicCm cm 14 12 Дистанция,#см Датчики anydata 2 inputDigit digit1 При#скольки#выключить? Датчики 95 3 inputDigit digit2 При#скольки#включить? Датчики 10 4 button 1 5 Насос Датчики 0 5 @@ -9,4 +9,4 @@ logging p 1 100 Вода#в#баке Датчики 6 //25 - это расстояние от датчика до поверхности воды когда бак полный в сантиметрах //distancePr - эта строка выводит процент заполнения бака //distanceCm - эта строка выводит расстояние в сантиметрах -//варианты отображения: any-data, progress-round, progress-line, fill-gauge \ No newline at end of file +//варианты отображения: anydata, progress-round, progress-line, fillgauge \ No newline at end of file diff --git a/data/conf/017c.txt b/data/conf/c017.txt similarity index 100% rename from data/conf/017c.txt rename to data/conf/c017.txt diff --git a/data/conf/018c.txt b/data/conf/c018.txt similarity index 100% rename from data/conf/018c.txt rename to data/conf/c018.txt diff --git a/data/conf/019c.txt b/data/conf/c019.txt similarity index 100% rename from data/conf/019c.txt rename to data/conf/c019.txt diff --git a/data/conf/020c.txt b/data/conf/c020.txt similarity index 100% rename from data/conf/020c.txt rename to data/conf/c020.txt diff --git a/data/conf/021c.txt b/data/conf/c021.txt similarity index 100% rename from data/conf/021c.txt rename to data/conf/c021.txt diff --git a/data/100c.txt b/data/conf/c100.txt similarity index 83% rename from data/100c.txt rename to data/conf/c100.txt index 99beb0be..c943b43b 100644 --- a/data/100c.txt +++ b/data/conf/c100.txt @@ -3,7 +3,7 @@ button 2 13 Прихожая Реле 0 2 button 3 14 Кухня Реле 0 3 pwm 1 3 Яркость#коредор: Реле 1023 4 pwm 2 4 Яркость#ванная: Реле 510 5 -analog adc 0 Аналоговый#вход Датчики fill-gauge 1 1023 1 1023 6 +analog adc 0 Аналоговый#вход Датчики fillgauge 1 1023 1 1023 6 logging adc 1 100 Аналоговый#вход Датчики 7 //Это демо конфигурация. В ней показано как связать кнопки c помощью сценариев diff --git a/data/conf/001s.txt b/data/conf/s001.txt similarity index 100% rename from data/conf/001s.txt rename to data/conf/s001.txt diff --git a/data/conf/002s.txt b/data/conf/s002.txt similarity index 100% rename from data/conf/002s.txt rename to data/conf/s002.txt diff --git a/data/conf/003s.txt b/data/conf/s003.txt similarity index 100% rename from data/conf/003s.txt rename to data/conf/s003.txt diff --git a/data/conf/004s.txt b/data/conf/s004.txt similarity index 100% rename from data/conf/004s.txt rename to data/conf/s004.txt diff --git a/data/conf/005s.txt b/data/conf/s005.txt similarity index 100% rename from data/conf/005s.txt rename to data/conf/s005.txt diff --git a/data/conf/006s.txt b/data/conf/s006.txt similarity index 100% rename from data/conf/006s.txt rename to data/conf/s006.txt diff --git a/data/conf/007s.txt b/data/conf/s007.txt similarity index 100% rename from data/conf/007s.txt rename to data/conf/s007.txt diff --git a/data/conf/008s.txt b/data/conf/s008.txt similarity index 100% rename from data/conf/008s.txt rename to data/conf/s008.txt diff --git a/data/conf/009s.txt b/data/conf/s009.txt similarity index 100% rename from data/conf/009s.txt rename to data/conf/s009.txt diff --git a/data/conf/010s.txt b/data/conf/s010.txt similarity index 100% rename from data/conf/010s.txt rename to data/conf/s010.txt diff --git a/data/conf/011s.txt b/data/conf/s011.txt similarity index 100% rename from data/conf/011s.txt rename to data/conf/s011.txt diff --git a/data/conf/012s.txt b/data/conf/s012.txt similarity index 100% rename from data/conf/012s.txt rename to data/conf/s012.txt diff --git a/data/conf/013s.txt b/data/conf/s013.txt similarity index 100% rename from data/conf/013s.txt rename to data/conf/s013.txt diff --git a/data/conf/014s.txt b/data/conf/s014.txt similarity index 100% rename from data/conf/014s.txt rename to data/conf/s014.txt diff --git a/data/conf/015s.txt b/data/conf/s015.txt similarity index 100% rename from data/conf/015s.txt rename to data/conf/s015.txt diff --git a/data/conf/016s.txt b/data/conf/s016.txt similarity index 100% rename from data/conf/016s.txt rename to data/conf/s016.txt diff --git a/data/conf/017s.txt b/data/conf/s017.txt similarity index 100% rename from data/conf/017s.txt rename to data/conf/s017.txt diff --git a/data/conf/018s.txt b/data/conf/s018.txt similarity index 100% rename from data/conf/018s.txt rename to data/conf/s018.txt diff --git a/data/conf/019s.txt b/data/conf/s019.txt similarity index 100% rename from data/conf/019s.txt rename to data/conf/s019.txt diff --git a/data/conf/020s.txt b/data/conf/s020.txt similarity index 100% rename from data/conf/020s.txt rename to data/conf/s020.txt diff --git a/data/conf/021s.txt b/data/conf/s021.txt similarity index 100% rename from data/conf/021s.txt rename to data/conf/s021.txt diff --git a/data/100s.txt b/data/conf/s100.txt similarity index 100% rename from data/100s.txt rename to data/conf/s100.txt diff --git a/data/config.json b/data/config.json index 589bab8c..6114577a 100644 --- a/data/config.json +++ b/data/config.json @@ -3,19 +3,19 @@ "chipID": "", "apssid": "IoTmanager", "appass": "", - "routerssid": "rise", - "routerpass": "hostel3333", + "routerssid": "HomeNet", + "routerpass": "#19821111_", "timezone": 2, "ntp": "pool.ntp.org", - "mqttServer": "91.204.228.124", + "mqttServer": "192.168.1.30", "mqttPort": 1883, - "mqttPrefix": "/rise", - "mqttUser": "test", - "mqttPass": "test", + "mqttPrefix": "/iot", + "mqttUser": "devices", + "mqttPass": "devices", "scen": "1", "pushingboxid": "v7C133E426B0C69E", "weblogin": "admin", "webpass": "admin", "udponoff": "1", - "blink":"1" + "blink": "1" } \ No newline at end of file diff --git a/data/conf/100s.txt b/data/dev_conf.txt similarity index 100% rename from data/conf/100s.txt rename to data/dev_conf.txt diff --git a/data/conf/100c.txt b/data/dev_scen.txt similarity index 83% rename from data/conf/100c.txt rename to data/dev_scen.txt index 99beb0be..c943b43b 100644 --- a/data/conf/100c.txt +++ b/data/dev_scen.txt @@ -3,7 +3,7 @@ button 2 13 Прихожая Реле 0 2 button 3 14 Кухня Реле 0 3 pwm 1 3 Яркость#коредор: Реле 1023 4 pwm 2 4 Яркость#ванная: Реле 510 5 -analog adc 0 Аналоговый#вход Датчики fill-gauge 1 1023 1 1023 6 +analog adc 0 Аналоговый#вход Датчики fillgauge 1 1023 1 1023 6 logging adc 1 100 Аналоговый#вход Датчики 7 //Это демо конфигурация. В ней показано как связать кнопки c помощью сценариев diff --git a/data/set.device.json b/data/set.device.json index 7206dbc0..cea148d5 100644 --- a/data/set.device.json +++ b/data/set.device.json @@ -85,7 +85,7 @@ }, { "type": "file", - "state": "100с.txt", + "state": "dev_conf.txt", "style": "width:100%;height:350px", "title": "Сохранить", "action": "/set?devinit", @@ -104,7 +104,7 @@ }, { "type": "file", - "state": "100s.txt", + "state": "dev_scen.txt", "style": "width:100%;height:350px", "title": "Сохранить", "action": "/set?sceninit", diff --git a/data/widgets/any-data.json b/data/widgets/anydata.json similarity index 100% rename from data/widgets/any-data.json rename to data/widgets/anydata.json diff --git a/data/widgets/fill-gauge.json b/data/widgets/fillgauge.json similarity index 100% rename from data/widgets/fill-gauge.json rename to data/widgets/fillgauge.json diff --git a/include/Clock.h b/include/Clock.h index 6c6efd84..94377691 100644 --- a/include/Clock.h +++ b/include/Clock.h @@ -1,7 +1,99 @@ #pragma once -#include "Global.h" +#include "Utils/TimeUtils.h" +#include "Utils/PrintMessage.h" -void startTimeSync(); +#include "time.h" -void reconfigTime(); \ No newline at end of file +class Clock { + const char* MODULE = "Clock"; + + public: + Clock() : _timezone{0}, _ntp{}, _hasSynced{false}, _configured{false} { + } + + bool hasSync() { + if (!_hasSynced) { + startSync(); + } + return _hasSynced; + } + + void + + setNtpPool(String ntp) { + _ntp = ntp; + } + + void setTimezone(int timezone) { + _timezone = timezone; + } + + time_t getSystemTime() { + timeval tv{0, 0}; + timezone tz = getTimeZone(getBiasInMinutes()); + time_t epoch = 0; + if (gettimeofday(&tv, &tz) != -1) + epoch = tv.tv_sec; + return epoch; + } + + void startSync() { + if (!_configured) { + pm.info("sync to: " + _ntp + " time zone: " + String(_timezone)); + setupSntp(); + _configured = true; + } + _hasSynced = hasTimeSynced(); + if (_hasSynced) { + pm.info("synced " + getDateDigitalFormated() + " " + getTime()); + } else { + pm.error("failed to obtain"); + } + } + + void setupSntp() { + int tzs = getBiasInSeconds(); + int tzh = tzs / 3600; + tzs -= tzh * 3600; + int tzm = tzs / 60; + tzs -= tzm * 60; + + char tzstr[64]; + snprintf(tzstr, sizeof tzstr, "ESPUSER<%+d:%02d:%02d>", tzh, tzm, tzs); + pm.info(String(tzstr)); + configTime(tzstr, _ntp.c_str()); + } + // #ifdef ESP32 + // uint8_t i = 0; + // struct tm timeinfo; + // while (!getLocalTime(&timeinfo) && i <= 4) { + // Serial.print("."); + // i++; + // delay(1000); + // } + // #endif + private: + bool hasTimeSynced() { + unsigned long now = time(nullptr); + return now > millis(); + } + + int getBiasInSeconds() { + return getBiasInMinutes() * 60; + } + + int getBiasInMinutes() { + return _timezone * 60; + } + + const timezone getTimeZone(int minutes) { + return timezone{minutes, 0}; + } + + private: + int _timezone; + String _ntp; + bool _hasSynced; + bool _configured; +}; \ No newline at end of file diff --git a/include/CommonTypes.h b/include/CommonTypes.h index 7ad65e65..1050bcc9 100644 --- a/include/CommonTypes.h +++ b/include/CommonTypes.h @@ -41,7 +41,7 @@ enum LedStatus_t { }; enum ConfigType_t { - CT_MACRO, + CT_CONFIG, CT_SCENARIO }; diff --git a/include/Consts.h b/include/Consts.h index b4728fc0..7240c27c 100644 --- a/include/Consts.h +++ b/include/Consts.h @@ -10,6 +10,11 @@ // 1000 * 60 * 60 * 2 #define TELEMETRY_UPDATE_INTERVAL 0 +#define DEVICE_CONFIG_FILE "dev_conf.txt" +#define DEVICE_SCENARIO_FILE "dev_scen.txt" +#define DEFAULT_PRESET 100 +#define DEFAULT_SCENARIO 100 + /* * Optional */ diff --git a/include/Global.h b/include/Global.h index 50ab2423..f236d5af 100644 --- a/include/Global.h +++ b/include/Global.h @@ -21,7 +21,6 @@ #include "Utils\JsonUtils.h" #include "Utils\StringUtils.h" #include "Utils\SysUtils.h" -#include "Utils\TimeUtils.h" #include "Utils\PrintMessage.h" #include "Utils\WiFiUtils.h" @@ -45,6 +44,8 @@ extern AsyncWebSocket ws; //extern AsyncEventSource events; #endif +extern Clock* rtc; + extern TickerScheduler ts; extern WiFiClient espClient; @@ -107,6 +108,7 @@ extern boolean mqttParamsChanged; extern boolean udp_data_parse; extern boolean mqtt_send_settings_to_udp; extern boolean i2c_scanning; +extern boolean fscheck_flag; extern int sensors_reading_map[15]; @@ -143,19 +145,15 @@ extern void mqttOrderSend(); extern void httpOrderSend(); extern void firmwareVersion(); extern void firmwareUpdate(); -extern void Scenario_init(); -extern void txtExecution(String file); -extern void stringExecution(String str); - -// i2c_bu -extern void do_i2c_scanning(); -extern String i2c_scan(); +extern void loadScenario(); +extern void fileExecute(const String& filename); +extern void stringExecute(String& cmdStr); // Init extern void loadConfig(); extern void All_init(); extern void statistics_init(); -extern void Scenario_init(); +extern void loadScenario(); extern void Device_init(); extern void prsets_init(); extern void up_time(); @@ -168,7 +166,6 @@ extern void choose_log_date_and_send(); // Main extern void setChipId(); -extern void printMemoryStatus(String text); extern void saveConfig(); extern String getURL(const String& urls); @@ -232,9 +229,10 @@ extern int readTimer(int number); extern void init_updater(); // widget -extern void createWidget(String widget_name, String page_name, String page_number, String file, String topic); + +extern void createWidgetByType(String widget_name, String page_name, String page_number, String file, String topic); extern void createWidgetParam(String widget_name, String page_name, String page_number, String file, String topic, String name1, String param1, String name2, String param2, String name3, String param3); -extern void createWidgetByType(String widget_name, String page_name, String page_number, String type, String topik); +extern void createWidget(String widget_name, String page_name, String page_number, String type, String topik); extern void createChart(String widget_name, String page_name, String page_number, String file, String topic, String maxCount); // PushingBox @@ -245,9 +243,6 @@ extern void UDP_init(); extern void do_udp_data_parse(); extern void do_mqtt_send_settings_to_udp(); -// WebServer -extern void Web_server_init(); - // iot_firmware extern void addCommandLoop(const String& cmdStr); extern void loopSerial(); diff --git a/include/Utils/FileUtils.h b/include/Utils/FileUtils.h index da01fb56..f4840f9c 100644 --- a/include/Utils/FileUtils.h +++ b/include/Utils/FileUtils.h @@ -20,37 +20,37 @@ bool fileSystemInit(); /* * Удалить файл */ -void removeFile(const String filename); +void removeFile(const String& filename); /* * Открыть файл на позиции */ -File seekFile(const String filename, size_t position = 0); +File seekFile(const String& filename, size_t position = 0); /* * Чтение строки из файла * возвращает стоку из файла в которой есть искомое слово found */ -String readFileString(const String filename, const String to_find); +const String readFileString(const String& filename, const String& to_find); /* * Добовление строки в файл */ -String addFile(const String filename, const String str); +const String addFile(const String& filename, const String& str); /* * Запись строки в файл */ -String writeFile(const String filename, const String str); +const String writeFile(const String& filename, const String& str); /* * Чтение файла в строку */ -String readFile(const String filename, size_t max_size); +const String readFile(const String& filename, size_t max_size); /* * Размер файла */ -String getFileSize(const String filename); +const String getFileSize(const String& filename); -bool copyFile(const String src, const String dst, bool overwrite = true); \ No newline at end of file +bool copyFile(const String& src, const String& dst, bool overwrite = true); \ No newline at end of file diff --git a/include/Utils/JsonUtils.h b/include/Utils/JsonUtils.h index 253bdc9b..762fc286 100644 --- a/include/Utils/JsonUtils.h +++ b/include/Utils/JsonUtils.h @@ -11,3 +11,5 @@ String jsonWriteStr(String& json, String name, String volume); String jsonWriteInt(String& json, String name, int volume); String jsonWriteFloat(String& json, String name, float volume); + +boolean jsonReadBool(String& json, String name); \ No newline at end of file diff --git a/include/Utils/PresetUtils.h b/include/Utils/PresetUtils.h index 552da5ca..9366d515 100644 --- a/include/Utils/PresetUtils.h +++ b/include/Utils/PresetUtils.h @@ -4,8 +4,7 @@ #include "CommonTypes.h" -const String getPresetFile(uint8_t preset, ConfigType_t type); +const String getConfigFile(uint8_t preset, ConfigType_t type); const String getItemName(Item_t item); -const Item_t getPresetItem(uint8_t preset); diff --git a/include/Utils/PrintMessage.h b/include/Utils/PrintMessage.h index 1434907a..ec3ab5bb 100644 --- a/include/Utils/PrintMessage.h +++ b/include/Utils/PrintMessage.h @@ -14,11 +14,11 @@ class PrintMessage { _module = module; } - void error(const String str) { + void error(const String& str) { print(EL_ERROR, str); } - void info(const String str) { + void info(const String& str) { print(EL_INFO, str); } diff --git a/include/Utils/SysUtils.h b/include/Utils/SysUtils.h index a6bdbe27..12ceb5fe 100644 --- a/include/Utils/SysUtils.h +++ b/include/Utils/SysUtils.h @@ -4,6 +4,6 @@ const String getChipId(); -void printMemoryStatus(String text = ""); +const String printMemoryStatus(); -String getHeapStats(); +const String getHeapStats(); diff --git a/include/Utils/TimeUtils.h b/include/Utils/TimeUtils.h index 82337b34..658634d9 100644 --- a/include/Utils/TimeUtils.h +++ b/include/Utils/TimeUtils.h @@ -35,12 +35,6 @@ int timeToMin(String Time); const String prettyMillis(unsigned long time_ms = millis()); -int timeZoneInSeconds(const byte timeZone); - -bool hasTimeSynced(); - -int getBiasInSeconds(); - /* * Время (мс) прошедщее с @simce */ diff --git a/include/Utils/i2c_bus.h b/include/Utils/i2c_bus.h new file mode 100644 index 00000000..c8d17aae --- /dev/null +++ b/include/Utils/i2c_bus.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +void do_i2c_scanning(); + +const String i2c_scan(); \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 7815fdfc..ee5d86e3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -36,7 +36,8 @@ lib_deps = [env:esp8266] platform = https://github.com/platformio/platform-espressif8266.git -build_flags = ${env.build_flags} -D=${PIOENV} +build_flags = ${env.build_flags} -D=${PIOENV} +##-DCORE_DEBUG_LEVEL=5 board = nodemcuv2 monitor_filters = esp8266_exception_decoder monitor_speed = 115200 @@ -51,3 +52,4 @@ lib_deps = DHT sensor library for ESPx Adafruit BMP280 Library Adafruit BME280 Library + diff --git a/src/Clock.cpp b/src/Clock.cpp deleted file mode 100644 index bfc0e005..00000000 --- a/src/Clock.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "Clock.h" - -#include "Utils/TimeUtils.h" - -static const char* MODULE = "Clock"; - -void startTimeSync() { - if (!hasTimeSynced()) { - pm.info("Start syncing"); - reconfigTime(); - } -} - -void setupSntp() { - int tzs = getBiasInSeconds(); - int tzh = tzs / 3600; - tzs -= tzh * 3600; - int tzm = tzs / 60; - tzs -= tzm * 60; - - String ntp = jsonReadStr(configSetupJson, "ntp"); - pm.info("Setup ntp: " + ntp); - char tzstr[64]; - snprintf(tzstr, sizeof tzstr, "ESPUSER<%+d:%02d:%02d>", tzh, tzm, tzs); - return configTime(tzstr, ntp.c_str(), "pool.ntp.org", "time.nist.gov"); -} - -void reconfigTime() { -#ifdef ESP32 - uint8_t i = 0; - struct tm timeinfo; - while (!getLocalTime(&timeinfo) && i <= 4) { - Serial.print("."); - i++; - delay(1000); - } -#endif - -#ifdef ESP8266 - setupSntp(); - uint8_t i = 0; - while (!hasTimeSynced() && i < 4) { - Serial.print("."); - i++; - delay(300); - } -#endif - - if (getTimeUnix() != "failed") { - pm.info("Time synced " + getDateDigitalFormated() + " " + getTime()); - } else { - pm.error("Failed to obtain"); - } -} diff --git a/src/Cmd.cpp b/src/Cmd.cpp index f1a2ee61..389a4529 100644 --- a/src/Cmd.cpp +++ b/src/Cmd.cpp @@ -13,6 +13,8 @@ Servo myServo1; Servo myServo2; SoftwareSerial *mySerial = nullptr; +void getData(); + void CMD_init() { sCmd.addCommand("button", button); sCmd.addCommand("buttonSet", buttonSet); @@ -97,47 +99,50 @@ void CMD_init() { sCmd.addCommand("firmwareUpdate", firmwareUpdate); sCmd.addCommand("firmwareVersion", firmwareVersion); + sCmd.addCommand("getData", getData); + handle_time_init(); } //========================================================================================================== //==========================================Модуль кнопок=================================================== void button() { - String button_number = sCmd.next(); - String button_param = sCmd.next(); - String widget_name = sCmd.next(); - String page_name = sCmd.next(); - String start_state = sCmd.next(); - String page_number = sCmd.next(); + pm.info("create 'button'"); + String number = sCmd.next(); + String param = sCmd.next(); + String widget = sCmd.next(); + String page = sCmd.next(); + String state = sCmd.next(); + String pageNumber = sCmd.next(); - jsonWriteStr(configOptionJson, "button_param" + button_number, button_param); - jsonWriteStr(configLiveJson, "button" + button_number, start_state); + jsonWriteStr(configOptionJson, "button_param" + number, param); + jsonWriteStr(configLiveJson, "button" + number, state); - if (isDigitStr(button_param)) { - pinMode(button_param.toInt(), OUTPUT); - digitalWrite(button_param.toInt(), start_state.toInt()); + if (isDigitStr(param)) { + pinMode(param.toInt(), OUTPUT); + digitalWrite(param.toInt(), state.toInt()); } - if (button_param == "scen") { - jsonWriteStr(configSetupJson, "scen", start_state); - Scenario_init(); + if (param == "scen") { + jsonWriteStr(configSetupJson, "scen", state); + loadScenario(); saveConfig(); } - if (button_param.indexOf("line") != -1) { - String str = button_param; - while (str.length() != 0) { + if (param.indexOf("line") != -1) { + String str = param; + while (str.length()) { if (str == "") return; String tmp = selectToMarker(str, ","); //line1, String number = deleteBeforeDelimiter(tmp, "e"); //1, number.replace(",", ""); Serial.println(number); int number_int = number.toInt(); - scenario_line_status[number_int] = start_state.toInt(); + scenario_line_status[number_int] = state.toInt(); str = deleteBeforeDelimiter(str, ","); } } - createWidget(widget_name, page_name, page_number, "widgets/widget.toggle.json", "button" + button_number); + createWidget(widget, page, pageNumber, "toggle", "button" + number); } void buttonSet() { @@ -151,7 +156,7 @@ void buttonSet() { if (button_param == "scen") { jsonWriteStr(configSetupJson, "scen", button_state); - Scenario_init(); + loadScenario(); saveConfig(); } @@ -187,6 +192,7 @@ void buttonChange() { } order_loop += "buttonSet " + button_number + " " + current_state + ","; jsonWriteStr(configLiveJson, "button" + button_number, current_state); + MqttClient::publishStatus("button" + button_number, current_state); } @@ -221,7 +227,7 @@ void pwm() { //analogWriteFreq(32000); jsonWriteStr(configLiveJson, "pwm" + pwm_number, start_state); - createWidget(widget_name, page_name, page_number, "widgets/widget.range.json", "pwm" + pwm_number); + createWidget(widget_name, page_name, page_number, "range", "pwm" + pwm_number); } void pwmSet() { @@ -290,7 +296,7 @@ void inputDigit() { String start_state = sCmd.next(); String page_number = sCmd.next(); jsonWriteStr(configLiveJson, "digit" + number, start_state); - createWidget(widget_name, page_name, page_number, "widgets/widget.inputNum.json", "digit" + number); + createWidget(widget_name, page_name, page_number, "inputNum", "digit" + number); } void digitSet() { @@ -312,7 +318,7 @@ void inputTime() { String start_state = sCmd.next(); String page_number = sCmd.next(); jsonWriteStr(configLiveJson, "time" + number, start_state); - createWidget(widget_name, page_name, page_number, "widgets/widget.inputTime.json", "time" + number); + createWidget(widget_name, page_name, page_number, "inputTime", "time" + number); } void timeSet() { @@ -342,7 +348,7 @@ void text() { String page_name = sCmd.next(); String page_number = sCmd.next(); - createWidget(widget_name, page_name, page_number, "widgets/widget.anyData.json", "text" + number); + createWidget(widget_name, page_name, page_number, "anydata", "text" + number); } void textSet() { @@ -475,7 +481,7 @@ void servo_() { jsonWriteStr(configLiveJson, "servo" + servo_number, start_state); - createWidgetParam(widget_name, page_name, page_number, "widgets/widget.range.json", "servo" + servo_number, "min", min_value, "max", max_value, "k", "1"); + createWidgetParam(widget_name, page_name, page_number, "range", "servo" + servo_number, "min", min_value, "max", max_value, "k", "1"); } void servoSet() { @@ -545,6 +551,14 @@ void serialBegin() { }); } +void getData() { + String param = sCmd.next(); + String res = param.length() ? jsonReadStr(configLiveJson, param) : configLiveJson; + if (term) { + term->println(res.c_str()); + } +} + void serialWrite() { String payload = sCmd.next(); if (term) { @@ -576,11 +590,13 @@ void firmwareUpdate() { } void firmwareVersion() { - String widget_name = sCmd.next(); - String page_name = sCmd.next(); - String page_number = sCmd.next(); + String widget = sCmd.next(); + String page = sCmd.next(); + String pageNumber = sCmd.next(); + jsonWriteStr(configLiveJson, "firmver", FIRMWARE_VERSION); - createWidgetByType(widget_name, page_name, page_number, "any-data", "firmver"); + + createWidget(widget, page, pageNumber, "anydata", "firmver"); } void addCommandLoop(const String &cmdStr) { @@ -594,35 +610,33 @@ void loopCmd() { if (order_loop.length()) { String tmp = selectToMarker(order_loop, ","); //выделяем первую команду rel 5 1, sCmd.readStr(tmp); //выполняем - Serial.println("[ORDER] => " + order_loop); + pm.info("do: " + order_loop); order_loop = deleteBeforeDelimiter(order_loop, ","); //осекаем } } -void txtExecution(String file) { - String command_all = readFile(file, 2048) + "\r\n"; +void fileExecute(const String &filename) { + String cmdStr = readFile(filename, 2048); + cmdStr += "\r\n"; + cmdStr.replace("\r\n", "\n"); + cmdStr.replace("\r", "\n"); - command_all.replace("\r\n", "\n"); - command_all.replace("\r", "\n"); - - while (command_all.length() != 0) { - String tmp = selectToMarker(command_all, "\n"); - sCmd.readStr(tmp); - command_all = deleteBeforeDelimiter(command_all, "\n"); + while (cmdStr.length() != 0) { + String buf = selectToMarker(cmdStr, "\n"); + sCmd.readStr(buf); + cmdStr = deleteBeforeDelimiter(cmdStr, "\n"); } - command_all = ""; } -void stringExecution(String str) { - str = str + "\r\n"; +void stringExecute(String &cmdStr) { + cmdStr = cmdStr + "\r\n"; - str.replace("\r\n", "\n"); - str.replace("\r", "\n"); + cmdStr.replace("\r\n", "\n"); + cmdStr.replace("\r", "\n"); - while (str.length() != 0) { - String tmp = selectToMarker(str, "\n"); - sCmd.readStr(tmp); - - str = deleteBeforeDelimiter(str, "\n"); + while (cmdStr.length()) { + String buf = selectToMarker(cmdStr, "\n"); + sCmd.readStr(buf); + cmdStr = deleteBeforeDelimiter(cmdStr, "\n"); } } \ No newline at end of file diff --git a/src/Global.cpp b/src/Global.cpp index bbd5610b..aec0b751 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -5,6 +5,8 @@ AsyncWebSocket ws; //AsyncEventSource events; #endif +Clock* rtc; + TickerScheduler ts(TEST + 1); WiFiClient espClient; @@ -17,8 +19,6 @@ AsyncWebServer server(80); DallasTemperature sensors; - - /* * Global vars */ @@ -73,3 +73,4 @@ boolean mqttParamsChanged = false; boolean udp_data_parse = false; boolean mqtt_send_settings_to_udp = false; boolean i2c_scanning = false; +boolean fscheck_flag = false; diff --git a/src/Init.cpp b/src/Init.cpp index f2dc3952..e5215f0a 100644 --- a/src/Init.cpp +++ b/src/Init.cpp @@ -19,7 +19,7 @@ void loadConfig() { void All_init() { Device_init(); - Scenario_init(); + loadScenario(); Timer_countdown_init(); } @@ -57,17 +57,17 @@ void Device_init() { #ifdef LAYOUT_IN_RAM all_widgets = ""; #else - removeFile("/layout.txt"); + removeFile(String("layout.txt")); #endif - txtExecution("100с.txt"); + fileExecute(String(DEVICE_CONFIG_FILE)); //outcoming_date(); } //-------------------------------сценарии----------------------------------------------------- -void Scenario_init() { +void loadScenario() { if (jsonReadStr(configSetupJson, "scen") == "1") { - scenario = readFile("100s.txt", 2048); + scenario = readFile(String(DEVICE_SCENARIO_FILE), 2048); } } @@ -107,20 +107,15 @@ void handle_statistics() { urls += "iot-manager_esp32"; #endif urls += "&"; - //----------------------------------------------------------------- #ifdef ESP8266 urls += ESP.getResetReason(); - //Serial.println(ESP.getResetReason()); #endif #ifdef ESP32 urls += "Power on"; #endif urls += "&"; - //----------------------------------------------------------------- urls += "ver: "; urls += String(FIRMWARE_VERSION); - //----------------------------------------------------------------- String stat = getURL(urls); - //Serial.println(stat); } } \ No newline at end of file diff --git a/src/Logging.cpp b/src/Logging.cpp index c6c40454..00035aa9 100644 --- a/src/Logging.cpp +++ b/src/Logging.cpp @@ -5,6 +5,8 @@ void sendLogData(String file, String topic); +static const char* MODULE = "Log"; + #ifdef LOGGING_ENABLED //===============================================Логирование============================================================ //logging temp1 1 10 Температура Датчики 2 @@ -17,15 +19,18 @@ void logging() { 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 - createChart(widget_name, page_name, page_number, "widgets/widget.chart.json", value_name + "_ch", maxCount); //создаем график в приложении с топиком _ch /prefix/3234045-1589487/value_name_ch + 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)); - Serial.println("[I] LOGGING for sensor '" + tmp_buf_1 + "' done"); + pm.info("logging for " + tmp_buf_1 + " done"); }, nullptr, false); } @@ -34,7 +39,7 @@ void logging() { 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)); - Serial.println("[I] LOGGING for sensor '" + tmp_buf_2 + "' done"); + pm.info("logging for " + tmp_buf_2 + " done"); }, nullptr, false); } @@ -43,7 +48,7 @@ void logging() { 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)); - Serial.println("[I] LOGGING for sensor '" + tmp_buf_3 + "' done"); + pm.info("logging for " + tmp_buf_3 + " done"); }, nullptr, false); } @@ -52,7 +57,7 @@ void logging() { 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)); - Serial.println("[I] LOGGING for sensor '" + tmp_buf_4 + "' done"); + pm.info("logging for " + tmp_buf_4 + " done"); }, nullptr, false); } @@ -61,7 +66,7 @@ void logging() { 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)); - Serial.println("[I] LOGGING for sensor '" + tmp_buf_5 + "' done"); + pm.info("logging for " + tmp_buf_5 + " done"); }, nullptr, false); } @@ -74,10 +79,10 @@ void deleteOldDate(const String filename, size_t max_lines_cnt, String date_to_a String log_date = readFile(filename, 5120); size_t lines_cnt = itemsCount(log_date, "\r\n"); - Serial.printf("[I] log %s (%d lines)\n", filename.c_str(), lines_cnt); + pm.info("log " + filename + " (" + String(lines_cnt, DEC) + ")"); if ((lines_cnt > max_lines_cnt + 1) || !lines_cnt) { - removeFile("/" + filename); + removeFile(filename); lines_cnt = 0; } @@ -92,7 +97,6 @@ void deleteOldDate(const String filename, size_t max_lines_cnt, String date_to_a addFile(filename, getTimeUnix() + " " + date_to_add); } } - log_date = ""; } //=========================================Выбор какие данные отправлять================================================================== @@ -103,19 +107,18 @@ void choose_log_date_and_send() { sendLogData("log." + tmp + ".txt", tmp + "_ch"); all_line = deleteBeforeDelimiter(all_line, ","); } - all_line = ""; } //=========================================Отправка данных=================================================================================== void sendLogData(String file, String topic) { - String log_date = readFile(file, 5000); - if (log_date != "Failed") { + 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() != 0) { + while (log_date.length()) { String tmp = selectToMarker(log_date, "\n"); log_date = deleteBeforeDelimiter(log_date, "\n"); unix_time = selectToMarker(tmp, " "); @@ -133,40 +136,18 @@ void sendLogData(String file, String topic) { value = ""; log_date = ""; json_array = "{\"status\":[" + json_array + "]}"; - Serial.println(json_array); - + pm.info(json_array); + MqttClient::publishChart(topic, json_array); - json_array = ""; - printMemoryStatus("[I] send log date"); } } -/* - //---------------------------------------------- - File configFile = SPIFFS.open("/" + file, "r"); - if (!configFile) { - return; - } - configFile.seek(0, SeekSet); //поставим курсор в начало файла - while (configFile.position() != configFile.size()) { - String tmp = configFile.readStringUntil('\r\n'); - String unix_time = selectToMarker (tmp, " "); - String value = deleteBeforeDelimiter(tmp, " "); - String final_line = "{\"status\":{\"x\":" + unix_time + ",\"y1\":" + value + "}}"; - //Serial.println(final_line); - sendCHART(topic, final_line); - } - getMemoryLoad("[I] after send log date"); -*/ - -//=========================================Очистка данных=================================================================================== void clean_log_date() { String all_line = logging_value_names_list; - while (all_line.length() != 0) { + while (all_line.length()) { String tmp = selectToMarker(all_line, ","); - removeFile("/log." + tmp + ".txt"); + removeFile("log." + tmp + ".txt"); all_line = deleteBeforeDelimiter(all_line, ","); } - all_line = ""; } #endif \ No newline at end of file diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index df61092d..31d48979 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -29,7 +29,7 @@ void init() { if (!just_load) mqtt_lost_error++; } } else { - pm.error("WiFi connection lost"); + pm.error("connection lost"); ts.remove(WIFI_MQTT_CONNECTION_CHECK); wifi_lost_error++; startAPMode(); @@ -86,7 +86,7 @@ boolean connect() { mqttRootDevice = mqttPrefix + "/" + chipId; pm.info("broker " + addr + ":" + String(port, DEC)); - pm.info("root " + mqttRootDevice); + pm.info("topic " + mqttRootDevice); setLedStatus(LED_FAST); mqtt.setServer(addr.c_str(), port); @@ -115,10 +115,8 @@ void handleSubscribedUpdates(char* topic, uint8_t* payload, size_t length) { payloadStr += (char)payload[i]; } pm.info(payloadStr); - - if (payloadStr == "HELLO") { - //данные которые отправляем при подключении или отбновлении страницы - pm.info("Send web page updates"); + if (payloadStr.startsWith("HELLO")) { + pm.info("Full update"); publishWidgets(); publishState(); #ifdef LOGGING_ENABLED @@ -148,11 +146,11 @@ void handleSubscribedUpdates(char* topic, uint8_t* payload, size_t length) { upgrade = true; } } else if (topicStr.indexOf("devc")) { - writeFile("100с.txt", payloadStr); + writeFile(String(DEVICE_CONFIG_FILE), payloadStr); Device_init(); } else if (topicStr.indexOf("devs")) { - writeFile("100s.txt", payloadStr); - Scenario_init(); + writeFile(String(DEVICE_SCENARIO_FILE), payloadStr); + loadScenario(); } } @@ -225,13 +223,14 @@ void publishWidgets() { #ifndef LAYOUT_IN_RAM void publishWidgets() { - auto file = seekFile("/layout.txt"); + auto file = seekFile("layout.txt"); if (!file) { + pm.error("on seek layout.txt"); return; } - while (file.position() != file.size()) { + while (file.available()) { String payload = file.readStringUntil('\n'); - pm.info("publish: " + payload); + pm.info("widgets: " + payload); publishData("config", payload); } file.close(); @@ -243,14 +242,13 @@ void publishState() { // {"name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1"} // "name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1" // "name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1", - String current_config = configLiveJson; - printMemoryStatus("[I] after send all date"); - current_config.replace("{", ""); - current_config.replace("}", ""); - current_config += ","; + String str = configLiveJson; + str.replace("{", ""); + str.replace("}", ""); + str += ","; - while (current_config.length()) { - String tmp = selectToMarker(current_config, ","); + while (str.length()) { + String tmp = selectToMarker(str, ","); String topic = selectToMarker(tmp, ":"); topic.replace("\"", ""); @@ -261,7 +259,7 @@ void publishState() { if (topic != "name" && topic != "lang" && topic != "ip" && topic.indexOf("_in") < 0) { publishStatus(topic, state); } - current_config = deleteBeforeDelimiter(current_config, ","); + str = deleteBeforeDelimiter(str, ","); } } diff --git a/src/Scenario.cpp b/src/Scenario.cpp index 67fa00fa..849ba2b8 100644 --- a/src/Scenario.cpp +++ b/src/Scenario.cpp @@ -53,7 +53,7 @@ void loopScenario() { if (flag) { tmp = deleteBeforeDelimiter(tmp, "\n"); //удаляем строку самого сценария оставляя только команды - stringExecution(tmp); //выполняем все команды + stringExecute(tmp); //выполняем все команды Serial.println("[SCENARIO] '" + condition + "'"); //Serial.println(" " + tmp); diff --git a/src/Sensors.cpp b/src/Sensors.cpp index 6f0b2f20..c4503d39 100644 --- a/src/Sensors.cpp +++ b/src/Sensors.cpp @@ -81,7 +81,7 @@ void sensors_init() { //========================================================================================================================================= //=========================================Модуль измерения уровня в баке================================================================== #ifdef LEVEL_ENABLED -//levelPr p 14 12 Вода#в#баке,#% Датчики fill-gauge 125 20 1 +//levelPr p 14 12 Вода#в#баке,#% Датчики fillgauge 125 20 1 void levelPr() { String value_name = sCmd.next(); String trig = sCmd.next(); @@ -102,7 +102,7 @@ void levelPr() { createWidgetByType(widget_name, page_name, page_number, type, value_name); sensors_reading_map[0] = 1; } -//ultrasonicCm cm 14 12 Дистанция,#см Датчики fill-gauge 1 +//ultrasonicCm cm 14 12 Дистанция,#см Датчики fillgauge 1 void ultrasonicCm() { String value_name = sCmd.next(); String trig = sCmd.next(); @@ -399,7 +399,7 @@ void dhtC() { String widget_name = sCmd.next(); String page_name = sCmd.next(); String page_number = sCmd.next(); - createWidgetByType(widget_name, page_name, page_number, "any-data", "dhtComfort"); + createWidgetByType(widget_name, page_name, page_number, "anydata", "dhtComfort"); sensors_reading_map[7] = 1; } @@ -459,7 +459,7 @@ void dhtD() { String widget_name = sCmd.next(); String page_name = sCmd.next(); String page_number = sCmd.next(); - createWidgetByType(widget_name, page_name, page_number, "any-data", "dhtDewpoint"); + createWidgetByType(widget_name, page_name, page_number, "anydata", "dhtDewpoint"); sensors_reading_map[8] = 1; } diff --git a/src/Upgrade.cpp b/src/Upgrade.cpp index 0c2ab7c8..51dafbd5 100644 --- a/src/Upgrade.cpp +++ b/src/Upgrade.cpp @@ -1,4 +1,5 @@ #include "Global.h" + void init_updater() { #ifdef ESP8266 if (WiFi.status() == WL_CONNECTED) last_version = getURL("http://91.204.228.124:1100/update/esp8266/version.txt"); @@ -28,8 +29,9 @@ void upgrade_firmware() { String scenario_for_update; String config_for_update; String configSetup_for_update; - scenario_for_update = readFile("100s.txt", 4000); - config_for_update = readFile("100с.txt", 4000); + + scenario_for_update = readFile(String(DEVICE_SCENARIO_FILE), 4000); + config_for_update = readFile(String(DEVICE_CONFIG_FILE), 4000); configSetup_for_update = configSetupJson; Serial.println("Start upgrade SPIFFS, please wait..."); @@ -46,8 +48,8 @@ void upgrade_firmware() { #endif if (ret == HTTP_UPDATE_OK) { - writeFile("100s.txt", scenario_for_update); - writeFile("100с.txt", config_for_update); + writeFile(String(DEVICE_SCENARIO_FILE), scenario_for_update); + writeFile(String(DEVICE_CONFIG_FILE), config_for_update); writeFile("config.json", configSetup_for_update); saveConfig(); diff --git a/src/Utils/FileUtils.cpp b/src/Utils/FileUtils.cpp index 8f98c472..16975564 100644 --- a/src/Utils/FileUtils.cpp +++ b/src/Utils/FileUtils.cpp @@ -15,27 +15,34 @@ bool fileSystemInit() { return true; } -void removeFile(const String filename) { - if (!LittleFS.remove(filepath(filename))) { - pm.error("remove " + filename); +void removeFile(const String& filename) { + String path = filepath(filename); + if (LittleFS.exists(path)) { + if (!LittleFS.remove(path)) { + pm.error("remove " + path); + } + } else { + pm.info("not exist" + path); } } -File seekFile(const String filename, size_t position) { - auto file = LittleFS.open(filepath(filename), "r"); +File seekFile(const String& filename, size_t position) { + String path = filepath(filename); + auto file = LittleFS.open(path, "r"); if (!file) { - pm.error("open " + filename); + pm.error("open " + path); } // поставим курсор в начало файла file.seek(position, SeekSet); return file; } -String readFileString(const String filename, const String to_find) { - String res = "Failed"; - auto file = LittleFS.open(filepath(filename), "r"); +const String readFileString(const String& filename, const String& to_find) { + String path = filepath(filename); + String res = "failed"; + auto file = LittleFS.open(path, "r"); if (!file) { - return "Failed"; + return "failed"; } if (file.find(to_find.c_str())) { res = file.readStringUntil('\n'); @@ -44,19 +51,21 @@ String readFileString(const String filename, const String to_find) { return res; } -String addFile(const String filename, const String str) { - auto file = LittleFS.open(filepath(filename), "a"); +const String addFile(const String& filename, const String& str) { + String path = filepath(filename); + auto file = LittleFS.open(path, "a"); if (!file) { - return "Failed"; + return "failed"; } file.println(str); file.close(); - return "Sucсess"; + return "sucсess"; } -bool copyFile(const String src, const String dst, bool overwrite) { +bool copyFile(const String& src, const String& dst, bool overwrite) { String srcPath = filepath(src); String dstPath = filepath(dst); + pm.info("copy " + srcPath + " to " + dstPath); if (!LittleFS.exists(srcPath)) { pm.error("not exist: " + srcPath); return false; @@ -81,35 +90,38 @@ bool copyFile(const String src, const String dst, bool overwrite) { return true; } -String writeFile(const String filename, const String str) { - auto file = LittleFS.open(filepath(filename), "w"); +const String writeFile(const String& filename, const String& str) { + String path = filepath(filename); + auto file = LittleFS.open(path, "w"); if (!file) { - return "Failed"; + return "failed"; } file.print(str); file.close(); - return "Sucсess"; + return "sucсess"; } -String readFile(const String filename, size_t max_size) { - auto file = LittleFS.open(filepath(filename), "r"); +const String readFile(const String& filename, size_t max_size) { + String path = filepath(filename); + auto file = LittleFS.open(path, "r"); if (!file) { - return "Failed"; + return "failed"; } size_t size = file.size(); if (size > max_size) { file.close(); - return "Large"; + return "large"; } String temp = file.readString(); file.close(); return temp; } -String getFileSize(const String filename) { - auto file = LittleFS.open(filepath(filename), "r"); +const String getFileSize(const String filename) { + String filepath(filename); + auto file = LittleFS.open(filepath, "r"); if (!file) { - return "Failed"; + return "failed"; } size_t size = file.size(); file.close(); diff --git a/src/Utils/JsonUtils.cpp b/src/Utils/JsonUtils.cpp index 3adeb6fd..d814c409 100644 --- a/src/Utils/JsonUtils.cpp +++ b/src/Utils/JsonUtils.cpp @@ -8,6 +8,12 @@ String jsonReadStr(String& json, String name) { return root[name].as(); } +boolean jsonReadBool(String& json, String name) { + DynamicJsonBuffer jsonBuffer; + JsonObject& root = jsonBuffer.parseObject(json); + return root[name].as(); +} + int jsonReadInt(String& json, String name) { DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject(json); diff --git a/src/Utils/PresetUtils.cpp b/src/Utils/PresetUtils.cpp index 50e0da66..f82a7e40 100644 --- a/src/Utils/PresetUtils.cpp +++ b/src/Utils/PresetUtils.cpp @@ -1,54 +1,9 @@ #include "Utils/PresetUtils.h" -static const char* item_names[NUM_ITEMS] = {"relay", "pwm", - "dht11", "dht22", "analog", - "bmp280", "bme280", "dallas", - "termostat", "ultrasonic", - "motion", "stepper", - "servo", "firmware"}; +static const char* config_file_fmt PROGMEM = "/conf/%s%03d.txt"; -static const char* config_file_fmt = "/conf/%03d%s.txt"; - -const String getPresetFile(uint8_t preset, ConfigType_t type) { +const String getConfigFile(uint8_t preset, ConfigType_t type) { char buf[64]; - sprintf(buf, config_file_fmt, preset, type == CT_MACRO ? "c" : "s"); + sprintf_P(buf, config_file_fmt, (type == CT_CONFIG) ? "c" : "s", preset); return String(buf); -} - -const String getItemName(Item_t item) { - return String(item_names[item]); -} - -const Item_t getPresetItem(uint8_t num) { - Item_t res = NUM_ITEMS; - if (num >= 1 && num <= 7) { - res = RELAY; - } else if (num == 8) { - res = PWM; - } else if (num == 9) { - res = DHT11; - } else if (num == 10) { - res = DHT22; - } else if (num == 11) { - res = ANALOG; - } else if (num == 12) { - res = BMP280; - } else if (num == 13) { - res = BME280; - } else if (num == 14) { - res = DALLAS; - } else if (num == 15) { - res = TERMOSTAT; - } else if (num == 16) { - res = ULTRASONIC; - } else if (num >= 17 || num <= 18) { - res = MOTION; - } else if (num == 19) { - res = STEPPER; - } else if (num == 20) { - res = SERVO; - } else if (num == 21) { - res = FIRMWARE; - } - return res; } \ No newline at end of file diff --git a/src/Utils/SysUtils.cpp b/src/Utils/SysUtils.cpp index 51b32dc4..e67b9b02 100644 --- a/src/Utils/SysUtils.cpp +++ b/src/Utils/SysUtils.cpp @@ -23,25 +23,24 @@ static uint32_t total_memory = 52864; static uint32_t total_memory = 362868; #endif -void printMemoryStatus(String text) { +const String printMemoryStatus() { uint32_t free = ESP.getFreeHeap(); uint32_t used = total_memory - free; uint32_t memory_load = (used * 100) / total_memory; - if (text) { - Serial.print(text); - } - Serial.printf(" used: %d%% free: %s\n", memory_load, prettyBytes(free).c_str()); + char buf[64]; + sprintf(buf, "used: %d%% free: %s", memory_load, getHeapStats().c_str()); + return String(buf); } #ifdef ESP8266 -String getHeapStats() { +const String getHeapStats() { uint32_t free; uint16_t max; uint8_t frag; ESP.getHeapStats(&free, &max, &frag); String buf; buf += prettyBytes(free); - buf += " "; + buf += " frag: "; buf += frag; buf += '%'; return buf; diff --git a/src/Utils/TimeUtils.cpp b/src/Utils/TimeUtils.cpp index 72eb4c9b..59aa09cc 100644 --- a/src/Utils/TimeUtils.cpp +++ b/src/Utils/TimeUtils.cpp @@ -6,33 +6,17 @@ #define ONE_MINUTE_s 60 #define ONE_HOUR_s 60 * ONE_MINUTE_s -int getBiasInSeconds() { - return 3600 * jsonReadStr(configSetupJson, "timezone").toInt(); -} - -int getBiasInMinutes() { - return getBiasInSeconds() / 60; -} - -const timezone getTimeZone() { - return timezone{getBiasInMinutes(), 0}; -} - -time_t getSystemTime() { - timeval tv{0, 0}; - timezone tz = getTimeZone(); - time_t epoch = 0; - if (gettimeofday(&tv, &tz) != -1) - epoch = tv.tv_sec; - return epoch; -} - -bool hasTimeSynced() { - time_t now = time(nullptr); - return now > millis(); -} - +time_t t; +struct tm* tm; +static const char* wd[7] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat"}; String getTimeUnix() { + t = time(NULL); + tm = localtime(&t); + Serial.printf("%04d/%02d/%02d(%s) %02d:%02d:%02d\n", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + wd[tm->tm_wday], + tm->tm_hour, tm->tm_min, tm->tm_sec); + delay(1000); time_t now = time(nullptr); if (now < 30000) { return "failed"; @@ -149,127 +133,6 @@ const String prettyMillis(unsigned long time_ms) { return String(buf); } -int timeZoneInSeconds(const byte timeZone) { - int res = 0; - switch (constrain(timeZone, 1, 38)) { - case 1: - res = -12 * ONE_HOUR_s; - break; - case 2: - res = -11 * ONE_HOUR_s; - break; - case 3: - res = -10 * ONE_HOUR_s; - break; - case 4: - res = -9 * ONE_HOUR_s - 30 * ONE_MINUTE_s; - break; - case 5: - res = -9 * ONE_HOUR_s; - break; - case 6: - res = -8 * ONE_HOUR_s; - break; - case 7: - res = -7 * ONE_HOUR_s; - break; - case 8: - res = -6 * ONE_HOUR_s; - break; - case 9: - res = -5 * ONE_HOUR_s; - break; - case 10: - res = -4 * ONE_HOUR_s; - break; - case 11: - res = -3 * ONE_HOUR_s - 30 * ONE_MINUTE_s; - break; - case 12: - res = -3 * ONE_HOUR_s; - break; - case 13: - res = -2 * ONE_HOUR_s; - break; - case 14: - res = -1 * ONE_HOUR_s; - break; - case 15: - res = 0; - break; - case 16: - res = 1 * ONE_HOUR_s; - break; - case 17: - res = 2 * ONE_HOUR_s; - break; - case 18: - res = 3 * ONE_HOUR_s; - break; - case 19: - res = 3 * ONE_HOUR_s + 30 * ONE_MINUTE_s; - break; - case 20: - res = 4 * ONE_HOUR_s; - break; - case 21: - res = 4 * ONE_HOUR_s + 30 * ONE_MINUTE_s; - break; - case 22: - res = 5 * ONE_HOUR_s; - break; - case 23: - res = 5 * ONE_HOUR_s + 30 * ONE_MINUTE_s; - break; - case 24: - res = 5 * ONE_HOUR_s + 45 * ONE_MINUTE_s; - break; - case 25: - res = 6 * ONE_HOUR_s; - break; - case 26: - res = 6 * ONE_HOUR_s + 30 * ONE_MINUTE_s; - break; - case 27: - res = 7 * ONE_HOUR_s; - break; - case 28: - res = 8 * ONE_HOUR_s; - break; - case 29: - res = 8 * ONE_HOUR_s + 45 * ONE_MINUTE_s; - break; - case 30: - res = 9 * ONE_HOUR_s; - break; - case 31: - res = 9 * ONE_HOUR_s + 30 * ONE_MINUTE_s; - break; - case 32: - res = 10 * ONE_HOUR_s; - break; - case 33: - res = 10 * ONE_HOUR_s + 30 * ONE_MINUTE_s; - break; - case 34: - res = 11 * ONE_HOUR_s; - break; - case 35: - res = 12 * ONE_HOUR_s; - break; - case 36: - res = 12 * ONE_HOUR_s + 45 * ONE_MINUTE_s; - break; - case 37: - res = 13 * ONE_HOUR_s; - break; - case 38: - res = 14 * ONE_HOUR_s; - break; - } - return res; -} - unsigned long millis_since(unsigned long sinse) { return millis_passed(sinse, millis()); } diff --git a/src/Utils/i2c_bus.cpp b/src/Utils/i2c_bus.cpp new file mode 100644 index 00000000..c3d92927 --- /dev/null +++ b/src/Utils/i2c_bus.cpp @@ -0,0 +1,30 @@ +#include "Utils/i2c_bus.h" + +#include "Global.h" + +void do_i2c_scanning() { + String tmp = i2c_scan(); + if (tmp == "error") { + tmp = i2c_scan(); + } + jsonWriteStr(configLiveJson, "i2c", tmp); +} + +const String i2c_scan() { + String out; + byte count = 0; + Wire.begin(); + for (byte i = 8; i < 120; i++) { + Wire.beginTransmission(i); + if (Wire.endTransmission() == 0) { + count++; + out += String(count) + ". 0x" + String(i, HEX) + "; "; + delay(1); + } + } + if (count == 0) { + return "error"; + } else { + return out; + } +} \ No newline at end of file diff --git a/src/Web.cpp b/src/Web.cpp index 842bc452..2cd0b397 100644 --- a/src/Web.cpp +++ b/src/Web.cpp @@ -11,7 +11,7 @@ static const uint8_t MAX_PRESET = 21; bool parseRequestForPreset(AsyncWebServerRequest* request, uint8_t& preset) { if (request->hasArg("preset")) { preset = request->getParam("preset")->value().toInt(); - return (preset >= MIN_PRESET && preset <= MAX_PRESET) || preset == 100; + return true; } return false; } @@ -22,15 +22,13 @@ void web_init() { server.on("/set", HTTP_GET, [](AsyncWebServerRequest* request) { uint8_t preset; if (parseRequestForPreset(request, preset)) { - pm.info("activate # " + String(preset, DEC) + "(" + getItemName(getPresetItem(preset)) + ")"); - String srcMacro = preset == 21 ? "configs/100с.txt" : getPresetFile(preset, CT_MACRO); - String srcScenario = preset == 21 ? "configs/100s.txt" : getPresetFile(preset, CT_SCENARIO); - copyFile(srcMacro, "100с.txt"); - copyFile(srcScenario, "100s.txt"); - + pm.info("activate #" + String(preset, DEC)); + String configFile = DEVICE_CONFIG_FILE; + String scenarioFile = DEVICE_SCENARIO_FILE; + copyFile(getConfigFile(preset, CT_CONFIG), configFile); + copyFile(getConfigFile(preset, CT_SCENARIO), scenarioFile); Device_init(); - Scenario_init(); - + loadScenario(); request->redirect("/?set.device"); } @@ -45,18 +43,18 @@ void web_init() { if (value == "0") { jsonWriteStr(configSetupJson, "scen", value); saveConfig(); - Scenario_init(); + loadScenario(); } if (value == "1") { jsonWriteStr(configSetupJson, "scen", value); saveConfig(); - Scenario_init(); + loadScenario(); } request->send(200, "text/text", "OK"); } //-------------------------------------------------------------------------------- if (request->hasArg("sceninit")) { - Scenario_init(); + loadScenario(); request->send(200, "text/text", "OK"); } //-------------------------------------------------------------------------------- @@ -72,12 +70,12 @@ void web_init() { if (value == "0") { jsonWriteStr(configSetupJson, "udponoff", value); saveConfig(); - Scenario_init(); + loadScenario(); } if (value == "1") { jsonWriteStr(configSetupJson, "udponoff", value); saveConfig(); - Scenario_init(); + loadScenario(); } request->send(200, "text/text", "OK"); } @@ -132,15 +130,17 @@ void web_init() { } //-------------------------------------------------------------------------------- if (request->hasArg("timezone")) { - jsonWriteStr(configSetupJson, "timezone", request->getParam("timezone")->value()); + String timezoneStr = request->getParam("timezone")->value(); + jsonWriteStr(configSetupJson, "timezone", timezoneStr); saveConfig(); - reconfigTime(); + rtc->setTimezone(timezoneStr.toInt()); request->send(200, "text/text", "OK"); } if (request->hasArg("ntp")) { - jsonWriteStr(configSetupJson, "ntp", request->getParam("ntp")->value()); + String ntpStr = request->getParam("ntp")->value(); + jsonWriteStr(configSetupJson, "ntp", ntpStr); saveConfig(); - reconfigTime(); + rtc->setNtpPool(ntpStr); request->send(200, "text/text", "OK"); } //-------------------------------------------------------------------------------- @@ -222,6 +222,11 @@ void web_init() { i2c_scanning = true; request->redirect("/?set.utilities"); } + + if (request->hasArg("fscheck")) { + fscheck_flag = true; + request->redirect("/?set.utilities"); + } }); //==============================upgrade settings============================================= server.on("/check", HTTP_GET, [](AsyncWebServerRequest* request) { diff --git a/src/Widgets.cpp b/src/Widgets.cpp index 41c1f28e..3acad28c 100644 --- a/src/Widgets.cpp +++ b/src/Widgets.cpp @@ -1,18 +1,24 @@ #include "Global.h" +static const char* MODULE = "Widget"; + const String getWidgetFile(const String& name); -bool loadWidget(const String filename, String& buf) { - buf = readFile(filename, 1024); - return !(buf == "Failed" || buf == "Large"); +bool loadWidget(const String& filename, String& buf) { + buf = readFile(getWidgetFile(filename), 2048); + bool res = !(buf == "Failed" || buf == "Large"); + if (!res) { + pm.error("on load" + filename); + } + return res; } void createWidget(String widget, String page, String pageNumber, String filename, String topic) { - String buf; + String buf = "{}"; if (!loadWidget(filename, buf)) { + pm.error("failed " + widget); return; } - widget.replace("#", " "); page.replace("#", " "); @@ -29,7 +35,7 @@ void createWidget(String widget, String page, String pageNumber, String filename } void createWidgetParam(String widget, String page, String pageNumber, String filename, String topic, String name1, String param1, String name2, String param2, String name3, String param3) { - String buf; + String buf = ""; if (!loadWidget(filename, buf)) { return; } @@ -54,7 +60,7 @@ void createWidgetParam(String widget, String page, String pageNumber, String fil } void createChart(String widget, String page, String pageNumber, String filename, String topic, String maxCount) { - String buf; + String buf = ""; if (!loadWidget(filename, buf)) { return; } @@ -77,9 +83,11 @@ void createChart(String widget, String page, String pageNumber, String filename, } void createWidgetByType(String widget, String page, String pageNumber, String type, String topic) { + pm.info("create" + type); createWidget(widget, page, pageNumber, getWidgetFile(type), topic); } const String getWidgetFile(const String& name) { - return "widgets/" + name + ".json"; + pm.info("get " + name); + return "/widgets/" + name + ".json"; } diff --git a/src/i2c_bus.cpp b/src/i2c_bus.cpp deleted file mode 100644 index bbcd8b29..00000000 --- a/src/i2c_bus.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "Global.h" - -void do_i2c_scanning() { - if (i2c_scanning) { - i2c_scanning = false; - String tmp = i2c_scan(); - if (tmp == "error") { - tmp = i2c_scan(); - Serial.println(tmp); - jsonWriteStr(configLiveJson, "i2c", tmp); - } else { - Serial.println(tmp); - jsonWriteStr(configLiveJson, "i2c", tmp); - } - } -} - -String i2c_scan() { - String out; - byte count = 0; - Wire.begin(); - for (byte i = 8; i < 120; i++) { - Wire.beginTransmission(i); - if (Wire.endTransmission() == 0) { - count++; - out += String(count) + ". 0x" + String(i, HEX) + "; "; - delay(1); - } - } - if (count == 0) { - return "error"; - } else { - return out; - } -} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a5263b02..9edeb862 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,15 @@ #include "Global.h" #include "HttpServer.h" +#include "Utils/i2c_bus.h" void not_async_actions(); static const char* MODULE = "Main"; +void do_fscheck(String& results) { +} + void setup() { WiFi.setAutoConnect(false); WiFi.persistent(false); @@ -52,10 +56,14 @@ void setup() { pm.info("WebAdmin"); web_init(); - pm.info("TimeSync"); + pm.info("Clock"); + rtc = new Clock(); + rtc->setNtpPool(jsonReadStr(configSetupJson, "ntp")); + rtc->setTimezone(jsonReadStr(configSetupJson, "timezone").toInt()); + ts.add( TIME_SYNC, 30000, [&](void*) { - startTimeSync(); + rtc->hasSync(); }, nullptr, true); @@ -65,7 +73,7 @@ void setup() { #endif ts.add( TEST, 10000, [&](void*) { - printMemoryStatus(); + pm.info(printMemoryStatus()); }, nullptr, true); @@ -73,7 +81,7 @@ void setup() { } void saveConfig() { - writeFile("config.json", configSetupJson); + writeFile(String("config.json"), configSetupJson); } void loop() { @@ -114,7 +122,17 @@ void not_async_actions() { do_mqtt_send_settings_to_udp(); #endif - do_i2c_scanning(); + if (i2c_scanning) { + do_i2c_scanning(); + i2c_scanning = false; + } + + if (fscheck_flag) { + String buf; + do_fscheck(buf); + jsonWriteStr(configLiveJson, "fscheck", buf); + fscheck_flag = false; + } } String getURL(const String& urls) { diff --git a/src/udp.cpp b/src/udp.cpp index f2a9be5a..988a99d3 100644 --- a/src/udp.cpp +++ b/src/udp.cpp @@ -20,7 +20,7 @@ void add_dev_in_list(String fileName, String id, String dev_name, String ip); #ifdef UDP_ENABLED void UDP_init() { - removeFile("/dev.csv"); + removeFile("dev.csv"); addFile("dev.csv", "device id;device name;ip address"); #ifdef ESP8266