From 8c601ece4cde74b15ac64b169445ad93ff594f3f Mon Sep 17 00:00:00 2001 From: iranl Date: Wed, 7 Feb 2024 22:08:54 +0100 Subject: [PATCH 01/13] Check GitHub for updates --- Config.h | 2 ++ MqttTopics.h | 1 + Network.cpp | 19 +++++++++++++++++++ Network.h | 6 ++++++ 4 files changed, 28 insertions(+) diff --git a/Config.h b/Config.h index 07f9518..9c28fa0 100644 --- a/Config.h +++ b/Config.h @@ -1,6 +1,8 @@ #pragma once #define NUKI_HUB_VERSION "8.32-pre-3" +#define GITHUB_LATEST_RELEASE_URL "https://github.com/technyon/nuki_hub/releases/latest" +#define GITHUB_RELEASE_TAG_URL "https://github.com/technyon/nuki_hub/releases/tag/" #define MQTT_QOS_LEVEL 1 #define MQTT_CLEAN_SESSIONS false diff --git a/MqttTopics.h b/MqttTopics.h index b5ae1ff..d8d0470 100644 --- a/MqttTopics.h +++ b/MqttTopics.h @@ -41,6 +41,7 @@ #define mqtt_topic_info_hardware_version "/info/hardwareVersion" #define mqtt_topic_info_firmware_version "/info/firmwareVersion" #define mqtt_topic_info_nuki_hub_version "/info/nukiHubVersion" +#define mqtt_topic_info_nuki_hub_latest "/info/nukiHubLatest" #define mqtt_topic_keypad "/keypad" #define mqtt_topic_keypad_command_action "/keypad/command/action" diff --git a/Network.cpp b/Network.cpp index e951574..cd7e110 100644 --- a/Network.cpp +++ b/Network.cpp @@ -357,7 +357,26 @@ bool Network::update() } _lastMaintenanceTs = ts; } + + if(_lastUpdateCheckTs == 0 || (ts - _lastUpdateCheckTs) > 86400000) + { + _lastUpdateCheckTs = ts; + + https.collectHeaders(headerKeys, 1); + https.setFollowRedirects(HTTPC_DISABLE_FOLLOW_REDIRECTS); + https.begin(GITHUB_LATEST_RELEASE_URL); + int httpResponseCode = https.GET(); + + if (httpResponseCode==302) { + _latestVersion = https.header("location"); + _latestVersion.replace(GITHUB_RELEASE_TAG_URL, ""); + publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion); + } + + https.end(); + } + for(const auto& gpioTs : _gpioTs) { uint8_t pin = gpioTs.first; diff --git a/Network.h b/Network.h index c9aa133..7cda6a7 100644 --- a/Network.h +++ b/Network.h @@ -8,6 +8,7 @@ #include "networkDevices/IPConfiguration.h" #include "MqttTopics.h" #include "Gpio.h" +#include enum class NetworkDeviceType { @@ -111,6 +112,10 @@ private: char _mqttConnectionStateTopic[211] = {0}; String _lockPath; + const char* headerKeys[] = {"location"}; + String _latestVersion; + HTTPClient https; + Preferences* _preferences; Gpio* _gpio; IPConfiguration* _ipConfiguration = nullptr; @@ -137,6 +142,7 @@ private: unsigned long _lastConnectedTs = 0; unsigned long _lastMaintenanceTs = 0; + unsigned long _lastUpdateCheckTs = 0; unsigned long _lastRssiTs = 0; bool _mqttEnabled = true; static unsigned long _ignoreSubscriptionsTs; From 01100d22a925e5e49d650fb8088c19be20599441 Mon Sep 17 00:00:00 2001 From: iranl Date: Wed, 7 Feb 2024 22:21:39 +0100 Subject: [PATCH 02/13] Fixes --- Network.cpp | 3 ++- Network.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Network.cpp b/Network.cpp index cd7e110..c122c0b 100644 --- a/Network.cpp +++ b/Network.cpp @@ -11,6 +11,7 @@ Network* Network::_inst = nullptr; unsigned long Network::_ignoreSubscriptionsTs = 0; bool _versionPublished = false; +const char* headerKeys[] = {"location"}; RTC_NOINIT_ATTR char WiFi_fallbackDetect[14]; @@ -371,7 +372,7 @@ bool Network::update() if (httpResponseCode==302) { _latestVersion = https.header("location"); _latestVersion.replace(GITHUB_RELEASE_TAG_URL, ""); - publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion); + publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion.c_str()); } https.end(); diff --git a/Network.h b/Network.h index 7cda6a7..3a5012f 100644 --- a/Network.h +++ b/Network.h @@ -112,7 +112,6 @@ private: char _mqttConnectionStateTopic[211] = {0}; String _lockPath; - const char* headerKeys[] = {"location"}; String _latestVersion; HTTPClient https; From 8be5631394d65966af12b6eef034df65e6cc390f Mon Sep 17 00:00:00 2001 From: iranl Date: Wed, 7 Feb 2024 22:41:13 +0100 Subject: [PATCH 03/13] Show latest version on WebCfg --- Network.cpp | 5 +++++ Network.h | 1 + WebCfgServer.cpp | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/Network.cpp b/Network.cpp index c122c0b..0926257 100644 --- a/Network.cpp +++ b/Network.cpp @@ -663,6 +663,11 @@ int Network::mqttConnectionState() return _mqttConnectionState; } +String Network::latestHubVersion() +{ + return _latestVersion; +} + bool Network::encryptionSupported() { return _device->supportsEncryption(); diff --git a/Network.h b/Network.h index 3a5012f..46e367d 100644 --- a/Network.h +++ b/Network.h @@ -63,6 +63,7 @@ public: void publishPresenceDetection(char* csv); int mqttConnectionState(); // 0 = not connected; 1 = connected; 2 = connected and mqtt processed + String latestHubVersion(); bool encryptionSupported(); const String networkDeviceName() const; diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index 07f1446..2416b8b 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -612,6 +612,13 @@ void WebCfgServer::buildHtml(String& response) printParameter(response, "NUKI Opener state", lockstateArr); } printParameter(response, "Firmware", version.c_str(), "/info"); + + String _latestVersion = _network->latestHubVersion(); + + //if (_latestVersion.toFloat() > atof(NUKI_HUB_VERSION) || (_latestVersion.toFloat() == atof(NUKI_HUB_VERSION) && _latestVersion.c_str() != NUKI_HUB_VERSION)) { + printParameter(response, "Latest Firmware", _latestVersion.c_str(), GITHUB_LATEST_RELEASE_URL); + //} + response.concat("

