From 2550e564c15e000802fb0add0ff060451068b616 Mon Sep 17 00:00:00 2001 From: xyzroe Date: Fri, 7 Jun 2024 00:09:43 +0200 Subject: [PATCH] 20240607 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Zigbee Updates - Add Zigbee role on root page and MQTT - Display saved Zigbee version if unable to detect the installed version (Web UI and MQTT) - Add check for available Zigbee updates - Fix Zigbee version detection after Zigbee firmware update - Add **automatic change of baud rate** after installing new Zigbee firmware - Add NV parameters for last installed Zigbee firmware version and role - Add MQTT sensor for Zigbee update availability - HTTP API command to update Zigbee firmware now uses the role and gets the latest firmware from GitHub - Remove Zigbee firmware check during boot if not in coordinator role ### General Improvements - Add Wi-Fi mode and TX power options to configure on the network page - Revert Wi-Fi RSSI bar. Lower values are green (better), higher values are red (worse) - Add tooltips for any element with a title attribute (currently only on General and MQTT pages) - Set Debug tab cards width to 100% - Rework DNS check and restore to avoid saving every time - Remove cron-based DNS check and restore, only before HTTP, MQTT, WG actions Fix #11, #24, #42, #43 ? - Fix **MQTT Discovery** option. No more publications to **/homeassistant/** if disabled - Attempt to fix memory leak during long events - Remove in-browser JS-based ESP update check availability ### Hardware Support - Remove alternative power pin from ETH config, as it is deprecated - Fix some UZG-01 v0.5 boards not starting ETH. Fix #44 ? - Add support for HamGeek POE Plus board. Thanks @radioelf 🥇 Done #50 *(Still no ability to select, if more than one same board configs)* - Add support for SLS board. Thanks t.me/Novgorod73 *(Still no ability to select, if more than one same board configs)* --- README.md | 4 +- platformio.ini | 12 -- src/config.cpp | 76 +++++++-- src/config.h | 59 +++++-- src/const/hw.cpp | 44 ++--- src/const/hw.h | 2 +- src/const/keys.cpp | 26 ++- src/const/keys.h | 15 ++ src/etc.cpp | 194 +++++++++++++++------- src/etc.h | 4 +- src/main.cpp | 101 +++++++----- src/mqtt.cpp | 82 ++++++++-- src/version.h | 2 +- src/web.cpp | 260 +++++++++++++++++++++++------- src/web.h | 3 +- src/websrc/html/PAGE_GENERAL.html | 78 +++++---- src/websrc/html/PAGE_NETWORK.html | 25 +++ src/websrc/html/PAGE_ROOT.html | 6 +- src/websrc/html/PAGE_TOOLS.html | 4 +- src/websrc/html/PAGE_ZIGBEE.html | 5 +- src/websrc/js/functions.js | 142 +++++++++++----- src/websrc/json/cz.json | 30 +++- src/websrc/json/de.json | 30 +++- src/websrc/json/en.json | 30 +++- src/websrc/json/es.json | 30 +++- src/websrc/json/fr.json | 30 +++- src/websrc/json/it.json | 30 +++- src/websrc/json/ja.json | 30 +++- src/websrc/json/pl.json | 30 +++- src/websrc/json/pt.json | 30 +++- src/websrc/json/ru.json | 30 +++- src/websrc/json/tr.json | 30 +++- src/websrc/json/uk.json | 30 +++- src/websrc/json/zh.json | 30 +++- src/zb.cpp | 131 +++++++++++---- 35 files changed, 1283 insertions(+), 382 deletions(-) diff --git a/README.md b/README.md index a882d5e..4d96232 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # XZG Firmware
-GitHub version +GitHub version GitHub Actions Workflow Status -GitHub download +GitHub download GitHub Issues or Pull Requests License
diff --git a/platformio.ini b/platformio.ini index 0d57031..0c4a984 100644 --- a/platformio.ini +++ b/platformio.ini @@ -8,18 +8,6 @@ ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html -;It was difficult to find working platform for https get function on solo board. Here are some logs: -;https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5/platform-espressif32-2.0.5.zip ;- old build. - unkown board -;https://github.com/tasmota/platform-espressif32/releases/download/2023.01.00/platform-espressif32.zip ; fuck yeaar. it works on solo -;https://github.com/tasmota/platform-espressif32/releases/download/2023.07.00/platform-espressif32.zip ; fuck yeaar. it also works on solo -;https://github.com/tasmota/platform-espressif32/releases/download/2023.08.00/platform-espressif32.zip ; bitch. did't work -1 -;https://github.com/tasmota/platform-espressif32/releases/download/2023.10.01/platform-espressif32.zip ;- build but -1 -;https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip ;- last builds version but -1 -;https://github.com/tasmota/platform-espressif32/releases/download/2023.10.05/platform-espressif32.zip ;- WiFiClientSecure.h: No such file or directory -;https://github.com/tasmota/platform-espressif32/releases/download/2023.10.10/platform-espressif32.zip ; - logs2.txt -;espressif32 @ ^6.4.0 ;- unkown board -;espressif32 @ 5.1.0 ; - works but no solo - [platformio] default_envs = prod-solo diff --git a/src/config.cpp b/src/config.cpp index 9fc07bd..16b80dd 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -125,6 +125,8 @@ void saveNetworkConfig(const NetworkConfigStruct &config) preferences.putString(wifiGateKey, config.wifiGate.toString()); preferences.putString(wifiDns1Key, config.wifiDns1.toString()); preferences.putString(wifiDns2Key, config.wifiDns2.toString()); + preferences.putInt(wifiPwrKey, static_cast(config.wifiPower)); + preferences.putInt(wifiModeKey, config.wifiMode); preferences.putBool(ethEnblKey, config.ethEnable); preferences.putBool(ethDhcpKey, config.ethDhcp); @@ -151,6 +153,9 @@ void loadNetworkConfig(NetworkConfigStruct &config) config.wifiDns1.fromString(preferences.getString(wifiDns1Key, DNS_SERV_1)); config.wifiDns2.fromString(preferences.getString(wifiDns2Key, DNS_SERV_2)); + config.wifiPower = static_cast(preferences.getInt(wifiPwrKey, WIFI_POWER_19_5dBm)); + config.wifiMode = preferences.getInt(wifiModeKey, WIFI_PROTOCOL_11B); + config.ethEnable = preferences.getBool(ethEnblKey, true); config.ethDhcp = preferences.getBool(ethDhcpKey, true); config.ethIp.fromString(preferences.getString(ethIpKey)); @@ -260,7 +265,7 @@ void saveSystemConfig(const SystemConfigStruct &config) { preferences.begin(systemConfigKey, false); - //preferences.putBool(keepWebKey, config.keepWeb); + // preferences.putBool(keepWebKey, config.keepWeb); preferences.putBool(disableWebKey, config.disableWeb); preferences.putBool(webAuthKey, config.webAuth); preferences.putString(webUserKey, config.webUser); @@ -283,6 +288,13 @@ void saveSystemConfig(const SystemConfigStruct &config) // preferences.putInt(prevWorkModeKey, static_cast(config.prevWorkMode)); preferences.putInt(workModeKey, static_cast(config.workMode)); + preferences.putInt(zbRoleKey, static_cast(config.zbRole)); + preferences.putString(zbFwKey, config.zbFw); + + preferences.putString(updCheckTimeKey, config.updCheckTime); + preferences.putString(updCheckDayKey, config.updCheckDay); + preferences.putBool(updAutoInstKey, config.updAutoInst); + preferences.end(); } @@ -290,7 +302,7 @@ void loadSystemConfig(SystemConfigStruct &config) { preferences.begin(systemConfigKey, true); - //config.keepWeb = preferences.getBool(keepWebKey, true); + // config.keepWeb = preferences.getBool(keepWebKey, true); config.disableWeb = preferences.getBool(disableWebKey, false); config.webAuth = preferences.getBool(webAuthKey, false); strlcpy(config.webUser, preferences.getString(webUserKey, "").c_str(), sizeof(config.webUser)); @@ -315,6 +327,13 @@ void loadSystemConfig(SystemConfigStruct &config) // config.prevWorkMode = static_cast(preferences.getInt(prevWorkModeKey, WORK_MODE_NETWORK)); config.workMode = static_cast(preferences.getInt(workModeKey, WORK_MODE_NETWORK)); + config.zbRole = static_cast(preferences.getInt(zbRoleKey, UNDEFINED)); + strlcpy(config.zbFw, preferences.getString(zbFwKey, "?").c_str(), sizeof(config.zbFw)); + + strlcpy(config.updCheckTime, preferences.getString(updCheckTimeKey, UPD_CHK_TIME).c_str(), sizeof(config.updCheckTime)); + strlcpy(config.updCheckDay, preferences.getString(updCheckDayKey, UPD_CHK_DAY).c_str(), sizeof(config.updCheckDay)); + config.updAutoInst = preferences.getBool(updAutoInstKey, false); + preferences.end(); } @@ -398,19 +417,33 @@ void updateConfiguration(WebServer &serverWeb, SystemConfigStruct &configSys, Ne if (serverWeb.hasArg(nmStartHourKey)) { - LOGD("nmStartHourKey %s", String(serverWeb.arg(nmStartHourKey))); + // LOGD("nmStartHourKey %s", String(serverWeb.arg(nmStartHourKey))); // Serial.println(convertTimeToCron(serverWeb.arg(nmStartHourKey))); strncpy(configSys.nmStart, serverWeb.arg(nmStartHourKey).c_str(), sizeof(configSys.nmStart) - 1); configSys.nmStart[sizeof(configSys.nmStart) - 1] = '\0'; // Guarantee a null terminator at the end } if (serverWeb.hasArg(nmEndHourKey)) { - LOGD("nmEndHourKey %s", String(serverWeb.arg(nmEndHourKey))); + // LOGD("nmEndHourKey %s", String(serverWeb.arg(nmEndHourKey))); // Serial.println(convertTimeToCron(serverWeb.arg(nmEndHourKey))); strncpy(configSys.nmEnd, serverWeb.arg(nmEndHourKey).c_str(), sizeof(configSys.nmEnd) - 1); configSys.nmEnd[sizeof(configSys.nmEnd) - 1] = '\0'; // Guarantee a null terminator at the end } + if (serverWeb.hasArg(updCheckTimeKey)) + { + strncpy(configSys.updCheckTime, serverWeb.arg(updCheckTimeKey).c_str(), sizeof(configSys.updCheckTime) - 1); + configSys.updCheckTime[sizeof(configSys.updCheckTime) - 1] = '\0'; // Guarantee a null terminator at the end + } + + if (serverWeb.hasArg(updCheckDayKey)) + { + strncpy(configSys.updCheckDay, serverWeb.arg(updCheckDayKey).c_str(), sizeof(configSys.updCheckDay) - 1); + configSys.updCheckDay[sizeof(configSys.updCheckDay) - 1] = '\0'; // Guarantee a null terminator at the end + } + + configSys.updAutoInst = serverWeb.hasArg(updAutoInstKey) == true; + saveSystemConfig(configSys); } break; @@ -449,6 +482,16 @@ void updateConfiguration(WebServer &serverWeb, SystemConfigStruct &configSys, Ne configNet.wifiDhcp = serverWeb.hasArg(wifiDhcpKey) == true; + if (serverWeb.hasArg(wifiModeKey)) + { + configNet.wifiMode = serverWeb.arg(wifiModeKey).toInt(); + } + if (serverWeb.hasArg(wifiPwrKey)) + { + const uint8_t pwr = serverWeb.arg(wifiPwrKey).toInt(); + configNet.wifiPower = static_cast(pwr); + } + if (serverWeb.arg(wifiSsidKey)) { strncpy(configNet.wifiSsid, serverWeb.arg(wifiSsidKey).c_str(), sizeof(configNet.wifiSsid) - 1); @@ -709,6 +752,8 @@ void serializeNetworkConfigToJson(const NetworkConfigStruct &config, JsonObject obj[wifiGateKey] = config.wifiGate.toString(); obj[wifiDns1Key] = config.wifiDns1.toString(); obj[wifiDns2Key] = config.wifiDns2.toString(); + obj[wifiPwrKey] = config.wifiPower; + obj[wifiModeKey] = config.wifiMode; obj[ethEnblKey] = config.ethEnable; obj[ethDhcpKey] = config.ethDhcp; obj[ethIpKey] = config.ethIp.toString(); @@ -761,7 +806,7 @@ void serializeMqttConfigToJson(const MqttConfigStruct &config, JsonObject obj) // Serialization SystemConfigStruct into JSON void serializeSystemConfigToJson(const SystemConfigStruct &config, JsonObject obj) { - //obj[keepWebKey] = config.keepWeb; + // obj[keepWebKey] = config.keepWeb; obj[disableWebKey] = config.disableWeb; obj[webAuthKey] = config.webAuth; obj[webUserKey] = config.webUser; @@ -783,6 +828,13 @@ void serializeSystemConfigToJson(const SystemConfigStruct &config, JsonObject ob obj[nmEndHourKey] = config.nmEnd; // obj[prevWorkModeKey] = static_cast(config.prevWorkMode); obj[workModeKey] = static_cast(config.workMode); + + obj[zbRoleKey] = static_cast(config.zbRole); + obj[zbFwKey] = config.zbFw; + + obj[updCheckTimeKey] = config.updCheckTime; + obj[updCheckDayKey] = config.updCheckDay; + obj[updAutoInstKey] = config.updAutoInst; } // Serializing system variables to JSON @@ -791,7 +843,7 @@ void serializeSysVarsToJson(const SysVarsStruct &vars, JsonObject obj) obj[hwBtnIsKey] = vars.hwBtnIs; obj[hwLedUsbIsKey] = vars.hwLedUsbIs; obj[hwLedPwrIsKey] = vars.hwLedPwrIs; - //obj[hwUartSelIsKey] = vars.hwUartSelIs; + // obj[hwUartSelIsKey] = vars.hwUartSelIs; obj[hwZigbeeIsKey] = vars.hwZigbeeIs; obj[connectedClientsKey] = vars.connectedClients; @@ -815,6 +867,9 @@ void serializeSysVarsToJson(const SysVarsStruct &vars, JsonObject obj) // obj[zbFlashingKey] = vars.zbFlashing; obj[deviceIdKey] = vars.deviceId; + + obj[espUpdAvailKey] = vars.updateEspAvail; + obj[zbUpdAvailKey] = vars.updateZbAvail; } bool loadFileConfigHW() @@ -862,7 +917,10 @@ bool loadFileConfigHW() hwConfig.eth.mdiPin = config[mdiPin]; hwConfig.eth.phyType = config[phyType]; hwConfig.eth.clkMode = config[clkMode]; - hwConfig.eth.pwrAltPin = config[pwrAltPin]; + if (hwConfig.eth.pwrPin == -1) { + hwConfig.eth.pwrPin = config[pwrAltPin]; + } + //hwConfig.eth.pwrAltPin = config[pwrAltPin]; hwConfig.mist.btnPin = config[btnPin]; hwConfig.mist.btnPlr = config[btnPlr]; hwConfig.mist.uartSelPin = config[uartSelPin]; @@ -903,7 +961,7 @@ bool loadFileConfigHW() config[mdiPin] = newConfig->eth.mdiPin; config[phyType] = newConfig->eth.phyType; config[clkMode] = newConfig->eth.clkMode; - config[pwrAltPin] = newConfig->eth.pwrAltPin; + //config[pwrAltPin] = newConfig->eth.pwrAltPin; config[btnPin] = newConfig->mist.btnPin; config[btnPlr] = newConfig->mist.btnPlr; config[uartSelPin] = newConfig->mist.uartSelPin; @@ -1097,7 +1155,7 @@ bool loadFileConfigGeneral() systemCfg.disableLedPwr = (uint8_t)doc[disableLedPwrKey]; systemCfg.disableLedUSB = (uint8_t)doc[disableLedUSBKey]; vars.disableLeds = (uint8_t)doc[disableLedsKey]; - //systemCfg.keepWeb = (uint8_t)doc[keepWebKey]; + // systemCfg.keepWeb = (uint8_t)doc[keepWebKey]; strlcpy(systemCfg.timeZone, doc[timeZoneKey] | NTP_TIME_ZONE, sizeof(systemCfg.timeZone)); configFile.close(); diff --git a/src/config.h b/src/config.h index d3f4817..910a270 100644 --- a/src/config.h +++ b/src/config.h @@ -14,7 +14,7 @@ #define ZB_TCP_PORT 6638 // any port ever. later setup from config file #define ZB_SERIAL_SPEED 115200 -#define NTP_TIME_ZONE "Europe/Kiev" +#define NTP_TIME_ZONE "Europe/Berlin" #define NTP_SERV_1 "pool.ntp.org" #define NTP_SERV_2 "time.google.com" #define DNS_SERV_1 "1.1.1.1" @@ -23,6 +23,8 @@ #define NETWORK_ZERO "0.0.0.0" #define NM_START_TIME "23:00" #define NM_END_TIME "07:00" +#define UPD_CHK_TIME "01:00" +#define UPD_CHK_DAY "*" #define MAX_SOCKET_CLIENTS 5 @@ -50,6 +52,14 @@ enum LED_t : uint8_t ZB_LED }; +enum ZB_ROLE_t : uint8_t +{ + UNDEFINED, + COORDINATOR, + ROUTER, + OPENTHREAD +}; + extern const char *coordMode; // coordMode node name extern const char *configFileSystem; extern const char *configFileWifi; @@ -66,7 +76,7 @@ struct SysVarsStruct bool hwBtnIs = false; bool hwLedUsbIs = false; bool hwLedPwrIs = false; - //bool hwUartSelIs = false; + // bool hwUartSelIs = false; bool hwZigbeeIs = false; bool connectedSocket[MAX_SOCKET_CLIENTS]; //[10] @@ -95,6 +105,9 @@ struct SysVarsStruct char deviceId[MAX_DEV_ID_LONG]; bool updateEspAvail; + bool updateZbAvail; + IPAddress savedWifiDNS; + IPAddress savedEthDNS; }; // Network configuration structure @@ -102,6 +115,9 @@ struct NetworkConfigStruct { // Wi-Fi bool wifiEnable; + // int wifiPower; + wifi_power_t wifiPower; + int wifiMode; char wifiSsid[50]; char wifiPass[80]; bool wifiDhcp; @@ -175,7 +191,7 @@ void loadMqttConfig(MqttConfigStruct &config); struct SystemConfigStruct { - //bool keepWeb; // when usb mode active + // bool keepWeb; // when usb mode active bool disableWeb; // when socket connected bool webAuth; @@ -205,7 +221,14 @@ struct SystemConfigStruct char nmEnd[6]; // WORK_MODE_t prevWorkMode; // for button // WORK_MODE_t - WORK_MODE_t workMode; // for button // WORK_MODE_t + WORK_MODE_t workMode; + + ZB_ROLE_t zbRole; + char zbFw[30]; + + char updCheckTime[6]; + char updCheckDay[3]; + bool updAutoInst; }; // Function prototypes for SystemConfigStruct @@ -297,33 +320,35 @@ uint8_t temprature_sens_read(); // Conditional logging macros #if CURRENT_LOG_LEVEL >= LOG_LEVEL_WARN -#define LOGW(format, ...) \ - if (systemCfg.workMode == WORK_MODE_NETWORK) { \ - Serial.printf(ANSI_COLOR_PURPLE "%d " ANSI_COLOR_RESET ANSI_COLOR_RED "[%s] " ANSI_COLOR_RESET format "\n", millis(), __func__, ##__VA_ARGS__); \ - } +#define LOGW(format, ...) \ + if (systemCfg.workMode == WORK_MODE_NETWORK) \ + { \ + Serial.printf(ANSI_COLOR_PURPLE "%d " ANSI_COLOR_RESET ANSI_COLOR_RED "[%s] " ANSI_COLOR_RESET format "\n", millis(), __func__, ##__VA_ARGS__); \ + } #else #define LOGW(format, ...) // Nothing #endif #if CURRENT_LOG_LEVEL >= LOG_LEVEL_INFO -#define LOGI(format, ...) \ - if (systemCfg.workMode == WORK_MODE_NETWORK) { \ - Serial.printf(ANSI_COLOR_PURPLE "%d " ANSI_COLOR_RESET ANSI_COLOR_GREEN "[%s] " ANSI_COLOR_RESET format "\n", millis(), __func__, ##__VA_ARGS__); \ - } +#define LOGI(format, ...) \ + if (systemCfg.workMode == WORK_MODE_NETWORK) \ + { \ + Serial.printf(ANSI_COLOR_PURPLE "%d " ANSI_COLOR_RESET ANSI_COLOR_GREEN "[%s] " ANSI_COLOR_RESET format "\n", millis(), __func__, ##__VA_ARGS__); \ + } #else #define LOGI(format, ...) // Nothing #endif #if CURRENT_LOG_LEVEL >= LOG_LEVEL_DEBUG -#define LOGD(format, ...) \ - if (systemCfg.workMode == WORK_MODE_NETWORK) { \ - Serial.printf(ANSI_COLOR_PURPLE "%d " ANSI_COLOR_RESET ANSI_COLOR_YELLOW "[%s] " ANSI_COLOR_RESET format "\n", millis(), __func__, ##__VA_ARGS__); \ - } +#define LOGD(format, ...) \ + if (systemCfg.workMode == WORK_MODE_NETWORK) \ + { \ + Serial.printf(ANSI_COLOR_PURPLE "%d " ANSI_COLOR_RESET ANSI_COLOR_YELLOW "[%s] " ANSI_COLOR_RESET format "\n", millis(), __func__, ##__VA_ARGS__); \ + } #else #define LOGD(format, ...) // Nothing #endif - /* ----- Define functions | END -----*/ enum LEDMode diff --git a/src/const/hw.cpp b/src/const/hw.cpp index 222c16f..4a1bec5 100644 --- a/src/const/hw.cpp +++ b/src/const/hw.cpp @@ -3,9 +3,10 @@ // Ethernet configurations // !!! Don't forget to edit ETH_CFG_CNT !!! EthConfig ethConfigs[] = { - {.addr = 0, .pwrPin = 12, .mdcPin = 23, .mdiPin = 18, .phyType = ETH_PHY_LAN8720, .clkMode = ETH_CLOCK_GPIO17_OUT, .pwrAltPin = -1}, // 0 Olimex-ESP32-POE - {.addr = 1, .pwrPin = 16, .mdcPin = 23, .mdiPin = 18, .phyType = ETH_PHY_LAN8720, .clkMode = ETH_CLOCK_GPIO0_IN, .pwrAltPin = -1}, // 1 WT32-ETH01 - {.addr = 0, .pwrPin = -1, .mdcPin = 23, .mdiPin = 18, .phyType = ETH_PHY_LAN8720, .clkMode = ETH_CLOCK_GPIO17_OUT, .pwrAltPin = 5}, // 2 T-Internet-POE + {.addr = 0, .pwrPin = 12, .mdcPin = 23, .mdiPin = 18, .phyType = ETH_PHY_LAN8720, .clkMode = ETH_CLOCK_GPIO17_OUT}, // .pwrAltPin = -1}, // 0 Olimex-ESP32-POE + {.addr = 1, .pwrPin = 16, .mdcPin = 23, .mdiPin = 18, .phyType = ETH_PHY_LAN8720, .clkMode = ETH_CLOCK_GPIO0_IN}, // .pwrAltPin = -1}, // 1 WT32-ETH01 + {.addr = 0, .pwrPin = 5, .mdcPin = 23, .mdiPin = 18, .phyType = ETH_PHY_LAN8720, .clkMode = ETH_CLOCK_GPIO17_OUT}, // .pwrAltPin = -1}, // 2 T-Internet-POE / UZG01 / HamGeek POE Plus + // {.addr = 0, .pwrPin = 5, .mdcPin = 23, .mdiPin = 18, .phyType = ETH_PHY_LAN8720, .clkMode = ETH_CLOCK_GPIO17_OUT}, // .pwrAltPin = -1}, // 3 HamGeek POE Plus }; // ZigBee configurations @@ -14,11 +15,11 @@ ZbConfig zbConfigs[] = { {.txPin = 4, .rxPin = 36, .rstPin = 16, .bslPin = 32}, // 0 {.txPin = 17, .rxPin = 5, .rstPin = 33, .bslPin = 32}, // 1 {.txPin = 33, .rxPin = 32, .rstPin = 12, .bslPin = 14}, // 2 - {.txPin = 4, .rxPin = 36, .rstPin = 5, .bslPin = 16}, // 3 - {.txPin = 5, .rxPin = 17, .rstPin = 33, .bslPin = 32}, // 4 - {.txPin = 16, .rxPin = 5, .rstPin = 33, .bslPin = 32}, // 5 - {.txPin = 16, .rxPin = 5, .rstPin = 13, .bslPin = 4}, // 6 - {.txPin = 4, .rxPin = 36, .rstPin = 5, .bslPin = 16}, // 7 + {.txPin = 5, .rxPin = 17, .rstPin = 33, .bslPin = 32}, // 3 TubesZB-eth_usb + {.txPin = 16, .rxPin = 5, .rstPin = 33, .bslPin = 32}, // 4 TubesZB-poe + {.txPin = 16, .rxPin = 5, .rstPin = 13, .bslPin = 4}, // 5 TubesZB-poe-2022 + {.txPin = 4, .rxPin = 36, .rstPin = 5, .bslPin = 16}, // 6 TubesZB-poe-2023 + {.txPin = 22, .rxPin = 23, .rstPin = 18, .bslPin = 19}, // 7 SLS-classic }; // Mist configurations @@ -27,21 +28,24 @@ MistConfig mistConfigs[] = { {.btnPin = -1, .btnPlr = 0, .uartSelPin = -1, .uartSelPlr = 0, .ledModePin = -1, .ledModePlr = 0, .ledPwrPin = -1, .ledPwrPlr = 0}, // 0 {.btnPin = 35, .btnPlr = 1, .uartSelPin = 33, .uartSelPlr = 1, .ledModePin = 12, .ledModePlr = 1, .ledPwrPin = 14, .ledPwrPlr = 1}, // 1 {.btnPin = 35, .btnPlr = 1, .uartSelPin = 4, .uartSelPlr = 1, .ledModePin = 12, .ledModePlr = 1, .ledPwrPin = 14, .ledPwrPlr = 1}, // 2 + {.btnPin = 33, .btnPlr = 1, .uartSelPin = -1, .uartSelPlr = 0, .ledModePin = -1, .ledModePlr = 0, .ledPwrPin = -1, .ledPwrPlr = 0}, // 3 SLS-classic }; // Board configurations // !!! Don't forget to edit BOARD_CFG_CNT !!! BrdConfigStruct brdConfigs[] = { - {"UZG-01", .ethConfigIndex = 2, .zbConfigIndex = 0, .mistConfigIndex = 1}, - {"SLZB-06", .ethConfigIndex = 1, .zbConfigIndex = 1, .mistConfigIndex = 2}, - {"WT32-ETH01", .ethConfigIndex = 1, .zbConfigIndex = 1, .mistConfigIndex = 0}, - {"T-Internet-POE", .ethConfigIndex = 2, .zbConfigIndex = 0, .mistConfigIndex = 0}, - {"Olimex-ESP32-POE", .ethConfigIndex = 0, .zbConfigIndex = 0, .mistConfigIndex = 0}, - {"China-GW", .ethConfigIndex = 0, .zbConfigIndex = 2, .mistConfigIndex = 0}, - {"TubesZB-eth", .ethConfigIndex = 1, .zbConfigIndex = 1, .mistConfigIndex = 0}, - {"TubesZB-eth_usb", .ethConfigIndex = 1, .zbConfigIndex = 4, .mistConfigIndex = 0}, - {"TubesZB-poe", .ethConfigIndex = 0, .zbConfigIndex = 5, .mistConfigIndex = 0}, - {"TubesZB-poe-2022", .ethConfigIndex = 0, .zbConfigIndex = 6, .mistConfigIndex = 0}, - {"TubesZB-poe-2023", .ethConfigIndex = 0, .zbConfigIndex = 7, .mistConfigIndex = 0}, - {"CZC-1.0", .ethConfigIndex = 2, .zbConfigIndex = 0, .mistConfigIndex = 1}, + {"UZG-01", .ethConfigIndex = 2, .zbConfigIndex = 0, .mistConfigIndex = 1}, // 0 + {"SLZB-06", .ethConfigIndex = 1, .zbConfigIndex = 1, .mistConfigIndex = 2}, // 1 + {"WT32-ETH01", .ethConfigIndex = 1, .zbConfigIndex = 1, .mistConfigIndex = 0}, // 2 + {"T-Internet-POE", .ethConfigIndex = 2, .zbConfigIndex = 0, .mistConfigIndex = 0}, // 3 + {"Olimex-ESP32-POE", .ethConfigIndex = 0, .zbConfigIndex = 0, .mistConfigIndex = 0}, // 4 + {"China-GW", .ethConfigIndex = 0, .zbConfigIndex = 2, .mistConfigIndex = 0}, // 5 + {"TubesZB-eth", .ethConfigIndex = 1, .zbConfigIndex = 1, .mistConfigIndex = 0}, // 6 + {"TubesZB-eth_usb", .ethConfigIndex = 1, .zbConfigIndex = 3, .mistConfigIndex = 0}, // 7 + {"TubesZB-poe", .ethConfigIndex = 0, .zbConfigIndex = 4, .mistConfigIndex = 0}, // 8 + {"TubesZB-poe-2022", .ethConfigIndex = 0, .zbConfigIndex = 5, .mistConfigIndex = 0}, // 9 + {"TubesZB-poe-2023", .ethConfigIndex = 0, .zbConfigIndex = 6, .mistConfigIndex = 0}, // 10 + {"CZC-1.0", .ethConfigIndex = 2, .zbConfigIndex = 0, .mistConfigIndex = 1}, // 11 + {"SLS-classic", .ethConfigIndex = -1, .zbConfigIndex = 7, .mistConfigIndex = 3}, // 12 + {"HG POE+", .ethConfigIndex = 2, .zbConfigIndex = 0, .mistConfigIndex = 1}, // 13 }; \ No newline at end of file diff --git a/src/const/hw.h b/src/const/hw.h index 11da41c..bb5e1c2 100644 --- a/src/const/hw.h +++ b/src/const/hw.h @@ -45,7 +45,7 @@ struct BrdConfigStruct #define ETH_CFG_CNT 3 #define ZB_CFG_CNT 8 -#define MIST_CFG_CNT 3 +#define MIST_CFG_CNT 4 #define BOARD_CFG_CNT 14 struct ThisConfigStruct diff --git a/src/const/keys.cpp b/src/const/keys.cpp index 4faa6ca..a490ef0 100644 --- a/src/const/keys.cpp +++ b/src/const/keys.cpp @@ -10,6 +10,8 @@ const char *wifiMaskKey = "wifiMask"; const char *wifiGateKey = "wifiGate"; const char *wifiDns1Key = "wifiDns1"; const char *wifiDns2Key = "wifiDns2"; +const char *wifiPwrKey = "wifiPwr"; +const char *wifiModeKey = "wifiMode"; const char *ethEnblKey = "ethEnbl"; const char *ethDhcpKey = "ethDhcp"; const char *ethIpKey = "ethIp"; @@ -51,7 +53,7 @@ const char *discoveryKey = "discovery"; const char *reconnectIntKey = "reconnectInt"; const char *systemConfigKey = "system-config"; -//const char *keepWebKey = "keepWeb"; +// const char *keepWebKey = "keepWeb"; const char *disableWebKey = "disableWeb"; const char *webAuthKey = "webAuth"; const char *webUserKey = "webUser"; @@ -73,11 +75,15 @@ const char *nmStartHourKey = "startHour"; const char *nmEndHourKey = "endHour"; const char *nmEnableKey = "nightMode"; +const char *updCheckTimeKey = "updHour"; +const char *updCheckDayKey = "updDays"; +const char *updAutoInstKey = "autoIns"; + const char *systemVarsKey = "system-vars"; const char *hwBtnIsKey = "hwBtnIs"; const char *hwLedUsbIsKey = "hwLedUsbIs"; const char *hwLedPwrIsKey = "hwLedPwrIs"; -//const char *hwUartSelIsKey = "hwUartSelIs"; +// const char *hwUartSelIsKey = "hwUartSelIs"; const char *hwZigbeeIsKey = "hwZigbeeIs"; const char *workModeKey = "workMode"; const char *connectedSocketKey = "connectedSocket"; @@ -94,8 +100,18 @@ const char *vpnHnInitKey = "vpnHnInit"; const char *mqttConnKey = "mqttConn"; const char *mqttReconnectTimeKey = "mqttReconnectTime"; const char *mqttHeartbeatTimeKey = "mqttHeartbeatTime"; -//const char *zbLedStateKey = "zbLedState"; -//const char *zbFlashingKey = "zbFlashing"; +// const char *zbLedStateKey = "zbLedState"; +// const char *zbFlashingKey = "zbFlashing"; const char *deviceIdKey = "deviceId"; +const char *timeZoneNameKey = "timeZoneName"; +const char *zbRoleKey = "zbRole"; +const char *zbFwKey = "zbFw"; +const char *zbUpdAvailKey = "zbUpdAvail"; +const char *espUpdAvailKey = "espUpdAvail"; -const char *timeZoneNameKey = "timeZoneName"; \ No newline at end of file +const char *tagZB_FW_info = "zb.fi"; +const char *tagZB_FW_file = "zb.ff"; +const char *tagZB_FW_err = "zb.fe"; +const char *tagZB_FW_prgs = "zb.fp"; +const char *tagZB_NV_prgs = "zb.nv"; +const char *tagESP_FW_prgs = "esp.fp"; \ No newline at end of file diff --git a/src/const/keys.h b/src/const/keys.h index 567abc2..d0b8225 100644 --- a/src/const/keys.h +++ b/src/const/keys.h @@ -12,6 +12,8 @@ extern const char *wifiMaskKey; extern const char *wifiGateKey; extern const char *wifiDns1Key; extern const char *wifiDns2Key; +extern const char *wifiPwrKey; +extern const char *wifiModeKey; extern const char *ethEnblKey; extern const char *ethDhcpKey; extern const char *ethIpKey; @@ -70,6 +72,9 @@ extern const char *ntpServ2Key; extern const char *nmStartHourKey; extern const char *nmEndHourKey; extern const char *nmEnableKey; +extern const char *updCheckTimeKey; +extern const char *updCheckDayKey; +extern const char *updAutoInstKey; extern const char *systemVarsKey; extern const char *hwBtnIsKey; extern const char *hwLedUsbIsKey; @@ -95,5 +100,15 @@ extern const char *zbLedStateKey; extern const char *zbFlashingKey; extern const char *deviceIdKey; extern const char *timeZoneNameKey; +extern const char *zbRoleKey; +extern const char *zbFwKey; +extern const char *zbUpdAvailKey; +extern const char *espUpdAvailKey; +extern const char *tagZB_FW_info; +extern const char *tagZB_FW_file; +extern const char *tagZB_FW_err; +extern const char *tagZB_FW_prgs; +extern const char *tagZB_NV_prgs; +extern const char *tagESP_FW_prgs; #endif // XZG_KEYS_H diff --git a/src/etc.cpp b/src/etc.cpp index 31bf49c..bce72ac 100644 --- a/src/etc.cpp +++ b/src/etc.cpp @@ -318,6 +318,7 @@ void factoryReset() void setClock(void *pvParameters) { + checkDNS(); configTime(0, 0, systemCfg.ntpServ1, systemCfg.ntpServ2); const time_t targetTime = 946684800; // 946684800 - is 01.01.2000 in timestamp @@ -340,7 +341,7 @@ void setClock(void *pvParameters) { // LOGD("Current GMT time: %s", String(asctime(&timeinfo)).c_str()); - char *zoneToFind = const_cast("Europe/Kiev"); + char *zoneToFind = const_cast(NTP_TIME_ZONE); if (systemCfg.timeZone) { zoneToFind = systemCfg.timeZone; @@ -399,9 +400,7 @@ void nmDeactivate() setLedsDisable(); } -IPAddress savedWifiDNS; -IPAddress savedEthDNS; -void checkDNS(bool setup = false) +void checkDNS(bool setup) { const char *wifiKey = "WiFi"; const char *ethKey = "ETH"; @@ -413,82 +412,106 @@ void checkDNS(bool setup = false) if (networkCfg.wifiEnable) { IPAddress currentWifiDNS = WiFi.dnsIP(); - char dnsStrW[16]; - snprintf(dnsStrW, sizeof(dnsStrW), "%u.%u.%u.%u", currentWifiDNS[0], currentWifiDNS[1], currentWifiDNS[2], currentWifiDNS[3]); - - int lastDot = -1; - for (int i = 0; dnsStrW[i] != '\0'; i++) + if (currentWifiDNS != vars.savedWifiDNS) { - if (dnsStrW[i] == '.') + char dnsStrW[16]; + snprintf(dnsStrW, sizeof(dnsStrW), "%u.%u.%u.%u", currentWifiDNS[0], currentWifiDNS[1], currentWifiDNS[2], currentWifiDNS[3]); + + int lastDot = -1; + for (int i = 0; dnsStrW[i] != '\0'; i++) { - lastDot = i; + if (dnsStrW[i] == '.') + { + lastDot = i; + } } - } - int fourthPartW = atoi(dnsStrW + lastDot + 1); + int fourthPartW = atoi(dnsStrW + lastDot + 1); - if (setup && fourthPartW != 0) - { - savedWifiDNS = currentWifiDNS; - snprintf(buffer, sizeof(buffer), "%s %s %s - %s", dnsTagKey, savedKey, wifiKey, dnsStrW); - printLogMsg(buffer); - } - else - { - if (savedWifiDNS && currentWifiDNS != savedWifiDNS) + if (setup && fourthPartW != 0) { - WiFi.config(WiFi.localIP(), WiFi.gatewayIP(), WiFi.subnetMask(), savedWifiDNS); - snprintf(buffer, sizeof(buffer), "%s %s %s - %s", dnsTagKey, restoredKey, wifiKey, savedWifiDNS.toString().c_str()); + vars.savedWifiDNS = currentWifiDNS; + snprintf(buffer, sizeof(buffer), "%s %s %s - %s", dnsTagKey, savedKey, wifiKey, dnsStrW); printLogMsg(buffer); } + else + { + if (vars.savedWifiDNS) + { + WiFi.config(WiFi.localIP(), WiFi.gatewayIP(), WiFi.subnetMask(), vars.savedWifiDNS); + snprintf(buffer, sizeof(buffer), "%s %s %s - %s", dnsTagKey, restoredKey, wifiKey, vars.savedWifiDNS.toString().c_str()); + printLogMsg(buffer); + } + } } } if (networkCfg.ethEnable) { IPAddress currentEthDNS = ETH.dnsIP(); - char dnsStrE[16]; - snprintf(dnsStrE, sizeof(dnsStrE), "%u.%u.%u.%u", currentEthDNS[0], currentEthDNS[1], currentEthDNS[2], currentEthDNS[3]); - - int lastDot = -1; - for (int i = 0; dnsStrE[i] != '\0'; i++) + if (currentEthDNS != vars.savedEthDNS) { - if (dnsStrE[i] == '.') + char dnsStrE[16]; + snprintf(dnsStrE, sizeof(dnsStrE), "%u.%u.%u.%u", currentEthDNS[0], currentEthDNS[1], currentEthDNS[2], currentEthDNS[3]); + + int lastDot = -1; + for (int i = 0; dnsStrE[i] != '\0'; i++) { - lastDot = i; + if (dnsStrE[i] == '.') + { + lastDot = i; + } } - } - int fourthPartE = atoi(dnsStrE + lastDot + 1); + int fourthPartE = atoi(dnsStrE + lastDot + 1); - if (setup && fourthPartE != 0) - { - savedEthDNS = currentEthDNS; - snprintf(buffer, sizeof(buffer), "%s %s %s - %s", dnsTagKey, savedKey, ethKey, dnsStrE); - printLogMsg(buffer); - } - else - { - if (savedEthDNS && currentEthDNS != savedEthDNS) + if (setup && fourthPartE != 0) { - ETH.config(ETH.localIP(), ETH.gatewayIP(), ETH.subnetMask(), savedEthDNS); - snprintf(buffer, sizeof(buffer), "%s %s %s - %s", dnsTagKey, restoredKey, ethKey, savedEthDNS.toString().c_str()); + vars.savedEthDNS = currentEthDNS; + snprintf(buffer, sizeof(buffer), "%s %s %s - %s", dnsTagKey, savedKey, ethKey, dnsStrE); printLogMsg(buffer); } + else + { + if (vars.savedEthDNS) + { + ETH.config(ETH.localIP(), ETH.gatewayIP(), ETH.subnetMask(), vars.savedEthDNS); + snprintf(buffer, sizeof(buffer), "%s %s %s - %s", dnsTagKey, restoredKey, ethKey, vars.savedEthDNS.toString().c_str()); + printLogMsg(buffer); + } + } } } } -void reCheckDNS() +/*void reCheckDNS() { checkDNS(); -} +}*/ void setupCron() { - Cron.create(const_cast("0 */1 * * * *"), reCheckDNS, false); + //Cron.create(const_cast("30 */1 * * * *"), reCheckDNS, false); - Cron.create(const_cast("0 0 */1 * * *"), checkEspUpdateAvail, false); + // const String time = systemCfg.updCheckTime; + static char formattedTime[16]; + int seconds, hours, minutes; + + String wday = systemCfg.updCheckDay; + + seconds = random(1, 59); + + // char timeArray[6]; + // String(systemCfg.updCheckTime).toCharArray(timeArray, sizeof(timeArray)); + + sscanf(systemCfg.updCheckTime, "%d:%d", &hours, &minutes); + + snprintf(formattedTime, sizeof(formattedTime), "%d %d %d * * %s", seconds, minutes, hours, wday); + + // LOGD("UPD cron %s", String(formattedTime)); + printLogMsg("[UPD_CHK] cron " + String(formattedTime)); + + Cron.create(const_cast(formattedTime), checkUpdateAvail, false); // 0 0 */6 * * * if (systemCfg.nmEnable) { @@ -604,7 +627,7 @@ ThisConfigStruct *findBrdConfig(int searchId = 0) bool zbOk = false; static ThisConfigStruct bestConfig; - bestConfig.eth = {.addr = -1, .pwrPin = -1, .mdcPin = -1, .mdiPin = -1, .phyType = ETH_PHY_LAN8720, .clkMode = ETH_CLOCK_GPIO17_OUT, .pwrAltPin = -1}; + bestConfig.eth = {.addr = -1, .pwrPin = -1, .mdcPin = -1, .mdiPin = -1, .phyType = ETH_PHY_LAN8720, .clkMode = ETH_CLOCK_GPIO17_OUT};// .pwrAltPin = -1}; bestConfig.zb = {.txPin = -1, .rxPin = -1, .rstPin = -1, .bslPin = -1}; memset(&bestConfig.mist, -1, sizeof(bestConfig.mist)); strlcpy(bestConfig.board, "Unknown", sizeof(bestConfig.board)); @@ -619,13 +642,13 @@ ThisConfigStruct *findBrdConfig(int searchId = 0) if (brdIdx == 3) // T-Internet-POE { - pinMode(ethConfigs[ethIdx].pwrAltPin, OUTPUT); + pinMode(ethConfigs[ethIdx].pwrPin, OUTPUT); delay(50); - digitalWrite(ethConfigs[ethIdx].pwrAltPin, LOW); + digitalWrite(ethConfigs[ethIdx].pwrPin, LOW); delay(50); - pinMode(ethConfigs[ethIdx].pwrAltPin, INPUT); + pinMode(ethConfigs[ethIdx].pwrPin, INPUT); delay(50); - bool pwrPinState = digitalRead(ethConfigs[ethIdx].pwrAltPin); + bool pwrPinState = digitalRead(ethConfigs[ethIdx].pwrPin); if (pwrPinState) { LOGW("%s", "Looks like not T-Internet-POE!"); @@ -633,7 +656,7 @@ ThisConfigStruct *findBrdConfig(int searchId = 0) } } - if (ETH.begin(ethConfigs[ethIdx].addr, ethConfigs[ethIdx].pwrPin, ethConfigs[ethIdx].mdcPin, ethConfigs[ethIdx].mdiPin, ethConfigs[ethIdx].phyType, ethConfigs[ethIdx].clkMode, ethConfigs[ethIdx].pwrAltPin)) + if (ETH.begin(ethConfigs[ethIdx].addr, ethConfigs[ethIdx].pwrPin, ethConfigs[ethIdx].mdcPin, ethConfigs[ethIdx].mdiPin, ethConfigs[ethIdx].phyType, ethConfigs[ethIdx].clkMode))// ethConfigs[ethIdx].pwrAltPin)) { ethOk = true; LOGD("Ethernet config OK: %d", ethIdx); @@ -724,6 +747,7 @@ ThisConfigStruct *findBrdConfig(int searchId = 0) void wgBegin() { + checkDNS(); if (!wg.is_initialized()) { @@ -913,18 +937,70 @@ void ledTask(void *parameter) } } -void checkEspUpdateAvail() +int compareVersions(String v1, String v2) +{ + int v1_major = v1.substring(0, v1.indexOf('.')).toInt(); + int v2_major = v2.substring(0, v2.indexOf('.')).toInt(); + + if (v1_major != v2_major) + { + return v1_major - v2_major; + } + + String v1_suffix = v1.substring(v1.indexOf('.') + 1); + String v2_suffix = v2.substring(v2.indexOf('.') + 1); + + if (v1_suffix.length() == 0) + return -1; + if (v2_suffix.length() == 0) + return 1; + + return v1_suffix.compareTo(v2_suffix); +} + +void checkUpdateAvail() { - String latestReleaseUrl = fetchGitHubReleaseInfo(); - String latestVersion = extractVersionFromURL(latestReleaseUrl); + const char *ESPkey = "ESP"; + const char *ZBkey = "ZB"; + const char *FoundKey = "Found "; + const char *NewFwKey = " new fw: "; + const char *TryKey = "try to install"; + String latestReleaseUrlEsp = fetchLatestEspFw(); + String latestReleaseUrlZb = fetchLatestZbFw(); + String latestVersionEsp = extractVersionFromURL(latestReleaseUrlEsp); + String latestVersionZb = extractVersionFromURL(latestReleaseUrlZb); + + LOGD("%s %s", ESPkey, latestVersionEsp.c_str()); + LOGD("%s %s", ZBkey, latestVersionZb.c_str()); - if (latestVersion.length() > 0 && latestVersion > VERSION) + if (latestVersionEsp.length() > 0 && compareVersions(latestVersionEsp, VERSION) > 0) { vars.updateEspAvail = true; + printLogMsg(String(FoundKey) + String(ESPkey) + String(NewFwKey) + latestVersionEsp); + if (systemCfg.updAutoInst) + { + printLogMsg(String(TryKey)); + getEspUpdate(latestReleaseUrlEsp); + } } else { vars.updateEspAvail = false; } - LOGD("%s", String(vars.updateEspAvail)); + + if (CCTool.chip.fwRev > 0 && latestVersionZb.length() > 0 && compareVersions(latestVersionZb, String(CCTool.chip.fwRev)) > 0) + { + vars.updateZbAvail = true; + printLogMsg(String(FoundKey) + String(ZBkey) + String(NewFwKey) + latestVersionZb); + if (systemCfg.updAutoInst) + { + printLogMsg(String(TryKey)); + flashZbUrl(latestReleaseUrlZb); + ESP.restart(); + } + } + else + { + vars.updateZbAvail = false; + } } diff --git a/src/etc.h b/src/etc.h index 89c9343..ca6cd10 100644 --- a/src/etc.h +++ b/src/etc.h @@ -27,7 +27,7 @@ void factoryReset(); void setLedsDisable(bool all = false); void cronTest(); void nmActivate(); -void checkDNS(bool setup); +void checkDNS(bool setup = false); void setupCron(); void setClock(void *pvParameters); @@ -43,4 +43,4 @@ void hnBegin(); void ledTask(void *parameter); String getTime(); -void checkEspUpdateAvail(); +void checkUpdateAvail(); diff --git a/src/main.cpp b/src/main.cpp index 13140d9..d900bb4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -76,7 +76,7 @@ void initLan() { LOGD("Try to use %s", hwConfig.board); - if (ETH.begin(hwConfig.eth.addr, hwConfig.eth.pwrPin, hwConfig.eth.mdcPin, hwConfig.eth.mdiPin, hwConfig.eth.phyType, hwConfig.eth.clkMode, hwConfig.eth.pwrAltPin)) + if (ETH.begin(hwConfig.eth.addr, hwConfig.eth.pwrPin, hwConfig.eth.mdcPin, hwConfig.eth.mdiPin, hwConfig.eth.phyType, hwConfig.eth.clkMode))// hwConfig.eth.pwrAltPin)) { String modeString = networkCfg.ethDhcp ? "DHCP" : "Static"; LOGD("LAN start ok, %s", modeString); @@ -142,54 +142,54 @@ void startServers(bool usb = false) void handleTmrNetworkOverseer() { - switch (systemCfg.workMode) + // switch (systemCfg.workMode) + //{ + // case WORK_MODE_NETWORK: + if (!networkCfg.wifiEnable && !networkCfg.ethEnable) { - case WORK_MODE_NETWORK: - if (!networkCfg.wifiEnable && !networkCfg.ethEnable) + LOGD("Both interfaces disabled. Start AP"); + startAP(true); + connectWifi(); + } + if (networkCfg.wifiEnable) + { + LOGD("WiFi.status = %s", String(WiFi.status())); + + if (WiFi.isConnected()) { - LOGD("Both interfaces disabled. Start AP"); - startAP(true); - connectWifi(); + LOGD("WIFI CONNECTED"); + // startServers(); + tmrNetworkOverseer.stop(); } - if (networkCfg.wifiEnable) + else { - LOGD("WiFi.status = %s", String(WiFi.status())); - - if (WiFi.isConnected()) + if (tmrNetworkOverseer.counter() > overseerMaxRetry) { - LOGD("WIFI CONNECTED"); - // startServers(); - tmrNetworkOverseer.stop(); - } - else - { - if (tmrNetworkOverseer.counter() > overseerMaxRetry) - { - LOGD("WIFI counter overflow"); - startAP(true); - connectWifi(); - } + LOGD("WIFI counter overflow"); + startAP(true); + connectWifi(); } } - if (networkCfg.ethEnable) + } + if (networkCfg.ethEnable) + { + if (vars.connectedEther) { - if (vars.connectedEther) - { - LOGD("LAN CONNECTED"); - // startServers(); - tmrNetworkOverseer.stop(); - } - else + LOGD("LAN CONNECTED"); + // startServers(); + tmrNetworkOverseer.stop(); + } + else + { + if (tmrNetworkOverseer.counter() > overseerMaxRetry) { - if (tmrNetworkOverseer.counter() > overseerMaxRetry) - { - LOGD("LAN counter overflow"); - startAP(true); - } + LOGD("LAN counter overflow"); + startAP(true); } } - break; - case WORK_MODE_USB: + } + // break; + /*case WORK_MODE_USB: if (tmrNetworkOverseer.counter() > 3) { // 10 seconds for wifi connect if (WiFi.isConnected()) @@ -217,8 +217,8 @@ void handleTmrNetworkOverseer() } break; default: - break; - } + break;*/ + //} } void NetworkEvent(WiFiEvent_t event) @@ -278,6 +278,7 @@ void NetworkEvent(WiFiEvent_t event) WiFi.gatewayIP().toString().c_str(), WiFi.dnsIP().toString().c_str()); checkDNS(true); + LOGD("WiFi TX %s", String(WiFi.getTxPower())); break; case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: // SYSTEM_EVENT_STA_DISCONNECTED: LOGD("%s STA DISCONNECTED", wifiKey); @@ -349,7 +350,10 @@ void connectWifi() LOGD("timeout"); } WiFi.persistent(false); - esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B); + + // TO-DO protocol and power setup via GUI + esp_wifi_set_protocol(WIFI_IF_STA, networkCfg.wifiMode); + if ((strlen(networkCfg.wifiSsid) >= 2) && (strlen(networkCfg.wifiPass) >= 8)) { LOGD("Ok SSID & PASS"); @@ -381,6 +385,9 @@ void connectWifi() WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); WiFi.begin(networkCfg.wifiSsid, networkCfg.wifiPass); + WiFi.setAutoReconnect(true); + WiFi.setTxPower(networkCfg.wifiPower); + LOGD("WiFi TX %s", String(WiFi.getTxPower())); LOGD("WiFi.begin"); } else @@ -573,7 +580,17 @@ void setup() printNVSFreeSpace(); - zbFwCheck(); + if (systemCfg.zbRole == COORDINATOR) + { + zbFwCheck(); + } + else { + LOGI("[ZB] role: %s", String(systemCfg.zbRole)); + } + LOGI("[ESP] FW: %s", String(VERSION)); + + if (!vars.apStarted) + checkUpdateAvail(); LOGD("done"); } diff --git a/src/mqtt.cpp b/src/mqtt.cpp index bf30cb4..479daa1 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -67,9 +67,10 @@ String getWlanIp() } String getWlanSsid() -{ +{ String ssid = WiFi.SSID(); - if (ssid.isEmpty()) { + if (ssid.isEmpty()) + { ssid = "-"; } return ssid; @@ -97,7 +98,16 @@ String getConnections() String getZigbeeFWver() { - return String(CCTool.chip.fwRev); + String fw; + if (CCTool.chip.fwRev > 0) + { + fw = CCTool.chip.fwRev; + } + else + { + fw = systemCfg.zbFw; + } + return fw; } String getZigbeeHWrev() @@ -119,6 +129,27 @@ String getWorkMode() return "Error"; } +String getRole() +{ + String role; + switch (systemCfg.zbRole) + { + case COORDINATOR: + role = "Coordinator"; + break; + case ROUTER: + role = "Router"; + break; + case OPENTHREAD: + role = "Thread"; + break; + default: + role = "Unknown"; + break; + } + return role; +} + mqttTopicsConfig mqttTopicsConfigs[] = { {.name = "Restart ESP", .sensorType = haButton, @@ -154,6 +185,11 @@ mqttTopicsConfig mqttTopicsConfigs[] = { .sensorId = "update_esp", .stateTopic = "/io/update_esp", .deviceClass = "update"}, + {.name = "Update Zigbee", + .sensorType = haBinarySensor, + .sensorId = "update_zb", + .stateTopic = "/io/update_zb", + .deviceClass = "update"}, {.name = "Uptime", .sensorType = haSensor, .sensorId = "uptime", @@ -234,11 +270,19 @@ mqttTopicsConfig mqttTopicsConfigs[] = { .stateTopic = stateTopic, .icon = "mdi:access-point", .valueTemplate = "{{ value_json.zbhw }}", - .getSensorValue = getZigbeeHWrev}}; + .getSensorValue = getZigbeeHWrev}, + {.name = "Zigbee Role", + .sensorType = haSensor, + .sensorId = "zbrl", + .stateTopic = stateTopic, + .icon = "mdi:access-point", + .valueTemplate = "{{ value_json.zbrl }}", + .getSensorValue = getRole}}; void mqttConnectSetup() { LOGD("mqttConnectSetup"); + checkDNS(); if (mqttCfg.reconnectInt == 0) { @@ -266,25 +310,25 @@ void mqttConnectSetup() uint16_t keepAlive = mqttCfg.updateInt + 10; mqttClient.setKeepAlive(keepAlive); - const char* clientId = vars.deviceId; + const char *clientId = vars.deviceId; mqttClient.setClientId(clientId); mqttClient.setCredentials(mqttCfg.user, mqttCfg.pass); - //String topic = String(mqttCfg.topic) + "/avty"; - //mqttClient.setWill(topic.c_str(), 1, true, "offline"); + // String topic = String(mqttCfg.topic) + "/avty"; + // mqttClient.setWill(topic.c_str(), 1, true, "offline"); mqttClient.setServer(mqttCfg.server, mqttCfg.port); -/* NO SSL SUPPORT in current SDK -#if ASYNC_TCP_SSL_ENABLED - mqttClient.setSecure(MQTT_SECURE); - if (MQTT_SECURE) - { - mqttClient.addServerFingerprint((const uint8_t[])MQTT_SERVER_FINGERPRINT); - } -#endif -*/ + /* NO SSL SUPPORT in current SDK + #if ASYNC_TCP_SSL_ENABLED + mqttClient.setSecure(MQTT_SECURE); + if (MQTT_SECURE) + { + mqttClient.addServerFingerprint((const uint8_t[])MQTT_SERVER_FINGERPRINT); + } + #endif + */ mqttClient.onConnect(onMqttConnect); mqttClient.onDisconnect(onMqttDisconnect); @@ -311,7 +355,10 @@ void onMqttConnect(bool sessionPresent) vars.mqttConn = true; - mqttPublishDiscovery(); + if (mqttCfg.discovery) + { + mqttPublishDiscovery(); + } mqttPublishIo("rst_esp", 0); mqttPublishIo("rst_zig", 0); @@ -319,6 +366,7 @@ void onMqttConnect(bool sessionPresent) bool socket_state = vars.connectedClients ? 1 : 0; mqttPublishIo("socket", socket_state); mqttPublishIo("update_esp", vars.updateEspAvail); + mqttPublishIo("update_zb", vars.updateZbAvail); mqttPublishState(); mqttPublishAvail(); diff --git a/src/version.h b/src/version.h index 613a26a..eb05108 100644 --- a/src/version.h +++ b/src/version.h @@ -1,4 +1,4 @@ // AUTO GENERATED FILE #ifndef VERSION - #define VERSION "20240603" + #define VERSION "20240607" #endif diff --git a/src/web.cpp b/src/web.cpp index 2cf3fa1..fa508d2 100644 --- a/src/web.cpp +++ b/src/web.cpp @@ -108,7 +108,6 @@ extern bool loadFileConfigWg(); WebServer serverWeb(80); -// HTTPClient clientWeb; WiFiClient eventsClient; void webServerHandleClient() @@ -487,6 +486,7 @@ void handleApi() const char *argConf = "conf"; const char *argLed = "led"; const char *argAct = "act"; + const char *errLink = "Error getting link"; if (serverWeb.hasArg(argCmd)) { @@ -524,15 +524,14 @@ void handleApi() getEspUpdate(serverWeb.arg(argUrl)); else { - String link = fetchGitHubReleaseInfo(); - LOGD("%s", link.c_str()); + String link = fetchLatestEspFw(); if (link) { getEspUpdate(link); } else { - LOGW("Error getting link"); + LOGW("%s", String(errLink)); } } break; @@ -607,12 +606,18 @@ void handleApi() break; case CMD_ZB_FLASH: if (serverWeb.hasArg(argUrl)) - { flashZbUrl(serverWeb.arg(argUrl)); - } else { - flashZbUrl("https://github.com/xyzroe/XZG/raw/zb_fws/ti/coordinator/CC1352P2_CC2652P_launchpad_coordinator_20240315.bin"); + String link = fetchLatestZbFw(); + if (link) + { + flashZbUrl(link); + } + else + { + LOGW("%s", String(errLink)); + } } break; default: @@ -906,6 +911,7 @@ void updateWebTask(void *parameter) { String root_data = getRootData(true); printEachKeyValuePair(root_data); + root_data = String(); // free memory vTaskDelayUntil(&lastWakeTime, pdMS_TO_TICKS(systemCfg.refreshLogs * 1000)); } } @@ -1053,6 +1059,13 @@ void handleGeneral() doc[nmEnableKey] = checked; } + if (systemCfg.updAutoInst) + { + doc[updAutoInstKey] = checked; + } + doc[updCheckTimeKey] = systemCfg.updCheckTime; + doc[updCheckDayKey] = systemCfg.updCheckDay; + serializeJson(doc, result); serverWeb.sendHeader(respHeaderName, result); @@ -1136,6 +1149,63 @@ void handleNetwork() doc[wifiDns1Key] = networkCfg.wifiDns1; doc[wifiDns2Key] = networkCfg.wifiDns2; + switch (networkCfg.wifiMode) + { + case WIFI_PROTOCOL_11B: + doc["1"] = checked; + break; + case WIFI_PROTOCOL_11G: + doc["2"] = checked; + break; + case WIFI_PROTOCOL_11N: + doc["4"] = checked; + break; + case WIFI_PROTOCOL_LR: + doc["8"] = checked; + break; + default: + break; + } + + switch (networkCfg.wifiPower) + { + case WIFI_POWER_19_5dBm: + doc["78"] = checked; + break; + case WIFI_POWER_19dBm: + doc["76"] = checked; + break; + case WIFI_POWER_18_5dBm: + doc["74"] = checked; + break; + case WIFI_POWER_17dBm: + doc["68"] = checked; + break; + case WIFI_POWER_15dBm: + doc["60"] = checked; + break; + case WIFI_POWER_13dBm: + doc["52"] = checked; + break; + case WIFI_POWER_11dBm: + doc["44"] = checked; + break; + case WIFI_POWER_8_5dBm: + doc["34"] = checked; + break; + case WIFI_POWER_7dBm: + doc["28"] = checked; + break; + case WIFI_POWER_5dBm: + doc["20"] = checked; + break; + case WIFI_POWER_2dBm: + doc["8"] = checked; + break; + default: + break; + } + serializeJson(doc, result); serverWeb.sendHeader(respHeaderName, result); } @@ -1157,41 +1227,38 @@ void handleSerial() break; } - if (systemCfg.serialSpeed == 9600) + switch (systemCfg.serialSpeed) { + case 9600: doc["9600"] = checked; - } - else if (systemCfg.serialSpeed == 19200) - { + break; + case 19200: doc["19200"] = checked; - } - else if (systemCfg.serialSpeed == 38400) - { - doc["8400"] = checked; - } - else if (systemCfg.serialSpeed == 57600) - { + break; + case 38400: + doc["38400"] = checked; + break; + case 57600: doc["57600"] = checked; - } - else if (systemCfg.serialSpeed == 115200) - { + break; + case 115200: doc["115200"] = checked; - } - else if (systemCfg.serialSpeed == 230400) - { + break; + case 230400: doc["230400"] = checked; - } - else if (systemCfg.serialSpeed == 460800) - { + break; + case 460800: doc["460800"] = checked; - } - else - { + break; + default: doc["115200"] = checked; + break; } doc[socketPortKey] = String(systemCfg.socketPort); + doc[zbRoleKey] = systemCfg.zbRole; + serializeJson(doc, result); serverWeb.sendHeader(respHeaderName, result); } @@ -1292,6 +1359,9 @@ String getRootData(bool update) const char *operationalMode = "operationalMode"; doc[operationalMode] = systemCfg.workMode; + + doc[espUpdAvailKey] = vars.updateEspAvail; + doc[zbUpdAvailKey] = vars.updateZbAvail; } // ETHERNET TAB @@ -1314,7 +1384,7 @@ String getRootData(bool update) doc[ethIpKey] = ETH.localIP().toString(); doc[ethMaskKey] = ETH.subnetMask().toString(); doc[ethGateKey] = ETH.gatewayIP().toString(); - doc[ethDns] = ETH.dnsIP().toString(); + doc[ethDns] = vars.savedEthDNS.toString();//ETH.dnsIP().toString(); } else { @@ -1322,7 +1392,7 @@ String getRootData(bool update) doc[ethIpKey] = networkCfg.ethDhcp ? noConn : ETH.localIP().toString(); doc[ethMaskKey] = networkCfg.ethDhcp ? noConn : ETH.subnetMask().toString(); doc[ethGateKey] = networkCfg.ethDhcp ? noConn : ETH.gatewayIP().toString(); - doc[ethDns] = networkCfg.ethDhcp ? noConn : ETH.dnsIP().toString(); + doc[ethDns] = networkCfg.ethDhcp ? noConn : vars.savedEthDNS.toString();//ETH.dnsIP().toString(); } } @@ -1353,7 +1423,16 @@ String getRootData(bool update) doc["espFlashSize"] = ESP.getFlashChipSize() / (1024 * 1024); - doc["zigbeeFwRev"] = String(CCTool.chip.fwRev); + // doc["zigbeeFwRev"] = String(CCTool.chip.fwRev); + if (CCTool.chip.fwRev > 0) + { + doc["zigbeeFwRev"] = String(CCTool.chip.fwRev); + } + else + { + doc["zigbeeFwRev"] = String(systemCfg.zbFw); + doc["zbFwSaved"] = true; + } doc["zigbeeHwRev"] = CCTool.chip.hwRev; @@ -1366,6 +1445,9 @@ String getRootData(bool update) doc["espFsSize"] = totalFs; doc["espFsUsed"] = usedFs; + + doc[zbRoleKey] = systemCfg.zbRole; + doc["zigbeeFwSaved"] = systemCfg.zbFw; } int heapSize = ESP.getHeapSize() / 1024; int heapFree = ESP.getFreeHeap() / 1024; @@ -1402,7 +1484,7 @@ String getRootData(bool update) doc[wifiIpKey] = WiFi.localIP().toString(); doc[wifiMaskKey] = WiFi.subnetMask().toString(); doc[wifiGateKey] = WiFi.gatewayIP().toString(); - doc[wifiDns] = WiFi.dnsIP().toString(); + doc[wifiDns] = vars.savedWifiDNS.toString();//WiFi.dnsIP().toString(); } else { @@ -1412,7 +1494,7 @@ String getRootData(bool update) doc[wifiIpKey] = networkCfg.wifiDhcp ? noConn : WiFi.localIP().toString(); doc[wifiMaskKey] = networkCfg.wifiDhcp ? noConn : WiFi.subnetMask().toString(); doc[wifiGateKey] = networkCfg.wifiDhcp ? noConn : WiFi.gatewayIP().toString(); - doc[wifiDns] = networkCfg.wifiDhcp ? noConn : WiFi.dnsIP().toString(); + doc[wifiDns] = networkCfg.wifiDhcp ? noConn : vars.savedWifiDNS.toString();//WiFi.dnsIP().toString(); } } @@ -1579,16 +1661,16 @@ void printLogMsg(String msg) logPush('\n'); LOGI("%s", msg.c_str()); } - +/* void progressNvRamFunc(unsigned int progress, unsigned int total) { - const char *tagESP_FW_progress = "ESP_FW_prgs"; + const char *tagESP_FW_prgs = "ESP_FW_prgs"; const uint8_t eventLen = 11; float percent = ((float)progress / total) * 100.0; - sendEvent(tagESP_FW_progress, eventLen, String(percent)); + sendEvent(tagESP_FW_prgs, eventLen, String(percent)); // printLogMsg(String(percent)); #ifdef DEBUG @@ -1598,16 +1680,16 @@ void progressNvRamFunc(unsigned int progress, unsigned int total) } #endif }; - +*/ void progressFunc(unsigned int progress, unsigned int total) { - const char *tagESP_FW_progress = "ESP_FW_prgs"; + const uint8_t eventLen = 11; float percent = ((float)progress / total) * 100.0; - sendEvent(tagESP_FW_progress, eventLen, String(percent)); + sendEvent(tagESP_FW_prgs, eventLen, String(percent)); // printLogMsg(String(percent)); #ifdef DEBUG @@ -1625,21 +1707,22 @@ void getEspUpdate(String esp_fw_url) { LOGI("getEspUpdate: %s", esp_fw_url.c_str()); - HTTPClient clientWeb; + checkDNS(); + HTTPClient http; WiFiClientSecure client; client.setInsecure(); // the magic line, use with caution - clientWeb.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); - clientWeb.begin(client, esp_fw_url); - clientWeb.addHeader("Content-Type", "application/octet-stream"); + http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); + http.begin(client, esp_fw_url); + http.addHeader("Content-Type", "application/octet-stream"); // Get file, just to check if each reachable - int resp = clientWeb.GET(); + int resp = http.GET(); LOGD("Response: %s", String(resp)); // If file is reachable, start downloading if (resp == HTTP_CODE_OK) { // get length of document (is -1 when Server sends no Content-Length header) - totalLength = clientWeb.getSize(); + totalLength = http.getSize(); // transfer to local variable int len = totalLength; // this is required to start firmware update process @@ -1649,10 +1732,10 @@ void getEspUpdate(String esp_fw_url) // create buffer for read uint8_t buff[128] = {0}; // get tcp stream - WiFiClient *stream = clientWeb.getStreamPtr(); + WiFiClient *stream = http.getStreamPtr(); // read all data from server LOGI("Updating firmware..."); - while (clientWeb.connected() && (len > 0 || len == -1)) + while (http.connected() && (len > 0 || len == -1)) { // get available data size size_t size = stream->available(); @@ -1673,7 +1756,7 @@ void getEspUpdate(String esp_fw_url) { LOGI("Cannot download firmware file."); } - clientWeb.end(); + http.end(); } void runEspUpdateFirmware(uint8_t *data, size_t len) @@ -1691,10 +1774,11 @@ void runEspUpdateFirmware(uint8_t *data, size_t len) ESP.restart(); } -String fetchGitHubReleaseInfo() +String fetchLatestEspFw() { + checkDNS(); HTTPClient http; - http.begin("https://api.github.com/repos/xyzroe/xzg/releases"); + http.begin("https://api.github.com/repos/xyzroe/XZG/releases"); int httpCode = http.GET(); String browser_download_url = ""; @@ -1710,7 +1794,68 @@ String fetchGitHubReleaseInfo() if (releases.size() > 0 && releases[0]["assets"].size() > 1) { browser_download_url = releases[0]["assets"][1]["browser_download_url"].as(); - LOGD("browser_download_url: %s", browser_download_url.c_str()); + // LOGD("browser_download_url: %s", browser_download_url.c_str()); + } + } + else + { + LOGD("Error on HTTP request"); + } + + http.end(); + return browser_download_url; +} + +String fetchLatestZbFw() +{ + checkDNS(); + HTTPClient http; + http.begin("https://raw.githubusercontent.com/xyzroe/XZG/zb_fws/ti/manifest.json"); + int httpCode = http.GET(); + + String browser_download_url = ""; + + if (httpCode > 0) + { + String payload = http.getString(); + + DynamicJsonDocument doc(8192 * 2); + deserializeJson(doc, payload); + + size_t usedMemory = doc.memoryUsage(); + LOGD("doc used: %s bytes", String(usedMemory)); + + String roleKey; + if (systemCfg.zbRole == COORDINATOR) + { + roleKey = "coordinator"; + } + else if (systemCfg.zbRole == ROUTER) + { + roleKey = "router"; + } + else if (systemCfg.zbRole == OPENTHREAD) + { + roleKey = "thread"; + } + + if (doc.containsKey(roleKey) && doc[roleKey].containsKey(CCTool.chip.hwRev)) + { + JsonObject roleObj = doc[roleKey][CCTool.chip.hwRev].as(); + for (JsonPair kv : roleObj) + { + JsonObject file = kv.value().as(); + if (file.containsKey("link")) + { + browser_download_url = file["link"].as(); + if (file.containsKey("baud")) + { + browser_download_url = browser_download_url + "?b=" + file["baud"].as(); + } + break; + } + } + // LOGD("browser_download_url: %s", browser_download_url.c_str()); } } else @@ -1724,8 +1869,13 @@ String fetchGitHubReleaseInfo() String extractVersionFromURL(String url) { - int startPos = url.indexOf("/download/") + 10; - int endPos = url.indexOf("/", startPos); + int startPos = url.lastIndexOf('_') + 1; + int endPos = url.indexOf(".ota.bin"); + if (endPos == -1) + { + endPos = url.indexOf(".bin"); + } + if (startPos != -1 && endPos != -1) { return url.substring(startPos, endPos); diff --git a/src/web.h b/src/web.h index b9bdce3..5832760 100644 --- a/src/web.h +++ b/src/web.h @@ -36,7 +36,8 @@ void progressFunc(unsigned int progress, unsigned int total); void getEspUpdate(String esp_fw_url); void runEspUpdateFirmware(uint8_t *data, size_t len); -String fetchGitHubReleaseInfo(); +String fetchLatestEspFw(); +String fetchLatestZbFw(); String extractVersionFromURL(String url); void updateWebTask(void *parameter); diff --git a/src/websrc/html/PAGE_GENERAL.html b/src/websrc/html/PAGE_GENERAL.html index 2d4fee7..8672e06 100644 --- a/src/websrc/html/PAGE_GENERAL.html +++ b/src/websrc/html/PAGE_GENERAL.html @@ -11,48 +11,44 @@ + pattern="^[a-zA-Z0-9]+([\-]?[a-zA-Z0-9]+)*$" + data-i18n="p.ge.host.ph[placeholder];p.ge.host.tt[title]" required>
- +
- + @@ -68,8 +64,8 @@ diff --git a/src/websrc/html/PAGE_NETWORK.html b/src/websrc/html/PAGE_NETWORK.html index 45baa1d..ccedb5f 100644 --- a/src/websrc/html/PAGE_NETWORK.html +++ b/src/websrc/html/PAGE_NETWORK.html @@ -72,6 +72,31 @@ +
+ + +
+
+ + +
checkLatestESPrelease(); +
@@ -23,6 +23,10 @@ + + + + diff --git a/src/websrc/html/PAGE_TOOLS.html b/src/websrc/html/PAGE_TOOLS.html index af7c7a5..dad8199 100644 --- a/src/websrc/html/PAGE_TOOLS.html +++ b/src/websrc/html/PAGE_TOOLS.html @@ -86,7 +86,7 @@
-
+
@@ -114,7 +114,7 @@
-
+
diff --git a/src/websrc/html/PAGE_ZIGBEE.html b/src/websrc/html/PAGE_ZIGBEE.html index 3711a3b..29d5840 100644 --- a/src/websrc/html/PAGE_ZIGBEE.html +++ b/src/websrc/html/PAGE_ZIGBEE.html @@ -188,9 +188,10 @@ if (matchedClass && fw[classToFwMap[matchedClass]] && fw[classToFwMap[matchedClass]].length > 0) { const fileLink = fw[classToFwMap[matchedClass]][0].link; - console.log(fileLink); + const baudRate = fw[classToFwMap[matchedClass]][0].baud; + console.log(fileLink + " @ " + baudRate); modalConstructor("flashZBM"); - startZbFlash(fileLink); + startZbFlash(fileLink + "?b=" + baudRate); } else { const errorMessage = classToErrorMessage[matchedClass] || "No matching firmware available."; console.log(errorMessage); diff --git a/src/websrc/js/functions.js b/src/websrc/js/functions.js index dfa0a25..603fb77 100644 --- a/src/websrc/js/functions.js +++ b/src/websrc/js/functions.js @@ -367,6 +367,7 @@ function setIconGlow(iconId, state, show = true) { function loadPage(url) { + delete updateValues.zbRole; if (window.location.pathname !== url) { window.history.pushState("", document.title, url); @@ -396,9 +397,9 @@ function loadPage(url) { break; case api.pages.API_PAGE_GENERAL.str: apiGetPage(api.pages.API_PAGE_GENERAL);//, () => { - //if (!$("#usbMode").prop(chck)) { - // KeepWebDsbl(true); - //} + //if (!$("#usbMode").prop(chck)) { + // KeepWebDsbl(true); + //} //}); break; case api.pages.API_PAGE_MQTT.str: @@ -644,8 +645,6 @@ function apiGetPage(page, doneCall, loader = true) { for (const property in values) { if (property === "timeZoneName") { selectedTimeZone = values[property]; - //console.log(selectedTimeZone); - //console.log("timeZoneName"); continue; } if (property === "hwBtnIs") { @@ -653,7 +652,6 @@ function apiGetPage(page, doneCall, loader = true) { continue; } if (property === "hwLedUsbIs") { - //hwBtnIs if (values[property]) { showDivById('ledsCard'); showDivById('modeLedBtn'); @@ -665,23 +663,17 @@ function apiGetPage(page, doneCall, loader = true) { showDivById('ledsCard'); showDivById('pwrLedBtn'); } - //hwBtnIs continue; } - /*if (property === "hwUartSelIs") { - if (values[property]) { - showDivById('modeSelCard'); - showDivById('curModeSelCard'); - } - - //hwBtnIs - continue; - }*/ } dataReplace(values); } updateLocalizedContent(); + $('[title]').each(function() { + var title = $(this).attr('title'); + setTitleAndActivateTooltip(this, title); + }); if (xhr.getResponseHeader("respTimeZones") !== null) { const zones = JSON.parse(xhr.getResponseHeader("respTimeZones")); @@ -962,6 +954,24 @@ function dataReplace(values, navOnly = false) { showCardDrawIcon(property, values); let $elements = $(baseSelector + property + "']"); + if (property == "zbRole") { + if (values[property] == 1) { + document.querySelectorAll('.zfs_coordinator').forEach(card => card.classList.add('selected')); + } else if (values[property] == 2) { + document.querySelectorAll('.zfs_router').forEach(card => card.classList.add('selected')); + } else if (values[property] == 3) { + document.querySelectorAll('.zfs_thread').forEach(card => card.classList.add('selected')); + } + } + if (property == "espUpdAvail" && values[property] == 1) { + toastConstructor("espUpdAvail"); + } + if (property == "zbUpdAvail" && values[property] == 1) { + toastConstructor("zbUpdAvail"); + } + if (property == "zbFwSaved" && values[property] == 1) { + $('td[data-r2v="zigbeeFwRev"]').addClass('fst-italic'); + } //console.log($elements); $elements.map(function () { const elemType = $(this).prop('nodeName').toLowerCase(); @@ -996,7 +1006,7 @@ function dataReplace(values, navOnly = false) { updateProgressBar("prgTemp", valueToSet, 15, 85) break; case "wifiRssi": - updateProgressBar("prgRssi", valueToSet, -105, 0) + updateProgressBar("prgRssi", valueToSet, 0, -105) valueToSet = valueToSet + " " + "dBm"; break; case "connectedSocket": // socket time @@ -1021,7 +1031,6 @@ function dataReplace(values, navOnly = false) { break; } break; - case "operationalMode": updateValues[property] = values[property]; switch (valueToSet) { @@ -1033,6 +1042,22 @@ function dataReplace(values, navOnly = false) { break; } break; + case "zbRole": + updateValues[property] = values[property]; + switch (valueToSet) { + case 1: + valueToSet = i18next.t('p.st.zr.c'); + break; + case 2: + valueToSet = i18next.t('p.st.zr.r'); + break; + case 2: + valueToSet = i18next.t('p.st.zr.t'); + break; + default: + break; + } + break; case "ethDhcp": case "wifiDhcp": if (valueToSet) { @@ -1152,8 +1177,9 @@ function toastConstructor(params, text) { switch (params) { case "espUpdAvail": $("#toastHeaderText").text(i18next.t("ts.esp.upd.tt")); - $("#toastBody").text(text); - $('
"); console.log(data); @@ -1364,7 +1421,7 @@ function updateRootEvents(callback) { }, false); - source.addEventListener('ZB_FW_file', function (e) { + source.addEventListener('zb.ff', function (e) { let fileName = fileFromUrl(e.data); if (fileName) { data = i18next.t('md.zg.fu.f', { file: fileName }); @@ -1378,12 +1435,12 @@ function updateRootEvents(callback) { setTimeout(function () { espReboot(); restartWait(); - }, 2000); + }, 1250); } $("#zbFlshPgsTxt").html(data); }, false); - source.addEventListener('ZB_FW_err', function (e) { + source.addEventListener('zb.fe', function (e) { const data = e.data.replaceAll("`", "
"); $(modalBtns).html(""); $("#zbFlshPgsTxt").html(data); @@ -1393,7 +1450,7 @@ function updateRootEvents(callback) { }, false); - source.addEventListener('ESP_FW_prgs', function (e) { + source.addEventListener('esp.fp', function (e) { $('#prg').css('width', e.data + '%'); $('#bar').html(i18next.t('md.esp.fu.prgs', { per: e.data })); @@ -1404,7 +1461,7 @@ function updateRootEvents(callback) { $('#bar').html(i18next.t('md.esp.fu.ucr')).css("color", "green"); setTimeout(function () { - localStorage.setItem('update_notify', 0); + //localStorage.setItem('update_notify', 0); restartWait(); }, 1000); @@ -1554,7 +1611,8 @@ function findAllVersionsSorted(data, chip) { file: file, ver: fileInfo.ver, link: fileInfo.link, - notes: fileInfo.notes + notes: fileInfo.notes, + baud: fileInfo.baud }); }); } @@ -1598,20 +1656,20 @@ function createReleaseBlock(file, deviceType) { setTitleAndActivateTooltip(emojiBlock[0], deviceName); - let fileName = fileFromUrl(file.link); + //let fileName = fileFromUrl(file.link); const buttonContainer = $('
', { "class": "d-flex align-items-start" }).appendTo(headerAndButtonContainer); const button = $('', { "class": buttonClass, "click": function () { - startZbFlash(file.link); + startZbFlash(file.link + "?b=" + file.baud); let tooltipInstance = bootstrap.Tooltip.getInstance(this); if (tooltipInstance) { tooltipInstance.hide(); } }, "data-bs-toggle": "tooltip", - "title": fileName, + "title": file.link, "text": i18next.t('c.inst'), "role": "button" }).css("white-space", "nowrap").appendTo(buttonContainer); @@ -1918,7 +1976,7 @@ function modalConstructor(type, params) { window.location = "http://" + data.ip + "/"; } }).appendTo(modalBtns); - }, 5000); + }, 3000); } else { counter++; } @@ -2131,6 +2189,8 @@ function WifiEnbl(state) { var dhcpEnabled = $("#wifiDhcp").is(":checked"); $("#wifiSsid").prop(disbl, state); $("#wifiPass").prop(disbl, state); + $("#wifiMode").prop(disbl, state); + $("#wifiPwr").prop(disbl, state); if (dhcpEnabled) { $("#wifiDhcp").prop(disbl, state); $("#wifiIp").prop(disbl, true); @@ -2234,7 +2294,7 @@ function logRefresh(ms) { }); }, ms); } - +/* async function fetchData(url, isJson = true) { if (isJson) { return await $.getJSON(url); @@ -2280,7 +2340,8 @@ function compareDates(dateStr1, dateStr2) { return 0; // даты равны } } - +*/ +/* function checkLatestESPrelease() { @@ -2323,6 +2384,7 @@ function checkLatestESPrelease() { }); } +*/ // CSS class name for dark theme const darkTheme = "dark-theme"; @@ -2471,7 +2533,7 @@ function sub_zb(t) { } async function fetchReleaseData() { - var t = await fetch("https://api.github.com/repos/xyzroe/xzg/releases"); + var t = await fetch("https://api.github.com/repos/xyzroe/XZG/releases"); if (t.ok) return await t.json(); throw new Error("GitHub API request failed: " + t.statusText) } @@ -2513,7 +2575,7 @@ function handleClicks() { $(document).on('click', '#upd_esp_git', function () { console.log("Update from Git started... Just be patient!"); - localStorage.setItem("update_notify", 0); + //localStorage.setItem("update_notify", 0); modalConstructor("flashESP"); }); diff --git a/src/websrc/json/cz.json b/src/websrc/json/cz.json index bd11b67..8d38f25 100644 --- a/src/websrc/json/cz.json +++ b/src/websrc/json/cz.json @@ -60,7 +60,13 @@ }, "c": { "fv": "Firmware", - "hv": "Hardware" + "hv": "Hardware", + "r": "Role" + }, + "zr": { + "c": "Coordinator", + "r": "Router", + "t": "OpenTread" } }, "ge": { @@ -98,6 +104,21 @@ "ph": "pool.ntp.org", "tt": "Zadejte platný název domény" } + }, + "u": { + "ai": "Auto install updates (ESP32 and Zigbee)", + "d": { + "ev": "Everyday", + "fr": "Friday", + "mn": "Monday", + "sa": "Saturday", + "su": "Sunday", + "th": "Thursday", + "tt": "Day of week", + "tu": "Tuesday", + "wd": "Wednesday" + }, + "h": "New firmware check time" } }, "ne": { @@ -117,7 +138,9 @@ "ssid": "SSID", "sc": "Zabezpečení", "ch": "Kanál", - "nnf": "Sítě Wi-Fi nebyly nalezeny" + "nnf": "Sítě Wi-Fi nebyly nalezeny", + "mode": "Mode", + "power": "Tx Power" } }, "zi": { @@ -428,6 +451,9 @@ "zb": { "nzfa": { "tt": "Nebyl nalezen žádný firmware" + }, + "upd": { + "tt": "New Zigbee firmware found 🌟" } } } diff --git a/src/websrc/json/de.json b/src/websrc/json/de.json index 51382d7..22dc5e8 100644 --- a/src/websrc/json/de.json +++ b/src/websrc/json/de.json @@ -158,6 +158,21 @@ "net": "Netzwerkmodus", "usb": "USB-Modus" } + }, + "u": { + "ai": "Automatische Installation von Updates (ESP32 und Zigbee)", + "d": { + "ev": "Täglich", + "fr": "Freitag", + "mn": "Montag", + "sa": "Samstag", + "su": "Sonntag", + "th": "Donnerstag", + "tt": "Wochentag", + "tu": "Dienstag", + "wd": "Mittwoch" + }, + "h": "Neue Firmware-Prüfzeit" } }, "lo": { @@ -227,7 +242,9 @@ "rssi": "RSSI", "sc": "Sicherheit", "ssid": "SSID", - "nnf": "WLAN-Netzwerke nicht gefunden" + "nnf": "WLAN-Netzwerke nicht gefunden", + "mode": "Modus", + "power": "Sendeleistung" } }, "st": { @@ -278,7 +295,13 @@ }, "c": { "fv": "FW-Revision", - "hv": "HW-Version" + "hv": "HW-Version", + "r": "Rolle" + }, + "zr": { + "c": "Koordinator", + "r": "Router", + "t": "OpenTread" } }, "se": { @@ -431,6 +454,9 @@ "zb": { "nzfa": { "tt": "Keine neue Firmware gefunden" + }, + "upd": { + "tt": "Neue Zigbee-Firmware gefunden 🌟" } } } diff --git a/src/websrc/json/en.json b/src/websrc/json/en.json index bb54e34..968b283 100644 --- a/src/websrc/json/en.json +++ b/src/websrc/json/en.json @@ -60,7 +60,13 @@ }, "c": { "fv": "Firmware", - "hv": "Hardware" + "hv": "Hardware", + "r": "Role" + }, + "zr": { + "c": "Coordinator", + "r": "Router", + "t": "OpenTread" } }, "ge": { @@ -98,6 +104,21 @@ "ph": "pool.ntp.org", "tt": "Enter valid domain name" } + }, + "u": { + "h": "New firmware check time", + "d": { + "tt": "Day of week", + "ev": "Everyday", + "mn": "Monday", + "tu": "Tuesday", + "wd": "Wednesday", + "th": "Thursday", + "fr": "Friday", + "sa": "Saturday", + "su": "Sunday" + }, + "ai": "Auto install updates (ESP32 and Zigbee)" } }, "ne": { @@ -117,7 +138,9 @@ "ssid": "SSID", "sc": "Security", "ch": "Channel", - "nnf": "WiFi networks not found" + "nnf": "WiFi networks not found", + "mode": "Mode", + "power": "Tx Power" } }, "zi": { @@ -428,6 +451,9 @@ "zb": { "nzfa": { "tt": "No firmware found" + }, + "upd": { + "tt": "New Zigbee firmware found 🌟" } } } diff --git a/src/websrc/json/es.json b/src/websrc/json/es.json index 981e1b9..be47a53 100644 --- a/src/websrc/json/es.json +++ b/src/websrc/json/es.json @@ -155,6 +155,21 @@ "net": "Modo de red", "usb": "Modo USB" } + }, + "u": { + "ai": "Actualizaciones de instalación automática (ESP32 y Zigbee)", + "d": { + "ev": "Cada día", + "fr": "Viernes", + "mn": "Lunes", + "sa": "Sábado", + "su": "Domingo", + "th": "Jueves", + "tt": "Día de la semana", + "tu": "Martes", + "wd": "Miércoles" + }, + "h": "Hora de verificación del nuevo firmware" } }, "lo": { @@ -224,7 +239,9 @@ "rssi": "RSSI", "sc": "Seguridad", "ssid": "SSID", - "nnf": "Redes Wifi no encontradas" + "nnf": "Redes Wifi no encontradas", + "mode": "Modo", + "power": "Poder TX" } }, "st": { @@ -275,7 +292,13 @@ }, "c": { "fv": "Revisión de firmware", - "hv": "Versión HW" + "hv": "Versión HW", + "r": "Role" + }, + "zr": { + "c": "Coordinador", + "r": "Enrutador", + "t": "OpenTread" } }, "se": { @@ -428,6 +451,9 @@ "zb": { "nzfa": { "tt": "No se encontró firmware" + }, + "upd": { + "tt": "Nuevo firmware Zigbee encontrado 🌟" } } } diff --git a/src/websrc/json/fr.json b/src/websrc/json/fr.json index 67a9453..fdfed05 100644 --- a/src/websrc/json/fr.json +++ b/src/websrc/json/fr.json @@ -158,6 +158,21 @@ "net": "Mode réseau", "usb": "Mode USB" } + }, + "u": { + "ai": "Mises à jour d'installation automatique (ESP32 et Zigbee)", + "d": { + "ev": "Tous les jours", + "fr": "Vendredi", + "mn": "Lundi", + "sa": "Samedi", + "su": "Dimanche", + "th": "Jeudi", + "tt": "Jour de la semaine", + "tu": "Mardi", + "wd": "Mercredi" + }, + "h": "Heure de vérification du nouveau firmware" } }, "lo": { @@ -227,7 +242,9 @@ "rssi": "RSSI", "sc": "Sécurité", "ssid": "SSID", - "nnf": "Réseaux WiFi introuvables" + "nnf": "Réseaux WiFi introuvables", + "mode": "Mode", + "power": "Puissance d'émission" } }, "st": { @@ -278,7 +295,13 @@ }, "c": { "fv": "Révision du microLOGDciel", - "hv": "Version matérielle" + "hv": "Version matérielle", + "r": "Rôle" + }, + "zr": { + "c": "Coordinateur", + "r": "Routeur", + "t": "Ouvrir la bande de roulement" } }, "se": { @@ -431,6 +454,9 @@ "zb": { "nzfa": { "tt": "Aucun firmware trouvé" + }, + "upd": { + "tt": "Nouveau firmware Zigbee trouvé 🌟" } } } diff --git a/src/websrc/json/it.json b/src/websrc/json/it.json index b3b260b..e4775fa 100644 --- a/src/websrc/json/it.json +++ b/src/websrc/json/it.json @@ -158,6 +158,21 @@ "net": "Modalità di rete", "usb": "Modalità USB" } + }, + "u": { + "ai": "Aggiornamenti con installazione automatica (ESP32 e Zigbee)", + "d": { + "ev": "Ogni giorno", + "fr": "Venerdì", + "mn": "Lunedi", + "sa": "Sabato", + "su": "Domenica", + "th": "Giovedì", + "tt": "Giorno della settimana", + "tu": "Martedì", + "wd": "Mercoledì" + }, + "h": "Orario di verifica del nuovo firmware" } }, "lo": { @@ -227,7 +242,9 @@ "rssi": "RSSI", "sc": "Sicurezza", "ssid": "SSID", - "nnf": "Reti WiFi non trovate" + "nnf": "Reti WiFi non trovate", + "mode": "Modalità", + "power": "Potenza Tx" } }, "st": { @@ -278,7 +295,13 @@ }, "c": { "fv": "Revisione firmware", - "hv": "Versione hardware" + "hv": "Versione hardware", + "r": "Ruolo" + }, + "zr": { + "c": "Coordinatore", + "r": "Router", + "t": "OpenTread" } }, "se": { @@ -431,6 +454,9 @@ "zb": { "nzfa": { "tt": "Nessun firmware trovato" + }, + "upd": { + "tt": "Trovato nuovo firmware Zigbee 🌟" } } } diff --git a/src/websrc/json/ja.json b/src/websrc/json/ja.json index dcafd60..5d08d27 100644 --- a/src/websrc/json/ja.json +++ b/src/websrc/json/ja.json @@ -158,6 +158,21 @@ "net": "ネットワークモード", "usb": "USBモード" } + }, + "u": { + "ai": "アップデートの自動インストール (ESP32 および Zigbee)", + "d": { + "ev": "毎日", + "fr": "金曜日", + "mn": "月曜日", + "sa": "土曜日", + "su": "日曜日", + "th": "木曜日", + "tt": "曜日", + "tu": "火曜日", + "wd": "水曜日" + }, + "h": "新しいファームウェアのチェック時間" } }, "lo": { @@ -227,7 +242,9 @@ "rssi": "RSSI", "sc": "安全", "ssid": "SSID", - "nnf": "WiFi ネットワークが見つかりません" + "nnf": "WiFi ネットワークが見つかりません", + "mode": "モード", + "power": "送信電力" } }, "st": { @@ -278,7 +295,13 @@ }, "c": { "fv": "FWリビジョン", - "hv": "ハードウェアバージョン" + "hv": "ハードウェアバージョン", + "r": "役割" + }, + "zr": { + "c": "コーディネーター", + "r": "ルーター", + "t": "オープントレッド" } }, "se": { @@ -431,6 +454,9 @@ "zb": { "nzfa": { "tt": "ファームウェアが見つかりません" + }, + "upd": { + "tt": "新しい Zigbee ファームウェアが見つかりました 🌟" } } } diff --git a/src/websrc/json/pl.json b/src/websrc/json/pl.json index d3db6fc..5f13620 100644 --- a/src/websrc/json/pl.json +++ b/src/websrc/json/pl.json @@ -158,6 +158,21 @@ "net": "Tryb sieciowy", "usb": "Tryb USB" } + }, + "u": { + "ai": "Automatyczna instalacja aktualizacji (ESP32 i Zigbee)", + "d": { + "ev": "Codziennie", + "fr": "Piątek", + "mn": "Poniedziałek", + "sa": "Sobota", + "su": "Niedziela", + "th": "Czwartek", + "tt": "Dzień tygodnia", + "tu": "Wtorek", + "wd": "Środa" + }, + "h": "Czas sprawdzania nowego oprogramowania sprzętowego" } }, "lo": { @@ -227,7 +242,9 @@ "rssi": "RSSI", "sc": "Bezpieczeństwo", "ssid": "SSID", - "nnf": "Nie znaleziono sieci Wi-Fi" + "nnf": "Nie znaleziono sieci Wi-Fi", + "mode": "Tryb", + "power": "Moc wysyłania" } }, "st": { @@ -278,7 +295,13 @@ }, "c": { "fv": "Wersja oprogramowania sprzętowego", - "hv": "Wersja sprzętowa" + "hv": "Wersja sprzętowa", + "r": "Rola" + }, + "zr": { + "c": "Koordynator", + "r": "Routera", + "t": "OtwórzTread" } }, "se": { @@ -431,6 +454,9 @@ "zb": { "nzfa": { "tt": "Nie znaleziono oprogramowania sprzętowego" + }, + "upd": { + "tt": "Znaleziono nowe oprogramowanie Zigbee 🌟" } } } diff --git a/src/websrc/json/pt.json b/src/websrc/json/pt.json index 899dee6..c6d61d7 100644 --- a/src/websrc/json/pt.json +++ b/src/websrc/json/pt.json @@ -158,6 +158,21 @@ "net": "Modo de rede", "usb": "Modo USB" } + }, + "u": { + "ai": "Atualizações de instalação automática (ESP32 e Zigbee)", + "d": { + "ev": "Diariamente", + "fr": "Sexta-feira", + "mn": "Segunda-feira", + "sa": "Sábado", + "su": "Domingo", + "th": "Quinta-feira", + "tt": "Dia da semana", + "tu": "Terça-feira", + "wd": "Quarta-feira" + }, + "h": "Tempo de verificação do novo firmware" } }, "lo": { @@ -227,7 +242,9 @@ "rssi": "RSSI", "sc": "Segurança", "ssid": "SSID", - "nnf": "Redes WiFi não encontradas" + "nnf": "Redes WiFi não encontradas", + "mode": "Modo", + "power": "Potência Tx" } }, "st": { @@ -278,7 +295,13 @@ }, "c": { "fv": "Revisão do firmware", - "hv": "Versão HW" + "hv": "Versão HW", + "r": "Papel" + }, + "zr": { + "c": "Coordenador", + "r": "Roteador", + "t": "OpenTread" } }, "se": { @@ -431,6 +454,9 @@ "zb": { "nzfa": { "tt": "Nenhum firmware encontrado" + }, + "upd": { + "tt": "Novo firmware Zigbee encontrado 🌟" } } } diff --git a/src/websrc/json/ru.json b/src/websrc/json/ru.json index 90b1613..baa4e85 100644 --- a/src/websrc/json/ru.json +++ b/src/websrc/json/ru.json @@ -158,6 +158,21 @@ "net": "Сетевой режим", "usb": "USB-режим" } + }, + "u": { + "ai": "Автоматическая установка обновлений (ESP32 и Zigbee)", + "d": { + "ev": "Каждый день", + "fr": "Пятница", + "mn": "Понедельник", + "sa": "Суббота", + "su": "Воскресенье", + "th": "Четверг", + "tt": "День недели", + "tu": "Вторник", + "wd": "Среда" + }, + "h": "Время проверки новой прошивки" } }, "lo": { @@ -227,7 +242,9 @@ "rssi": "RSSI", "sc": "Безопасность", "ssid": "SSID", - "nnf": "Сети Wi-Fi не найдены" + "nnf": "Сети Wi-Fi не найдены", + "mode": "Режим", + "power": "Мощность передачи" } }, "st": { @@ -278,7 +295,13 @@ }, "c": { "fv": "FW версия", - "hv": "HW версия" + "hv": "HW версия", + "r": "Роль" + }, + "zr": { + "c": "Координатор", + "r": "Маршрутизатор", + "t": "OpenTread" } }, "se": { @@ -431,6 +454,9 @@ "zb": { "nzfa": { "tt": "Прошивка не найдена" + }, + "upd": { + "tt": "Найдена новая прошивка Zigbee 🌟" } } } diff --git a/src/websrc/json/tr.json b/src/websrc/json/tr.json index 9ca8cab..c9907ef 100644 --- a/src/websrc/json/tr.json +++ b/src/websrc/json/tr.json @@ -158,6 +158,21 @@ "net": "AĞ modu", "usb": "USB modu" } + }, + "u": { + "ai": "Otomatik yükleme güncellemeleri (ESP32 ve Zigbee)", + "d": { + "ev": "Her gün", + "fr": "Cuma", + "mn": "Pazartesi", + "sa": "Cumartesi", + "su": "Pazar", + "th": "Perşembe", + "tt": "Haftanın günü", + "tu": "Salı", + "wd": "Çarşamba" + }, + "h": "Yeni ürün yazılımı kontrol zamanı" } }, "lo": { @@ -227,7 +242,9 @@ "rssi": "RSSI", "sc": "Güvenlik", "ssid": "SSID", - "nnf": "WiFi ağları bulunamadı" + "nnf": "WiFi ağları bulunamadı", + "mode": "Mod", + "power": "Teksas Gücü" } }, "st": { @@ -278,7 +295,13 @@ }, "c": { "fv": "Firmware revizyonu", - "hv": "Donanım sürümü" + "hv": "Donanım sürümü", + "r": "Rol" + }, + "zr": { + "c": "Koordinatör", + "r": "Yönlendirici", + "t": "Açık Sırt" } }, "se": { @@ -431,6 +454,9 @@ "zb": { "nzfa": { "tt": "Firmware bulunamadı" + }, + "upd": { + "tt": "Yeni Zigbee ürün yazılımı bulundu 🌟" } } } diff --git a/src/websrc/json/uk.json b/src/websrc/json/uk.json index 32e52b3..08741e7 100644 --- a/src/websrc/json/uk.json +++ b/src/websrc/json/uk.json @@ -60,7 +60,13 @@ }, "c": { "fv": "FW версія", - "hv": "HW версія" + "hv": "HW версія", + "r": "Роль" + }, + "zr": { + "c": "Координатор", + "r": "Маршрутизатор", + "t": "OpenTread" } }, "ge": { @@ -98,6 +104,21 @@ "ph": "pool.ntp.org", "tt": "Введіть дійсне доменне ім'я" } + }, + "u": { + "ai": "Автоматичне встановлення оновлень (ESP32 і Zigbee)", + "d": { + "ev": "Щодня", + "fr": "П'ятниця", + "mn": "понеділок", + "sa": "Субота", + "su": "неділя", + "th": "четвер", + "tt": "День тижня", + "tu": "вівторок", + "wd": "Середа" + }, + "h": "Час перевірки нової прошивки" } }, "ne": { @@ -117,7 +138,9 @@ "ssid": "SSID", "sc": "Безпека", "ch": "Канал", - "nnf": "Мережі WiFi не знайдено" + "nnf": "Мережі WiFi не знайдено", + "mode": "Режим", + "power": "Потужність передачі" } }, "zi": { @@ -428,6 +451,9 @@ "zb": { "nzfa": { "tt": "Прошивка не знайдена" + }, + "upd": { + "tt": "Знайдено нову мікропрограму Zigbee 🌟" } } } diff --git a/src/websrc/json/zh.json b/src/websrc/json/zh.json index 38bcfef..0ff7e3c 100644 --- a/src/websrc/json/zh.json +++ b/src/websrc/json/zh.json @@ -158,6 +158,21 @@ "net": "网络模式", "usb": "USB模式" } + }, + "u": { + "ai": "自动安装更新(ESP32 和 Zigbee)", + "d": { + "ev": "每天", + "fr": "星期五", + "mn": "周一", + "sa": "周六", + "su": "星期日", + "th": "周四", + "tt": "星期几", + "tu": "周二", + "wd": "周三" + }, + "h": "新固件检查时间" } }, "lo": { @@ -227,7 +242,9 @@ "rssi": "信号强度", "sc": "安全", "ssid": "SSID", - "nnf": "未找到 WiFi 网络" + "nnf": "未找到 WiFi 网络", + "mode": "模式", + "power": "发射功率" } }, "st": { @@ -278,7 +295,13 @@ }, "c": { "fv": "固件版本", - "hv": "硬件版本" + "hv": "硬件版本", + "r": "角色" + }, + "zr": { + "c": "协调员", + "r": "路由器", + "t": "开放式" } }, "se": { @@ -431,6 +454,9 @@ "zb": { "nzfa": { "tt": "未找到固件" + }, + "upd": { + "tt": "发现新的 Zigbee 固件 🌟" } } } diff --git a/src/zb.cpp b/src/zb.cpp index 687e29b..c4049de 100644 --- a/src/zb.cpp +++ b/src/zb.cpp @@ -14,6 +14,7 @@ #include "log.h" #include "etc.h" #include "zb.h" +#include "const/keys.h" extern struct SysVarsStruct vars; extern struct ThisConfigStruct hwConfig; @@ -45,11 +46,11 @@ bool zbFwCheck() return true; } else - { + { CCTool.restart(); - int val = attempt+1; + int val = attempt + 1; LOGD("Try: %d", val); - delay(500*(val*val)); + delay(500 * (val * val)); } } printLogMsg(tag_ZB + " FW: Unknown! Check serial speed!"); @@ -114,14 +115,14 @@ bool zigbeeErase() } void nvPrgs(const String &inputMsg) { - const char *tagZB_NV_progress = "NV"; + const uint8_t eventLen = 30; String msg = inputMsg; if (msg.length() > 25) { msg = msg.substring(0, 25); } - sendEvent(tagZB_NV_progress, eventLen, msg); + sendEvent(tagZB_NV_prgs, eventLen, msg); LOGD("%s", msg.c_str()); } @@ -135,26 +136,25 @@ void zbEraseNV(void *pvParameters) void flashZbUrl(String url) { + // zbFwCheck(); + checkDNS(); + delay(1000); + Serial2.updateBaudRate(500000); float last_percent = 0; - const char *tagZB_FW_info = "ZB_FW_info"; - const char *tagZB_FW_file = "ZB_FW_file"; - const char *tagZB_FW_err = "ZB_FW_err"; - const char *tagZB_FW_progress = "ZB_FW_prgs"; const uint8_t eventLen = 11; auto progressShow = [last_percent](float percent) mutable { - const char *tagZB_FW_progress = "ZB_FW_prgs"; if ((percent - last_percent) > 1 || percent < 0.1 || percent == 100) { // char buffer[100]; // snprintf(buffer, sizeof(buffer), "Flash progress: %.2f%%", percent); // printLogMsg(String(buffer)); - LOGI("%s", String(percent)); - sendEvent(tagZB_FW_progress, eventLen, String(percent)); + LOGI("%.2f%%", percent); + sendEvent(tagZB_FW_prgs, eventLen, String(percent)); last_percent = percent; } }; @@ -162,32 +162,109 @@ void flashZbUrl(String url) printLogMsg("Start Zigbee flashing"); sendEvent(tagZB_FW_info, eventLen, String("start")); - zbFwCheck(); + // https://raw.githubusercontent.com/xyzroe/XZG/zb_fws/ti/coordinator/CC1352P7_coordinator_20240316.bin + // CCTool.enterBSL(); + int key = url.indexOf("?b="); + + String clear_url = url.substring(0, key); - // CCTool.enterBSL(); + // printLogMsg("Clear from " + clear_url); + String baud_str = url.substring(key + 3, url.length()); + // printLogMsg("Baud " + baud_str); + systemCfg.serialSpeed = baud_str.toInt(); - printLogMsg("Installing from " + url); - sendEvent(tagZB_FW_file, eventLen, String(url)); + printLogMsg("ZB flash " + clear_url + " @ " + systemCfg.serialSpeed); - if (eraseWriteZbUrl(url.c_str(), progressShow, CCTool)) + sendEvent(tagZB_FW_file, eventLen, String(clear_url)); + + if (eraseWriteZbUrl(clear_url.c_str(), progressShow, CCTool)) { sendEvent(tagZB_FW_info, eventLen, String("finish")); - printLogMsg("Flashing finished successfully"); - zbFwCheck(); - zbLedToggle(); - delay(1000); - zbLedToggle(); - sendEvent(tagZB_FW_file, eventLen, String(CCTool.chip.fwRev)); + printLogMsg("Flashed successfully"); + Serial2.updateBaudRate(systemCfg.serialSpeed); + + int lineIndex = clear_url.lastIndexOf("_"); + int binIndex = clear_url.lastIndexOf(".bin"); + int lastSlashIndex = clear_url.lastIndexOf("/"); + + if (lineIndex > -1 && binIndex > -1 && lastSlashIndex > -1) + { + String zbFw = clear_url.substring(lineIndex + 1, binIndex); + // LOGI("1 %s", zbFw); + + strncpy(systemCfg.zbFw, zbFw.c_str(), sizeof(systemCfg.zbFw) - 1); + zbFw = ""; + + int i = 0; + + int preLastSlash = -1; + // LOGI("2 %s", String(url.c_str())); + + while (clear_url.indexOf("/", i) > -1 && i < lastSlashIndex) + { + int result = clear_url.indexOf("/", i); + // LOGI("r %d", result); + if (result > -1) + { + i = result + 1; + if (result < lastSlashIndex) + { + preLastSlash = result; + // LOGI("pl %d", preLastSlash); + } + } + // LOGI("l %d", lastSlashIndex); + // delay(500); + } + + //LOGD("%s %s", String(preLastSlash), String(lastSlashIndex)); + String zbRole = clear_url.substring(preLastSlash + 1, lastSlashIndex); + LOGI("%s", zbRole); + + if (zbRole.indexOf("coordinator") > -1) + { + systemCfg.zbRole = COORDINATOR; + } + else if (zbRole.indexOf("router") > -1) + { + systemCfg.zbRole = ROUTER; + } + else if (zbRole.indexOf("tread") > -1) + { + systemCfg.zbRole = OPENTHREAD; + } + else + { + systemCfg.zbRole = UNDEFINED; + } + zbRole = ""; + + saveSystemConfig(systemCfg); + } + else + { + LOGW("URL error"); + } + if (systemCfg.zbRole == COORDINATOR) + { + zbFwCheck(); + zbLedToggle(); + delay(1000); + zbLedToggle(); + } + sendEvent(tagZB_FW_file, eventLen, String(systemCfg.zbFw)); + delay(500); + ESP.restart(); } else { + Serial2.updateBaudRate(systemCfg.serialSpeed); printLogMsg("Failed to flash Zigbee"); sendEvent(tagZB_FW_err, eventLen, String("Failed!")); } - Serial2.updateBaudRate(systemCfg.serialSpeed); } -void printBufferAsHex(const byte *buffer, size_t length) +/*void printBufferAsHex(const byte *buffer, size_t length) { const char *TAG = "BufferHex"; char hexStr[CCTool.TRANSFER_SIZE + 10]; @@ -203,7 +280,7 @@ void printBufferAsHex(const byte *buffer, size_t length) } LOGD("Buffer content:\n%s", hexOutput.c_str()); -} +}*/ bool eraseWriteZbUrl(const char *url, std::function progressShow, CCTools &CCTool) { @@ -214,7 +291,7 @@ bool eraseWriteZbUrl(const char *url, std::function progressShow, C int loadedSize = 0; int totalSize = 0; - int maxRetries = 10; + int maxRetries = 7; int retryCount = 0; int retryDelay = 500; bool isSuccess = false;