diff --git a/include/Bus/BusScanner.h b/include/Bus/BusScanner.h new file mode 100644 index 00000000..e0618fdb --- /dev/null +++ b/include/Bus/BusScanner.h @@ -0,0 +1,73 @@ +#pragma once + +#include + +enum BusScanner_t { + BS_I2C, + BS_ONE_WIRE +}; + +class BusScanner { + public: + BusScanner(String& result, size_t tries) : _tries{tries}, _result{&result} {} + + void addResult(uint8_t addr, boolean last = true) { + _result->concat("0x"); + if (addr < 16) { + _result->concat("0"); + } + _result->concat(String(addr, HEX)); + _result->concat(!last ? ", " : ""); + }; + + void scan() { + if (!syncScan() && _tries--) { + syncScan(); + } + } + virtual boolean syncScan(); + + private: + size_t _tries; + BusScanner_t _type; + String* _result; +}; + +class I2CScanner : public BusScanner { + public: + I2CScanner(String& result) : BusScanner(result, 2){}; + + virtual boolean syncScan() override; +}; + +class OneWireScanner : public BusScanner { + public: + OneWireScanner(String& result) : BusScanner(result, 1){}; + + virtual boolean syncScan() override; +}; + +class BusScannerFactory { + public: + static const char* label(BusScanner_t type) { + switch (type) { + case BS_I2C: + return "i2c"; + case BS_ONE_WIRE: + return "onewire"; + default: + return ""; + } + } + + static BusScanner* get(String& str, BusScanner_t type, size_t tries = 1) { + switch (type) { + case BS_I2C: + return new I2CScanner(str); + case BS_ONE_WIRE: + return new OneWireScanner(str); + default: + return nullptr; + } + } +}; diff --git a/include/Clock.h b/include/Clock.h index 94377691..3f361122 100644 --- a/include/Clock.h +++ b/include/Clock.h @@ -3,14 +3,13 @@ #include "Utils/TimeUtils.h" #include "Utils/PrintMessage.h" -#include "time.h" +#include "TZ.h" class Clock { const char* MODULE = "Clock"; public: - Clock() : _timezone{0}, _ntp{}, _hasSynced{false}, _configured{false} { - } + Clock() : _timezone{0}, _hasSynced{false}, _configured{false} {} bool hasSync() { if (!_hasSynced) { @@ -19,9 +18,7 @@ class Clock { return _hasSynced; } - void - - setNtpPool(String ntp) { + void setNtpPool(String ntp) { _ntp = ntp; } @@ -29,15 +26,6 @@ class Clock { _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)); @@ -53,7 +41,7 @@ class Clock { } void setupSntp() { - int tzs = getBiasInSeconds(); + int tzs = getOffsetInSeconds(_timezone); int tzh = tzs / 3600; tzs -= tzh * 3600; int tzm = tzs / 60; @@ -72,26 +60,23 @@ class Clock { // i++; // delay(1000); // } - // #endif - private: + // #endifr + bool hasTimeSynced() { - unsigned long now = time(nullptr); - return now > millis(); + return getSystemTime() > 30000; } - int getBiasInSeconds() { - return getBiasInMinutes() * 60; - } - - int getBiasInMinutes() { - return _timezone * 60; - } - - const timezone getTimeZone(int minutes) { - return timezone{minutes, 0}; + time_t getSystemTime() { + timeval tv{0, 0}; + timezone tz = timezone{getOffsetInMinutes(_timezone), 0}; + if (gettimeofday(&tv, &tz) != -1) { + _epoch = tv.tv_sec; + } + return _epoch; } private: + time_t _epoch; int _timezone; String _ntp; bool _hasSynced; diff --git a/include/Global.h b/include/Global.h index f236d5af..87040f0c 100644 --- a/include/Global.h +++ b/include/Global.h @@ -11,9 +11,11 @@ // #include "Consts.h" #include "CommonTypes.h" +#include "Bus/BusScanner.h" #include "Errors.h" #include "GyverFilters.h" #include "UptimeInterval.h" +#include "Upgrade.h" #include "Clock.h" #include "MqttClient.h" @@ -100,15 +102,24 @@ extern int enter_to_logging_counter; extern int scenario_line_status[40]; -extern String last_version; +extern String lastVersion; extern boolean upgrade_url; extern boolean upgrade; extern boolean mqttParamsChanged; extern boolean udp_data_parse; extern boolean mqtt_send_settings_to_udp; -extern boolean i2c_scanning; -extern boolean fscheck_flag; + +/* +* Запрос на скарнирование шины +*/ +extern boolean busScanFlag; +/* +* Запрос на сканирование шины, указание какую +*/ +extern BusScanner_t busToScan; + +extern boolean fsCheckFlag; extern int sensors_reading_map[15]; @@ -225,11 +236,9 @@ extern void timerStop_(); extern void delTimer(String number); extern int readTimer(int number); -//Upgrade -extern void init_updater(); +extern void initUpdater(); // widget - 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 createWidget(String widget_name, String page_name, String page_number, String type, String topik); @@ -250,8 +259,8 @@ extern void loopCmd(); extern void loopButton(); extern void loopScenario(); extern void loopUdp(); -extern void do_upgrade_url(); -extern void do_upgrade(); + +extern void flashUpgrade(); // Init extern void uptime_init(); diff --git a/include/MqttDiscovery.h b/include/MqttDiscovery.h new file mode 100644 index 00000000..282b26fc --- /dev/null +++ b/include/MqttDiscovery.h @@ -0,0 +1,8 @@ +#pragma once + +#include "Utils/SysUtils.h" + +namespace Discovery { + + +} \ No newline at end of file diff --git a/include/Upgrade.h b/include/Upgrade.h new file mode 100644 index 00000000..b64e0eec --- /dev/null +++ b/include/Upgrade.h @@ -0,0 +1,5 @@ +#pragma once + +void getLastVersion(); + +void flashUpgrade(); \ No newline at end of file diff --git a/include/Utils/SysUtils.h b/include/Utils/SysUtils.h index 12ceb5fe..6e40c358 100644 --- a/include/Utils/SysUtils.h +++ b/include/Utils/SysUtils.h @@ -4,6 +4,10 @@ const String getChipId(); +const String getUniqueId(const String& name); + const String printMemoryStatus(); const String getHeapStats(); + +const String getMacAddress(); \ No newline at end of file diff --git a/include/Utils/TimeUtils.h b/include/Utils/TimeUtils.h index 658634d9..7cf508a5 100644 --- a/include/Utils/TimeUtils.h +++ b/include/Utils/TimeUtils.h @@ -1,16 +1,14 @@ #pragma once - -#include #ifdef ESP8266 -#include +#include #endif - -void Time_Init(); +#include /* * Получение текущего времени */ String getTime(); + /* * Получаем время в формате linux gmt */ @@ -36,11 +34,15 @@ int timeToMin(String Time); const String prettyMillis(unsigned long time_ms = millis()); /* -* Время (мс) прошедщее с @simce +* Время (мс) прошедщее с @since */ unsigned long millis_since(unsigned long sinse); /* -* Интерввал времени (мс) между @start и @fimish +* Интерввал времени (мс) между @start и @finish */ -unsigned long millis_passed(unsigned long start, unsigned long finish); \ No newline at end of file +unsigned long millis_passed(unsigned long start, unsigned long finish); + +int getOffsetInSeconds(int timezone); + +int getOffsetInMinutes(int timezone); diff --git a/include/Utils/Timings.h b/include/Utils/Timings.h new file mode 100644 index 00000000..c992eeee --- /dev/null +++ b/include/Utils/Timings.h @@ -0,0 +1,71 @@ +#include + +enum Timings_t { MT_ONE, + MT_TWO, + NUM_TIMINGS }; + +struct Timing { + unsigned long _total_mu; + unsigned long _min_mu; + unsigned long _max_mu; + + Timing() : _total_mu{0}, _min_mu{999999}, _max_mu{0} {}; + + void reset() { + _total_mu = 0; + _min_mu = 999999; + _max_mu = 0; + } + + void add(unsigned long time_mu) { + if (time_mu == 0) return; + + _total_mu += time_mu; + + if (_min_mu > time_mu) { + _min_mu = time_mu; + } + + if (_max_mu < time_mu) { + _max_mu = time_mu; + } + } +}; + +static const char* module_name[NUM_TIMINGS] = {"strings", "boolean"}; + +struct Timings { + Timing mu[NUM_TIMINGS]; + + unsigned long _counter; + unsigned long _start; + unsigned long long _total; + + Timings() : _counter{0}, _start{0} {}; + + void add(size_t module, unsigned long now = micros()) { + unsigned long time = now - _start; + _total += time; + mu[module].add(time); + _start = now; + } + + void count() { + _counter++; + _start = micros(); + } + + void print() { + if (!_counter) { + return; + }; + Serial.printf("lp/ms: %llu ", _counter / _total); + for (size_t i = 0; i < NUM_TIMINGS; i++) { + Serial.printf("%s: %.2f%% ", module_name[i], ((float)mu[i]._total_mu / _total) * 100); + mu[i].reset(); + } + Serial.println(); + _counter = 0; + _total = 0; + }; +}; \ No newline at end of file diff --git a/include/Utils/i2c_bus.h b/include/Utils/i2c_bus.h deleted file mode 100644 index c8d17aae..00000000 --- a/include/Utils/i2c_bus.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -void do_i2c_scanning(); - -const String i2c_scan(); \ No newline at end of file diff --git a/src/Bus/i2c_bus.cpp b/src/Bus/i2c_bus.cpp new file mode 100644 index 00000000..33e44a15 --- /dev/null +++ b/src/Bus/i2c_bus.cpp @@ -0,0 +1,21 @@ +#include "Bus/BusScanner.h" + +#include +#include "Utils/PrintMessage.h" + +static const char* MODULE = "I2C"; + +boolean I2CScanner::syncScan() { + Wire.begin(); + pm.info("scanning i2c..."); + size_t cnt = 0; + for (uint8_t i = 8; i < 120; i++) { + Wire.beginTransmission(i); + if (Wire.endTransmission() == 0) { + pm.info("found device: " + i); + addResult(i, i < 119); + cnt++; + } + } + return cnt; +} \ No newline at end of file diff --git a/src/Bus/onewire_bus.cpp b/src/Bus/onewire_bus.cpp new file mode 100644 index 00000000..a1ab283b --- /dev/null +++ b/src/Bus/onewire_bus.cpp @@ -0,0 +1,28 @@ +#include "Bus/BusScanner.h" + +#include "Utils/PresetUtils.h" +#include "Utils/PrintMessage.h" + +#include + +const char* MODULE = "1Wire"; + +bool OneWireScanner::syncScan() { + // Connect your 1-wire device to pin 3 + OneWire ds(3); + uint8_t addr[8]; + + pm.info("scanning 1-Wire..."); + while (ds.search(addr)) { + for (uint8_t i = 0; i < 8; i++) { + pm.info("found device: " + i); + addResult(addr[i], i < 7); + } + } + if (OneWire::crc8(addr, 7) != addr[7]) { + pm.error("CRC!"); + return false; + } + ds.reset_search(); + return true; +} diff --git a/src/Cmd.cpp b/src/Cmd.cpp index 389a4529..5d3789e9 100644 --- a/src/Cmd.cpp +++ b/src/Cmd.cpp @@ -606,15 +606,6 @@ void addCommandLoop(const String &cmdStr) { } } -void loopCmd() { - if (order_loop.length()) { - String tmp = selectToMarker(order_loop, ","); //выделяем первую команду rel 5 1, - sCmd.readStr(tmp); //выполняем - pm.info("do: " + order_loop); - order_loop = deleteBeforeDelimiter(order_loop, ","); //осекаем - } -} - void fileExecute(const String &filename) { String cmdStr = readFile(filename, 2048); cmdStr += "\r\n"; @@ -639,4 +630,13 @@ void stringExecute(String &cmdStr) { sCmd.readStr(buf); cmdStr = deleteBeforeDelimiter(cmdStr, "\n"); } -} \ No newline at end of file +} + +void loopCmd() { + if (order_loop.length()) { + String tmp = selectToMarker(order_loop, ","); //выделяем первую команду rel 5 1, + sCmd.readStr(tmp); //выполняем + pm.info("do: " + order_loop); + order_loop = deleteBeforeDelimiter(order_loop, ","); //осекаем + } +} diff --git a/src/Global.cpp b/src/Global.cpp index aec0b751..ceebddb2 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -64,13 +64,16 @@ int enter_to_logging_counter; // 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}; -String last_version = ""; +String lastVersion = ""; // Async actions boolean upgrade_url = false; boolean upgrade = false; + boolean mqttParamsChanged = false; boolean udp_data_parse = false; boolean mqtt_send_settings_to_udp = false; -boolean i2c_scanning = false; -boolean fscheck_flag = false; + +BusScanner_t busToScan; +boolean busScanFlag = false; +boolean fsCheckFlag = false; diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index 31d48979..19029498 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -9,6 +9,7 @@ namespace MqttClient { // Errors int wifi_lost_error = 0; int mqtt_lost_error = 0; +bool connected = false; // Session params String mqttPrefix; @@ -22,14 +23,20 @@ void init() { [&](void*) { if (isNetworkActive()) { if (mqtt.connected()) { - pm.info("OK"); - setLedStatus(LED_OFF); + if (!connected) { + pm.info("OK"); + setLedStatus(LED_OFF); + connected = true; + } } else { connect(); if (!just_load) mqtt_lost_error++; } } else { - pm.error("connection lost"); + if (connected) { + pm.error("connection lost"); + connected = false; + } ts.remove(WIFI_MQTT_CONNECTION_CHECK); wifi_lost_error++; startAPMode(); @@ -66,9 +73,6 @@ void subscribe() { } boolean connect() { - if (!isNetworkActive()) { - return false; - } pm.info("connect"); String addr = jsonReadStr(configSetupJson, "mqttServer"); diff --git a/src/MqttDiscovery.cpp b/src/MqttDiscovery.cpp new file mode 100644 index 00000000..626ee798 --- /dev/null +++ b/src/MqttDiscovery.cpp @@ -0,0 +1,78 @@ +#include "MqttDiscovery.h" + +namespace Discovery { + +static const char* json_is_defined = "is_defined"; +static const char* jsonId = "id"; +static const char* jsonBatt = "batt"; +static const char* jsonLux = "lux"; +static const char* jsonPres = "pres"; +static const char* jsonFer = "fer"; +static const char* jsonMoi = "moi"; +static const char* jsonHum = "hum"; +static const char* jsonTemp = "tem"; +static const char* jsonStep = "steps"; +static const char* jsonWeight = "weight"; +static const char* jsonPresence = "presence"; +static const char* jsonAltim = "altim"; +static const char* jsonAltif = "altift"; +static const char* jsonTempf = "tempf"; +static const char* jsonMsg = "message"; +static const char* jsonVal = "value"; +static const char* jsonVolt = "volt"; +static const char* jsonCurrent = "current"; +static const char* jsonPower = "power"; +static const char* jsonGpio = "gpio"; +static const char* jsonFtcd = "ftcd"; +static const char* jsonWm2 = "wattsm2"; +static const char* jsonAdc = "adc"; +static const char* jsonPa = "pa"; + +const String getValueJson(const char* str) { + char buf[32]; + sprintf(buf, "{{ value_json.%s }}", str); + return buf; +} + +void createDiscovery( + char* unique_id, + const char* type, char* name, char* clazz, + char* value_template, char* payload_on, char* payload_off, + char* maasure_unit, int off_delay, char* has_payload, char* no_payload, + char* avail_topi, char* cmd_topic, char* state_topic, bool child) { +} + +void createADC(const char* name) { + createDiscovery( + (char*)getUniqueId(name).c_str(), + "Type", "Name", "Clazz", + "Value", "Payload", "NoPayload", + "Measure", 0, "HasPayload", "NoPayload", + "", "", "", false); +} + +void createSwitch(const char* name) { + createDiscovery( + (char*)getUniqueId(name).c_str(), + "Type", "Name", "Clazz", + "Value", "Payload", "NoPayload", + "Measure", 0, "HasPayload", "NoPayload", + "", "", "", false); +} +// component, +// type, +// name, +// availability topic, +// device class, +// value template, payload on, payload off, unit of measurement +char* BMEsensor[6][8] = { + {"sensor", "tempc", "bme", "temperature", "", "", "°C"}, //jsonTemp + {"sensor", "tempf", "bme", "temperature", "", "", "°F"}, //jsonTempf + {"sensor", "pa", "bme", "", "", "", "hPa"}, //jsonPa + {"sensor", "hum", "bme", "humidity", "", "", "%"}, // jsonHum + {"sensor", "altim", "bme", "", "", "", "m"}, //jsonAltim + {"sensor", "altift", "bme", "", "", "", "ft"} // jsonAltif + +}; + +} // namespace Discovery diff --git a/src/Scenario.cpp b/src/Scenario.cpp index 849ba2b8..341a5be7 100644 --- a/src/Scenario.cpp +++ b/src/Scenario.cpp @@ -1,21 +1,27 @@ #include "Global.h" +static const char* MODULE = "Scen"; + void loopScenario() { - if (jsonReadStr(configSetupJson, "scen") == "1") { + bool enabled = jsonReadBool(configSetupJson, "scen"); + if (enabled) { if ((jsonReadStr(configOptionJson, "scenario_status") != "")) { - int i = 0; - String str = scenario; //читаем переменную с сценариями (то что из файла на странице) + String str = scenario; str += "\n"; str.replace("\r\n", "\n"); str.replace("\r", "\n"); - while (str.length() != 0) { - //----------------------------------------------------------------------------------------------------------------------- - String tmp = selectToMarker(str, "end"); //выделяем первый сценарий из файла вместе с командами - if (tmp == "") return; + + size_t i = 0; + while (str.length()) { + String block = selectToMarker(str, "end"); + if (!block.length()) { + return; + } i++; if (scenario_line_status[i] == 1) { - String condition = selectToMarker(tmp, "\n"); //выделяем первую строку самого сценария button1 = 1 (условие) + //выделяем первую строку самого сценария button1 = 1 (условие) + String condition = selectToMarker(block, "\n"); String param_name = selectFromMarkerToMarker(condition, " ", 0); String order = jsonReadStr(configOptionJson, "scenario_status"); //читаем весь файл событий String param = selectToMarker(order, ","); //читаем первое событие из файла событий @@ -52,11 +58,10 @@ void loopScenario() { } if (flag) { - tmp = deleteBeforeDelimiter(tmp, "\n"); //удаляем строку самого сценария оставляя только команды - stringExecute(tmp); //выполняем все команды + block = deleteBeforeDelimiter(block, "\n"); //удаляем строку самого сценария оставляя только команды + stringExecute(block); //выполняем все команды - Serial.println("[SCENARIO] '" + condition + "'"); - //Serial.println(" " + tmp); + pm.info(condition + "'"); } } } diff --git a/src/Sensors.cpp b/src/Sensors.cpp index c4503d39..108e6e5b 100644 --- a/src/Sensors.cpp +++ b/src/Sensors.cpp @@ -13,9 +13,10 @@ Adafruit_Sensor *bme_temp = bme.getTemperatureSensor(); Adafruit_Sensor *bme_pressure = bme.getPressureSensor(); Adafruit_Sensor *bme_humidity = bme.getHumiditySensor(); -String perception(byte value); +const String perceptionStr(byte value); +const String comfortStr(ComfortState value); + void bmp280T_reading(); -String get_comfort_status(ComfortState cf); void sensors_init() { ts.add( @@ -240,9 +241,11 @@ void dallas() { String type = sCmd.next(); String page_number = sCmd.next(); oneWire = new OneWire((uint8_t)pin.toInt()); + sensors.setOneWire(oneWire); sensors.begin(); sensors.setResolution(12); + createWidgetByType(widget_name, page_name, page_number, type, "dallas"); sensors_reading_map[3] = 1; } @@ -351,7 +354,7 @@ void dhtP_reading() { MqttClient::publishStatus("dhtPerception", String(dht.getStatusString())); } else { value = dht.computePerception(jsonReadStr(configLiveJson, dhtT_value_name).toFloat(), jsonReadStr(configLiveJson, dhtH_value_name).toFloat(), false); - String final_line = perception(value); + String final_line = perceptionStr(value); jsonWriteStr(configLiveJson, "dhtPerception", final_line); eventGen("dhtPerception", ""); MqttClient::publishStatus("dhtPerception", final_line); @@ -361,7 +364,30 @@ void dhtP_reading() { } } -String perception(byte value) { +//dhtComfort Степень#комфорта: Датчики 3 +void dhtC() { + String widget_name = sCmd.next(); + String page_name = sCmd.next(); + String page_number = sCmd.next(); + createWidgetByType(widget_name, page_name, page_number, "anydata", "dhtComfort"); + sensors_reading_map[7] = 1; +} + +void dhtC_reading() { + ComfortState cf; + if (dht.getStatus() != 0) { + MqttClient::publishStatus("dhtComfort", String(dht.getStatusString())); + } else { + dht.getComfortRatio(cf, jsonReadStr(configLiveJson, dhtT_value_name).toFloat(), jsonReadStr(configLiveJson, dhtH_value_name).toFloat(), false); + String final_line = comfortStr(cf); + jsonWriteStr(configLiveJson, "dhtComfort", final_line); + eventGen("dhtComfort", ""); + MqttClient::publishStatus("dhtComfort", final_line); + Serial.println("[I] sensor 'dhtComfort' send date " + final_line); + } +} + +const String perceptionStr(byte value) { String res; switch (value) { case 0: @@ -386,7 +412,7 @@ String perception(byte value) { res = F("Очень неудобно"); break; case 7: - res = F("Сильно неудобно, полный звиздец"); + res = F("Невыносимо"); default: res = F("Unknown"); break; @@ -394,64 +420,41 @@ String perception(byte value) { return res; } -//dhtComfort Степень#комфорта: Датчики 3 -void dhtC() { - String widget_name = sCmd.next(); - String page_name = sCmd.next(); - String page_number = sCmd.next(); - createWidgetByType(widget_name, page_name, page_number, "anydata", "dhtComfort"); - sensors_reading_map[7] = 1; -} - -void dhtC_reading() { - ComfortState cf; - if (dht.getStatus() != 0) { - MqttClient::publishStatus("dhtComfort", String(dht.getStatusString())); - } else { - dht.getComfortRatio(cf, jsonReadStr(configLiveJson, dhtT_value_name).toFloat(), jsonReadStr(configLiveJson, dhtH_value_name).toFloat(), false); - String final_line = get_comfort_status(cf); - jsonWriteStr(configLiveJson, "dhtComfort", final_line); - eventGen("dhtComfort", ""); - MqttClient::publishStatus("dhtComfort", final_line); - Serial.println("[I] sensor 'dhtComfort' send date " + final_line); - } -} - -String get_comfort_status(ComfortState cf) { - String comfortStatus; - switch (cf) { +const String comfortStr(ComfortState value) { + String res; + switch (value) { case Comfort_OK: - comfortStatus = "Отлично"; + res = F("Отлично"); break; case Comfort_TooHot: - comfortStatus = "Очень жарко"; + res = F("Очень жарко"); break; case Comfort_TooCold: - comfortStatus = "Очень холодно"; + res = F("Очень холодно"); break; case Comfort_TooDry: - comfortStatus = "Очень сухо"; + res = F("Очень сухо"); break; case Comfort_TooHumid: - comfortStatus = "Очень влажно"; + res = F("Очень влажно"); break; case Comfort_HotAndHumid: - comfortStatus = "Жарко и влажно"; + res = F("Жарко и влажно"); break; case Comfort_HotAndDry: - comfortStatus = "Жарко и сухо"; + res = F("Жарко и сухо"); break; case Comfort_ColdAndHumid: - comfortStatus = "Холодно и влажно"; + res = F("Холодно и влажно"); break; case Comfort_ColdAndDry: - comfortStatus = "Холодно и сухо"; + res = F("Холодно и сухо"); break; default: - comfortStatus = "Неизвестно"; + res = F("Неизвестно"); break; }; - return comfortStatus; + return res; } //dhtDewpoint Точка#росы: Датчики 5 diff --git a/src/Upgrade.cpp b/src/Upgrade.cpp index 51dafbd5..802986d0 100644 --- a/src/Upgrade.cpp +++ b/src/Upgrade.cpp @@ -1,30 +1,42 @@ +#include "Upgrade.h" + #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"); -#endif -#ifdef ESP32 - if (WiFi.status() == WL_CONNECTED) last_version = getURL("http://91.204.228.124:1100/update/esp32/version.txt"); -#endif - jsonWriteStr(configSetupJson, "last_version", last_version); - Serial.print("[I] Last firmware version: "); - Serial.println(last_version); +static const char* MODULE = "Upgr"; + +static const char* filesystem_image_url PROGMEM = "http://91.204.228.124:1100/update/%s/fs.bin"; +static const char* available_url PROGMEM = "http://91.204.228.124:1100/update/%s/version.txt"; + +const String getAvailableUrl(const char* mcu) { + char buf[128]; + sprintf_P(buf, available_url, mcu); + return buf; } -void do_upgrade_url() { +void getLastVersion() { if (upgrade_url) { upgrade_url = false; + String url; #ifdef ESP32 - last_version = getURL("http://91.204.228.124:1100/update/esp32/version.txt"); + url = getAvailableUrl("esp32"); #endif #ifdef ESP8266 - last_version = getURL("http://91.204.228.124:1100/update/esp8266/version.txt"); + url = getAvailableUrl("esp8266"); #endif - jsonWriteStr(configSetupJson, "last_version", last_version); + lastVersion = getURL(url); + jsonWriteStr(configSetupJson, "last_version", lastVersion); } } +void initUpdater() { + if (isNetworkActive()) { + getLastVersion(); + if (lastVersion.length()) { + pm.info("available: " + lastVersion); + } + }; +} + void upgrade_firmware() { String scenario_for_update; String config_for_update; @@ -77,7 +89,7 @@ void upgrade_firmware() { } } -void do_upgrade() { +void flashUpgrade() { if (upgrade) { upgrade = false; upgrade_firmware(); diff --git a/src/Utils/SysUtils.cpp b/src/Utils/SysUtils.cpp index e67b9b02..d46a343c 100644 --- a/src/Utils/SysUtils.cpp +++ b/src/Utils/SysUtils.cpp @@ -1,6 +1,10 @@ #include "Utils/SysUtils.h" -#include "Utils/StringUtils.h" +#include "Global.h" + +const String getUniqueId(const char* name) { + return String(name) + getMacAddress(); +} const String getChipId() { String res; @@ -62,6 +66,19 @@ String getHeapStats() { } #endif +const String getMacAddress() { + uint8_t mac[6]; + char buf[13] = {0}; +#if defined(ESP8266) + WiFi.macAddress(mac); + sprintf(buf, MACSTR, MAC2STR(mac)); +#else + esp_read_mac(mac, ESP_MAC_WIFI_STA); + sprintf(buf, MACSTR, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); +#endif + return String(buf); +} + //=================================================================== /* void web_print (String text) { diff --git a/src/Utils/TimeUtils.cpp b/src/Utils/TimeUtils.cpp index 59aa09cc..09c7185d 100644 --- a/src/Utils/TimeUtils.cpp +++ b/src/Utils/TimeUtils.cpp @@ -4,6 +4,7 @@ #include "Utils\StringUtils.h" #define ONE_MINUTE_s 60 +#define ONE_HOUR_m 60 #define ONE_HOUR_s 60 * ONE_MINUTE_s time_t t; @@ -13,22 +14,20 @@ 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_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"; - } else { - return String(now); } + return String(now); } boolean getUnixTimeStr(String& res) { time_t now = time(nullptr); res = String(now); - return now < 30000; + return now > 30000; } String getTime() { @@ -158,3 +157,11 @@ unsigned long millis_passed(unsigned long start, unsigned long finish) { } return result; } + +int getOffsetInSeconds(int timezone) { + return getOffsetInMinutes(timezone) * ONE_MINUTE_s; +} + +int getOffsetInMinutes(int timezone) { + return timezone * ONE_HOUR_m; +} diff --git a/src/Utils/i2c_bus.cpp b/src/Utils/i2c_bus.cpp deleted file mode 100644 index c3d92927..00000000 --- a/src/Utils/i2c_bus.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#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 2cd0b397..ae123d45 100644 --- a/src/Web.cpp +++ b/src/Web.cpp @@ -219,37 +219,44 @@ void web_init() { #endif //==============================utilities settings============================================= if (request->hasArg("itoc")) { - i2c_scanning = true; + busScanFlag = true; + busToScan = BS_I2C; + request->redirect("/?set.utilities"); + } + + if (request->hasArg("onewire")) { + busScanFlag = true; + busToScan = BS_ONE_WIRE; request->redirect("/?set.utilities"); } if (request->hasArg("fscheck")) { - fscheck_flag = true; + fsCheckFlag = true; request->redirect("/?set.utilities"); } }); //==============================upgrade settings============================================= server.on("/check", HTTP_GET, [](AsyncWebServerRequest* request) { upgrade_url = true; - pm.info("firmware version: " + last_version); + pm.info("firmware version: " + lastVersion); String tmp = "{}"; int case_of_update; if (WiFi.status() != WL_CONNECTED) { - last_version = "nowifi"; + lastVersion = "nowifi"; } if (!FLASH_4MB) { - last_version = "less"; + lastVersion = "less"; } - if (last_version == FIRMWARE_VERSION) case_of_update = 1; - if (last_version != FIRMWARE_VERSION) case_of_update = 2; - if (last_version == "error") case_of_update = 3; - if (last_version == "") case_of_update = 4; - if (last_version == "less") case_of_update = 5; - if (last_version == "nowifi") case_of_update = 6; - if (last_version == "notsupported") case_of_update = 7; + if (lastVersion == FIRMWARE_VERSION) case_of_update = 1; + if (lastVersion != FIRMWARE_VERSION) case_of_update = 2; + if (lastVersion == "error") case_of_update = 3; + if (lastVersion == "") case_of_update = 4; + if (lastVersion == "less") case_of_update = 5; + if (lastVersion == "nowifi") case_of_update = 6; + if (lastVersion == "notsupported") case_of_update = 7; switch (case_of_update) { case 1: { diff --git a/src/main.cpp b/src/main.cpp index 9edeb862..00737fff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,8 @@ #include "Global.h" #include "HttpServer.h" -#include "Utils/i2c_bus.h" +#include "Bus/BusScanner.h" +#include "Utils/Timings.h" void not_async_actions(); @@ -48,7 +49,7 @@ void setup() { telemetry_init(); pm.info("Updater"); - init_updater(); + initUpdater(); pm.info("HttpServer"); HttpServer::init(); @@ -84,22 +85,27 @@ void saveConfig() { writeFile(String("config.json"), configSetupJson); } +Timings metric; + void loop() { #ifdef OTA_UPDATES_ENABLED ArduinoOTA.handle(); #endif - #ifdef WS_enable ws.cleanupClients(); #endif - + metric.add(MT_ONE); not_async_actions(); + metric.add(MT_TWO); MqttClient::loop(); loopCmd(); + loopButton(); + loopScenario(); + #ifdef UDP_ENABLED loopUdp(); #endif @@ -107,6 +113,12 @@ void loop() { loopSerial(); ts.update(); + + if (metric._counter > 100000) { + metric.print(); + } else { + metric.count(); + } } void not_async_actions() { @@ -114,24 +126,27 @@ void not_async_actions() { MqttClient::reconnect(); mqttParamsChanged = false; } - do_upgrade_url(); - do_upgrade(); + getLastVersion(); + flashUpgrade(); #ifdef UDP_ENABLED do_udp_data_parse(); do_mqtt_send_settings_to_udp(); #endif - if (i2c_scanning) { - do_i2c_scanning(); - i2c_scanning = false; + if (busScanFlag) { + String res = ""; + BusScanner* scanner = BusScannerFactory::get(res, busToScan); + scanner->scan(); + jsonWriteStr(configLiveJson, BusScannerFactory::label(busToScan), res); + busScanFlag = false; } - if (fscheck_flag) { + if (fsCheckFlag) { String buf; do_fscheck(buf); jsonWriteStr(configLiveJson, "fscheck", buf); - fscheck_flag = false; + fsCheckFlag = false; } }