"); response.concat("

MQTT and Network Configuration

"); From 4fde6d3ebb7d61e98798d125b84efd4c0c56f001 Mon Sep 17 00:00:00 2001 From: iranl Date: Wed, 7 Feb 2024 23:03:22 +0100 Subject: [PATCH 04/13] Add HA sensor for latest version --- Network.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Network.cpp b/Network.cpp index 0926257..958bfbf 100644 --- a/Network.cpp +++ b/Network.cpp @@ -915,7 +915,7 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n publishHassTopic("sensor", "nuki_hub_version", uidString, - "_nuki_hub__version", + "_nuki_hub_version", "NUKI Hub version", name, baseTopic, @@ -927,6 +927,23 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n "", { { "enabled_by_default", "true" }, {"ic", "mdi:counter"}}); + + // NUKI Hub latest + publishHassTopic("sensor", + "nuki_hub_latest", + uidString, + "_nuki_hub_latest", + "NUKI Hub latest", + name, + baseTopic, + _lockPath + mqtt_topic_info_nuki_hub_latest, + deviceType, + "", + "", + "diagnostic", + "", + { { "enabled_by_default", "true" }, + {"ic", "mdi:counter"}}); // LED enabled publishHassTopic("switch", From 83eeaf7f6d09f6247e58ecbd53cbdce226e39bc1 Mon Sep 17 00:00:00 2001 From: iranl Date: Thu, 8 Feb 2024 20:50:16 +0100 Subject: [PATCH 05/13] Change to GitHub API URL --- Config.h | 2 +- Network.cpp | 28 +++++++++++++++++----------- Network.h | 3 ++- WebCfgServer.cpp | 2 +- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/Config.h b/Config.h index 9c28fa0..aa31c61 100644 --- a/Config.h +++ b/Config.h @@ -2,7 +2,7 @@ #define NUKI_HUB_VERSION "8.32-pre-3" #define GITHUB_LATEST_RELEASE_URL "https://github.com/technyon/nuki_hub/releases/latest" -#define GITHUB_RELEASE_TAG_URL "https://github.com/technyon/nuki_hub/releases/tag/" +#define GITHUB_LATEST_RELEASE_API_URL "https://api.github.com/repos/technyon/nuki_hub/releases/latest" #define MQTT_QOS_LEVEL 1 #define MQTT_CLEAN_SESSIONS false diff --git a/Network.cpp b/Network.cpp index 958bfbf..cb9bfab 100644 --- a/Network.cpp +++ b/Network.cpp @@ -11,7 +11,6 @@ Network* Network::_inst = nullptr; unsigned long Network::_ignoreSubscriptionsTs = 0; bool _versionPublished = false; -const char* headerKeys[] = {"location"}; RTC_NOINIT_ATTR char WiFi_fallbackDetect[14]; @@ -363,16 +362,20 @@ bool Network::update() { _lastUpdateCheckTs = ts; - https.collectHeaders(headerKeys, 1); - https.setFollowRedirects(HTTPC_DISABLE_FOLLOW_REDIRECTS); - https.begin(GITHUB_LATEST_RELEASE_URL); + https.useHTTP10(true); + https.begin(GITHUB_LATEST_RELEASE_API_URL); int httpResponseCode = https.GET(); - if (httpResponseCode==302) { - _latestVersion = https.header("location"); - _latestVersion.replace(GITHUB_RELEASE_TAG_URL, ""); - publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion.c_str()); + if (httpResponseCode == HTTP_CODE_OK || httpResponseCode == HTTP_CODE_MOVED_PERMANENTLY) { + DynamicJsonDocument doc(6144); + DeserializationError jsonError = deserializeJson(doc, https.getStream()); + + if (!jsonError) { + _latestVersion = doc["tag_name"]; + _latestVersionUrl = doc["assets"][0]["browser_download_url"]; + publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion); + } } https.end(); @@ -663,11 +666,16 @@ int Network::mqttConnectionState() return _mqttConnectionState; } -String Network::latestHubVersion() +const char* Network::latestHubVersion() { return _latestVersion; } +const char* Network::latestHubVersionUrl() +{ + return _latestVersionUrl; +} + bool Network::encryptionSupported() { return _device->supportsEncryption(); @@ -1043,8 +1051,6 @@ void Network::publishHASSConfigAdditionalButtons(char *deviceType, const char *b { "pl_prs", "lockNgoUnlatch" }}); } - -//json["cmd_t"] = String("~") + String(mqtt_topic_lock_action); void Network::publishHASSConfigBatLevel(char *deviceType, const char *baseTopic, char *name, char *uidString) { String discoveryTopic = _preferences->getString(preference_mqtt_hass_discovery); diff --git a/Network.h b/Network.h index 46e367d..b7b142a 100644 --- a/Network.h +++ b/Network.h @@ -63,7 +63,8 @@ public: void publishPresenceDetection(char* csv); int mqttConnectionState(); // 0 = not connected; 1 = connected; 2 = connected and mqtt processed - String latestHubVersion(); + const char* _latestVersion; + const char* _latestVersionUrl; bool encryptionSupported(); const String networkDeviceName() const; diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index 2416b8b..3315590 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -616,7 +616,7 @@ void WebCfgServer::buildHtml(String& response) String _latestVersion = _network->latestHubVersion(); //if (_latestVersion.toFloat() > atof(NUKI_HUB_VERSION) || (_latestVersion.toFloat() == atof(NUKI_HUB_VERSION) && _latestVersion.c_str() != NUKI_HUB_VERSION)) { - printParameter(response, "Latest Firmware", _latestVersion.c_str(), GITHUB_LATEST_RELEASE_URL); + printParameter(response, "Latest Firmware", _latestVersion, GITHUB_LATEST_RELEASE_URL); //} response.concat("

"); From f9a64b6e523a4d3a7b352660b42074b5be3c8476 Mon Sep 17 00:00:00 2001 From: iranl Date: Thu, 8 Feb 2024 20:54:09 +0100 Subject: [PATCH 06/13] Fixes --- Network.h | 7 ++++--- WebCfgServer.cpp | 4 +--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Network.h b/Network.h index b7b142a..6b6dbc0 100644 --- a/Network.h +++ b/Network.h @@ -63,8 +63,8 @@ public: void publishPresenceDetection(char* csv); int mqttConnectionState(); // 0 = not connected; 1 = connected; 2 = connected and mqtt processed - const char* _latestVersion; - const char* _latestVersionUrl; + const char* latestHubVersion; + const char* latestHubVersionUrl; bool encryptionSupported(); const String networkDeviceName() const; @@ -114,7 +114,8 @@ private: char _mqttConnectionStateTopic[211] = {0}; String _lockPath; - String _latestVersion; + const char* _latestVersion; + const char* _latestVersionUrl; HTTPClient https; Preferences* _preferences; diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index 3315590..960709e 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -613,10 +613,8 @@ void WebCfgServer::buildHtml(String& response) } printParameter(response, "Firmware", version.c_str(), "/info"); - String _latestVersion = _network->latestHubVersion(); - //if (_latestVersion.toFloat() > atof(NUKI_HUB_VERSION) || (_latestVersion.toFloat() == atof(NUKI_HUB_VERSION) && _latestVersion.c_str() != NUKI_HUB_VERSION)) { - printParameter(response, "Latest Firmware", _latestVersion, GITHUB_LATEST_RELEASE_URL); + printParameter(response, "Latest Firmware", _network->latestHubVersion(), GITHUB_LATEST_RELEASE_URL); //} response.concat("

"); From 2c71fedcfacd8f7d993db5ee7b349767f9e41424 Mon Sep 17 00:00:00 2001 From: iranl Date: Thu, 8 Feb 2024 20:57:21 +0100 Subject: [PATCH 07/13] Fixes --- Network.h | 4 ++-- WebCfgServer.cpp | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Network.h b/Network.h index 6b6dbc0..c2d6e00 100644 --- a/Network.h +++ b/Network.h @@ -63,8 +63,8 @@ public: void publishPresenceDetection(char* csv); int mqttConnectionState(); // 0 = not connected; 1 = connected; 2 = connected and mqtt processed - const char* latestHubVersion; - const char* latestHubVersionUrl; + const char* latestHubVersion(); + const char* latestHubVersionUrl(); bool encryptionSupported(); const String networkDeviceName() const; diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index 960709e..9e0bb28 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -613,8 +613,10 @@ void WebCfgServer::buildHtml(String& response) } printParameter(response, "Firmware", version.c_str(), "/info"); + const char* _latestVersion = _network->latestHubVersion(); + //if (_latestVersion.toFloat() > atof(NUKI_HUB_VERSION) || (_latestVersion.toFloat() == atof(NUKI_HUB_VERSION) && _latestVersion.c_str() != NUKI_HUB_VERSION)) { - printParameter(response, "Latest Firmware", _network->latestHubVersion(), GITHUB_LATEST_RELEASE_URL); + printParameter(response, "Latest Firmware", _latestVersion, GITHUB_LATEST_RELEASE_URL); //} response.concat("

"); From ef95e8721e53827147b3092d46e87e55adb28272 Mon Sep 17 00:00:00 2001 From: iranl Date: Thu, 8 Feb 2024 21:35:55 +0100 Subject: [PATCH 08/13] Checkbox, Update Topic, Remove HA topics --- Network.cpp | 213 ++++++++++++++++++++-------------------------- PreferencesKeys.h | 5 +- WebCfgServer.cpp | 15 +++- 3 files changed, 106 insertions(+), 127 deletions(-) diff --git a/Network.cpp b/Network.cpp index 30a49fb..a80131a 100644 --- a/Network.cpp +++ b/Network.cpp @@ -358,27 +358,30 @@ bool Network::update() _lastMaintenanceTs = ts; } - if(_lastUpdateCheckTs == 0 || (ts - _lastUpdateCheckTs) > 86400000) + if(_preferences->getBool(preference_check_updates)) { - _lastUpdateCheckTs = ts; - - https.useHTTP10(true); - https.begin(GITHUB_LATEST_RELEASE_API_URL); + if(_lastUpdateCheckTs == 0 || (ts - _lastUpdateCheckTs) > 86400000) + { + _lastUpdateCheckTs = ts; + + https.useHTTP10(true); + https.begin(GITHUB_LATEST_RELEASE_API_URL); - int httpResponseCode = https.GET(); + int httpResponseCode = https.GET(); - if (httpResponseCode == HTTP_CODE_OK || httpResponseCode == HTTP_CODE_MOVED_PERMANENTLY) { - DynamicJsonDocument doc(6144); - DeserializationError jsonError = deserializeJson(doc, https.getStream()); + if (httpResponseCode == HTTP_CODE_OK || httpResponseCode == HTTP_CODE_MOVED_PERMANENTLY) { + DynamicJsonDocument doc(6144); + DeserializationError jsonError = deserializeJson(doc, https.getStream()); - if (!jsonError) { - _latestVersion = doc["tag_name"]; - _latestVersionUrl = doc["assets"][0]["browser_download_url"]; - publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion); - } + if (!jsonError) { + _latestVersion = doc["tag_name"]; + _latestVersionUrl = doc["assets"][0]["browser_download_url"]; + publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion); + } + } + + https.end(); } - - https.end(); } for(const auto& gpioTs : _gpioTs) @@ -948,23 +951,50 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n "", { { "enabled_by_default", "true" }, {"ic", "mdi:counter"}}); - - // NUKI Hub latest - publishHassTopic("sensor", - "nuki_hub_latest", - uidString, - "_nuki_hub_latest", - "NUKI Hub latest", - name, - baseTopic, - _lockPath + mqtt_topic_info_nuki_hub_latest, - deviceType, - "", - "", - "diagnostic", - "", - { { "enabled_by_default", "true" }, - {"ic", "mdi:counter"}}); + + if(_preferences->getBool(preference_check_updates)) + { + // NUKI Hub latest + publishHassTopic("sensor", + "nuki_hub_latest", + uidString, + "_nuki_hub_latest", + "NUKI Hub latest", + name, + baseTopic, + _lockPath + mqtt_topic_info_nuki_hub_latest, + deviceType, + "", + "", + "diagnostic", + "", + { { "enabled_by_default", "true" }, + {"ic", "mdi:counter"}}); + + // NUKI Hub update + publishHassTopic("update", + "nuki_hub_update", + uidString, + "_nuki_hub_update", + "NUKI Hub Firmware Update", + name, + baseTopic, + _lockPath + mqtt_topic_info_nuki_hub_version, + deviceType, + "firmware", + "", + "", + "", + { { "enabled_by_default", "true" }, + { "entity_picture", "https://raw.githubusercontent.com/technyon/nuki_hub/master/icon/icon-192x192.png" }, + { "release_url", GITHUB_LATEST_RELEASE_URL }, + { "latest_version_topic", _lockPath + mqtt_topic_info_nuki_hub_latest }}); + } + else + { + removeHassTopic("sensor", "nuki_hub_latest", uidString); + removeHassTopic("update", "nuki_hub_update", uidString); + } // NUKI Hub IP Address publishHassTopic("sensor", @@ -1404,95 +1434,34 @@ void Network::removeHASSConfig(char* uidString) if(discoveryTopic != "") { - String path = discoveryTopic; - path.concat("/lock/"); - path.concat(uidString); - path.concat("/smartlock/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/binary_sensor/"); - path.concat(uidString); - path.concat("/battery_low/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/button/"); - path.concat(uidString); - path.concat("/lockngo/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/button/"); - path.concat(uidString); - path.concat("/lockngounlatch/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/button/"); - path.concat(uidString); - path.concat("/unlatch/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/sensor/"); - path.concat(uidString); - path.concat("/battery_voltage/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/sensor/"); - path.concat(uidString); - path.concat("/trigger/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/sensor/"); - path.concat(uidString); - path.concat("/battery_level/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/sensor/"); - path.concat(uidString); - path.concat("/sound_level/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/sensor/"); - path.concat(uidString); - path.concat("/nuki_hub_ip/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/number/"); - path.concat(uidString); - path.concat("/sound_level/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/binary_sensor/"); - path.concat(uidString); - path.concat("/door_sensor/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/binary_sensor/"); - path.concat(uidString); - path.concat("/ring/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/sensor/"); - path.concat(uidString); - path.concat("/wifi_signal_strength/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); - - path = discoveryTopic; - path.concat("/sensor/"); - path.concat(uidString); - path.concat("/bluetooth_signal_strength/config"); - _device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, ""); + removeHassTopic("lock", "smartlock", uidString); + removeHassTopic("binary_sensor", "battery_low", uidString); + removeHassTopic("binary_sensor", "keypad_battery_low", uidString); + removeHassTopic("sensor", "battery_voltage", uidString); + removeHassTopic("sensor", "trigger", uidString); + removeHassTopic("binary_sensor", "mqtt_connected", uidString); + removeHassTopic("switch", "reset", uidString); + removeHassTopic("sensor", "firmware_version", uidString); + removeHassTopic("sensor", "hardware_version", uidString); + removeHassTopic("sensor", "nuki_hub_version", uidString); + removeHassTopic("sensor", "nuki_hub_latest", uidString); + removeHassTopic("update", "nuki_hub_update", uidString); + removeHassTopic("sensor", "nuki_hub_ip", uidString); + removeHassTopic("switch", "led_enabled", uidString); + removeHassTopic("switch", "button_enabled", uidString); + removeHassTopic("button", "unlatch", uidString); + removeHassTopic("button", "lockngo", uidString); + removeHassTopic("button", "lockngounlatch", uidString); + removeHassTopic("sensor", "battery_level", uidString); + removeHassTopic("binary_sensor", "door_sensor", uidString); + removeHassTopic("binary_sensor", "ring", uidString); + removeHassTopic("number", "led_brightness", uidString); + removeHassTopic("sensor", "sound_level", uidString); + removeHassTopic("number", "sound_level", uidString); + removeHassTopic("sensor", "last_action_authorization", uidString); + removeHassTopic("sensor", "keypad_status", uidString); + removeHassTopic("sensor", "wifi_signal_strength", uidString); + removeHassTopic("sensor", "bluetooth_signal_strength", uidString); } } diff --git a/PreferencesKeys.h b/PreferencesKeys.h index 13757d5..c1632f4 100644 --- a/PreferencesKeys.h +++ b/PreferencesKeys.h @@ -14,6 +14,7 @@ #define preference_mqtt_lock_path "mqttpath" #define preference_opener_enabled "openerena" #define preference_mqtt_opener_path "mqttoppath" +#define preference_check_updates "checkupdates" #define preference_lock_max_keypad_code_count "maxkpad" #define preference_opener_max_keypad_code_count "opmaxkpad" #define preference_mqtt_ca "mqttca" @@ -62,7 +63,7 @@ private: std::vector _keys = { preference_started_before, preference_device_id_lock, preference_device_id_opener, preference_mqtt_broker, preference_mqtt_broker_port, - preference_mqtt_user, preference_mqtt_password, preference_mqtt_log_enabled, preference_lock_enabled, + preference_mqtt_user, preference_mqtt_password, preference_mqtt_log_enabled, preference_check_updates, preference_lock_enabled, preference_mqtt_lock_path, preference_opener_enabled, preference_mqtt_opener_path, preference_lock_max_keypad_code_count, preference_opener_max_keypad_code_count, preference_mqtt_ca, preference_mqtt_crt, preference_mqtt_key, preference_mqtt_hass_discovery, preference_mqtt_hass_cu_url, @@ -85,7 +86,7 @@ private: }; std::vector _boolPrefs = { - preference_started_before, preference_mqtt_log_enabled, preference_lock_enabled, preference_opener_enabled, + preference_started_before, preference_mqtt_log_enabled, preference_check_updates, preference_lock_enabled, preference_opener_enabled, preference_restart_on_disconnect, preference_keypad_control_enabled, preference_register_as_app, preference_ip_dhcp_enabled, preference_publish_authdata, preference_has_mac_saved, preference_publish_debug_info, preference_network_wifi_fallback_disabled }; diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index 5918386..a463939 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -377,6 +377,11 @@ bool WebCfgServer::processArgs(String& message) _preferences->putBool(preference_mqtt_log_enabled, (value == "1")); configChanged = true; } + else if(key == "CHECKUPDATE") + { + _preferences->putBool(preference_check_updates, (value == "1")); + configChanged = true; + } else if(key == "DHCPENA") { _preferences->putBool(preference_ip_dhcp_enabled, (value == "1")); @@ -620,9 +625,12 @@ void WebCfgServer::buildHtml(String& response) const char* _latestVersion = _network->latestHubVersion(); - //if (_latestVersion.toFloat() > atof(NUKI_HUB_VERSION) || (_latestVersion.toFloat() == atof(NUKI_HUB_VERSION) && _latestVersion.c_str() != NUKI_HUB_VERSION)) { - printParameter(response, "Latest Firmware", _latestVersion, GITHUB_LATEST_RELEASE_URL); - //} + if(_preferences->getBool(preference_check_updates)) + { + //if(atof(_latestVersion) > atof(NUKI_HUB_VERSION) || (atof(_latestVersion) == atof(NUKI_HUB_VERSION) && _latestVersion != NUKI_HUB_VERSION)) { + printParameter(response, "Latest Firmware", _latestVersion, GITHUB_LATEST_RELEASE_URL); + //} + } response.concat("

"); @@ -786,6 +794,7 @@ void WebCfgServer::buildMqttConfigHtml(String &response) printInputField(response, "NETTIMEOUT", "Network Timeout until restart (seconds; -1 to disable)", _preferences->getInt(preference_network_timeout), 5); printCheckBox(response, "RSTDISC", "Restart on disconnect", _preferences->getBool(preference_restart_on_disconnect)); printCheckBox(response, "MQTTLOG", "Enable MQTT logging", _preferences->getBool(preference_mqtt_log_enabled)); + printCheckBox(response, "CHECKUPDATE", "Check for Firmware Updates every 24h", _preferences->getBool(preference_check_updates)); response.concat(""); response.concat("* If no encryption is configured for the MQTT broker, leave empty. Only supported for WiFi connections.

"); From c5397d6c3564a08e694aa45ffe1f04732c78f0be Mon Sep 17 00:00:00 2001 From: iranl Date: Thu, 8 Feb 2024 22:12:13 +0100 Subject: [PATCH 09/13] Fixes --- Network.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Network.cpp b/Network.cpp index a80131a..ff813ec 100644 --- a/Network.cpp +++ b/Network.cpp @@ -971,7 +971,11 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n { { "enabled_by_default", "true" }, {"ic", "mdi:counter"}}); - // NUKI Hub update + // NUKI Hub update + char latest_version_topic[250]; + _lockPath.toCharArray(latest_version_topic,_lockPath.length() + 1); + strcat(latest_version_topic, mqtt_topic_info_nuki_hub_latest); + publishHassTopic("update", "nuki_hub_update", uidString, @@ -988,7 +992,7 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n { { "enabled_by_default", "true" }, { "entity_picture", "https://raw.githubusercontent.com/technyon/nuki_hub/master/icon/icon-192x192.png" }, { "release_url", GITHUB_LATEST_RELEASE_URL }, - { "latest_version_topic", _lockPath + mqtt_topic_info_nuki_hub_latest }}); + { "latest_version_topic", latest_version_topic }}); } else { From e3baa8e8c0f9fbdd22c1387c10c77ca8803a56f6 Mon Sep 17 00:00:00 2001 From: iranl Date: Thu, 8 Feb 2024 22:17:50 +0100 Subject: [PATCH 10/13] Use small favicon --- Network.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Network.cpp b/Network.cpp index ff813ec..c28412b 100644 --- a/Network.cpp +++ b/Network.cpp @@ -990,7 +990,7 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n "", "", { { "enabled_by_default", "true" }, - { "entity_picture", "https://raw.githubusercontent.com/technyon/nuki_hub/master/icon/icon-192x192.png" }, + { "entity_picture", "https://raw.githubusercontent.com/technyon/nuki_hub/master/icon/favicon-32x32.png" }, { "release_url", GITHUB_LATEST_RELEASE_URL }, { "latest_version_topic", latest_version_topic }}); } From d73526505ae36ee5dc79970232cf1311058fab3c Mon Sep 17 00:00:00 2001 From: iranl Date: Fri, 9 Feb 2024 14:55:54 +0100 Subject: [PATCH 11/13] Update Network.cpp --- Network.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Network.cpp b/Network.cpp index c28412b..c371833 100644 --- a/Network.cpp +++ b/Network.cpp @@ -980,14 +980,14 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n "nuki_hub_update", uidString, "_nuki_hub_update", - "NUKI Hub Firmware Update", + "NUKI Hub firmware update", name, baseTopic, _lockPath + mqtt_topic_info_nuki_hub_version, deviceType, "firmware", "", - "", + "diagnostic", "", { { "enabled_by_default", "true" }, { "entity_picture", "https://raw.githubusercontent.com/technyon/nuki_hub/master/icon/favicon-32x32.png" }, From 3804a54bf6832ee9846f159aa1a0161c5a09f692 Mon Sep 17 00:00:00 2001 From: iranl Date: Tue, 13 Feb 2024 21:05:43 +0100 Subject: [PATCH 12/13] Update over HTTPS Update Network.cpp Revert "Update over HTTPS" This reverts commit 505e988c5f7cb854d5008f61051c21a0eece7c59. Revert "Update Network.cpp" This reverts commit f81876fea10538d983d65bdee0f24a1f218a01dc. From 8139c237856b4ecb61985b088b432a4f50355d49 Mon Sep 17 00:00:00 2001 From: iranl Date: Thu, 15 Feb 2024 22:46:47 +0100 Subject: [PATCH 13/13] Add buttons to /ota --- Config.h | 1 + Network.cpp | 6 ------ Network.h | 2 -- WebCfgServer.cpp | 22 +++++++++++++++++----- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Config.h b/Config.h index cb36d31..c8f1bf4 100644 --- a/Config.h +++ b/Config.h @@ -4,6 +4,7 @@ #define GITHUB_LATEST_RELEASE_URL "https://github.com/technyon/nuki_hub/releases/latest" #define GITHUB_LATEST_RELEASE_API_URL "https://api.github.com/repos/technyon/nuki_hub/releases/latest" +#define GITHUB_LATEST_RELEASE_BINARY_URL "https://github.com/technyon/nuki_hub/raw/master/webflash/nuki_hub.bin" #define MQTT_QOS_LEVEL 1 #define MQTT_CLEAN_SESSIONS false diff --git a/Network.cpp b/Network.cpp index 48b823f..ba688af 100644 --- a/Network.cpp +++ b/Network.cpp @@ -375,7 +375,6 @@ bool Network::update() if (!jsonError) { _latestVersion = doc["tag_name"]; - _latestVersionUrl = doc["assets"][0]["browser_download_url"]; publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion); } } @@ -675,11 +674,6 @@ const char* Network::latestHubVersion() return _latestVersion; } -const char* Network::latestHubVersionUrl() -{ - return _latestVersionUrl; -} - bool Network::encryptionSupported() { return _device->supportsEncryption(); diff --git a/Network.h b/Network.h index c2d6e00..009511c 100644 --- a/Network.h +++ b/Network.h @@ -64,7 +64,6 @@ public: int mqttConnectionState(); // 0 = not connected; 1 = connected; 2 = connected and mqtt processed const char* latestHubVersion(); - const char* latestHubVersionUrl(); bool encryptionSupported(); const String networkDeviceName() const; @@ -115,7 +114,6 @@ private: String _lockPath; const char* _latestVersion; - const char* _latestVersionUrl; HTTPClient https; Preferences* _preferences; diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index 3028246..daacb29 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -356,7 +356,7 @@ bool WebCfgServer::processArgs(String& message) { _preferences->putString(preference_mqtt_hass_cu_url, value); configChanged = true; - } + } else if(key == "HOSTNAME") { _preferences->putString(preference_hostname, value); @@ -622,16 +622,16 @@ void WebCfgServer::buildHtml(String& response) printParameter(response, "Nuki Opener state", lockstateArr); } printParameter(response, "Firmware", version.c_str(), "/info"); - + const char* _latestVersion = _network->latestHubVersion(); - + if(_preferences->getBool(preference_check_updates)) { //if(atof(_latestVersion) > atof(NUKI_HUB_VERSION) || (atof(_latestVersion) == atof(NUKI_HUB_VERSION) && _latestVersion != NUKI_HUB_VERSION)) { - printParameter(response, "Latest Firmware", _latestVersion, GITHUB_LATEST_RELEASE_URL); + printParameter(response, "Latest Firmware", _latestVersion, "/ota"); //} } - + response.concat("

"); response.concat("

MQTT and Network Configuration

"); @@ -741,6 +741,18 @@ void WebCfgServer::buildOtaHtml(String &response, bool errored) response.concat("
Choose the updated nuki_hub.bin file to upload:
"); response.concat("
"); + + if(_preferences->getBool(preference_check_updates)) + { + response.concat(""); + + response.concat("

"); + } + response.concat("
Initiating Over-the-air update. This will take about two minutes, please be patient.
You will be forwarded automatically when the update is complete.
"); response.concat("