diff --git a/README.md b/README.md
index d152302..8edd8d5 100644
--- a/README.md
+++ b/README.md
@@ -587,7 +587,10 @@ The following mapping between Home Assistant services and Nuki commands is setup
| lock.unlock | Unlock | Enable Ring To Open | Enable Continuous Mode |
| lock.open | Unlatch | Electric Strike Actuation | Electric Strike Actuation |
-NOTE: MQTT Discovery uses retained MQTT messages to store devices configurations. In order to avoid orphan configurations on your broker please disable autodiscovery first if you no longer want to use this software. Retained messages are automatically cleared when unpairing and when changing/disabling autodiscovery topic in MQTT Configuration page.
+NOTE: MQTT Discovery uses retained MQTT messages to store devices configurations.
+In order to avoid orphan configurations on your broker please disable autodiscovery first if you no longer want to use this software.
+Retained messages are automatically cleared when unpairing and when changing/disabling autodiscovery topic in MQTT Configuration page.
+If you experience "ghost" entities/devices related to NukiHub you can completely purge NukiHub related Home Assistant discovery topics from your MQTT broker by following the instructions [here](#purging-home-assistant-discovery-mqtt-topics)
## Keypad control using JSON (optional)
@@ -782,6 +785,16 @@ Make sure you are using at least version 2023.8.0 of Home Assistant.
The Home Assistant developers have made changes to MQTT auto discovery which break support for older version and Nuki Hub has adopted these changes.
This unfortunately means that older versions of Home Assistant are not supported by the Nuki Hub discovery implementation anymore.
+### Purging Home Assistant discovery MQTT topics
+
+- Download the latest version of MQTT Explorer for your system from https://mqtt-explorer.com/
+- Run MQTT Explorer and connect to your MQTT broker
+- Enter `ids":["nuki_` in the MQTT explorer search bar
+- Click on the root `homeassistant` topic
+- Press delete on your keyboard
+- Click Yes to confirm deletion
+- Reboot all NukiHub devices connected to the MQTT broker to recreate the correct topics for Home Assistant
+
### Nuki Hub in bridge mode doesn't work when Thread or Wi-Fi on a Nuki Smartlock (3.0 Pro / 4.0 / 4.0 Pro) is turned on.
According to Nuki this is by design and part of the specification of the Pro lock.
diff --git a/src/Config.h b/src/Config.h
index 8de9162..aaa471f 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -5,7 +5,7 @@
#define NUKI_HUB_VERSION "9.07"
#define NUKI_HUB_VERSION_INT (uint32_t)907
#define NUKI_HUB_BUILD "unknownbuildnr"
-#define NUKI_HUB_DATE "2024-12-27"
+#define NUKI_HUB_DATE "2024-12-30"
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"
diff --git a/src/HomeAssistantDiscovery.cpp b/src/HomeAssistantDiscovery.cpp
index 95e5e92..63da986 100644
--- a/src/HomeAssistantDiscovery.cpp
+++ b/src/HomeAssistantDiscovery.cpp
@@ -16,7 +16,35 @@ HomeAssistantDiscovery::HomeAssistantDiscovery(NetworkDevice* device, Preference
_checkUpdates = _preferences->getBool(preference_check_updates, false);
_updateFromMQTT = _preferences->getBool(preference_update_from_mqtt, false);
_hostname = _preferences->getString(preference_hostname, "");
- sprintf(_nukiHubUidString, "%u", _preferences->getUInt(preference_device_id_lock, 0));
+ uint32_t savedDevId = _preferences->getUInt(preference_nukihub_id, 0);
+ uint32_t curDevId = ESP.getEfuseMac() & 0xFFFFFFFF;
+
+ if (savedDevId == 0)
+ {
+ _preferences->putUInt(preference_nukihub_id, curDevId);
+ char uidString[20];
+ itoa(_preferences->getUInt(preference_device_id_lock, 0), uidString, 10);
+ removeHASSConfig(uidString);
+ delay(3000);
+ }
+ else if(savedDevId != curDevId)
+ {
+ _preferences->putUInt(preference_nukihub_id, curDevId);
+ Log->print("Efuse ID: ");
+ Log->println(curDevId);
+ Log->print("Saved ID: ");
+ Log->println(savedDevId);
+ Log->println("Efuse ID and NukiHub device ID do not match, removing HASS setup for incorrect NukiHub device ID.");
+ char uidString[20];
+ itoa(_preferences->getUInt(preference_device_id_lock, 0), uidString, 10);
+ removeHASSConfig(uidString);
+ delay(3000);
+ itoa(savedDevId, uidString, 10);
+ removeHASSConfig(uidString);
+ delay(3000);
+ }
+
+ sprintf(_nukiHubUidString, "%u", curDevId);
}
void HomeAssistantDiscovery::setupHASS(int type, uint32_t nukiId, char* nukiName, const char* firmwareVersion, const char* hardwareVersion, bool hasDoorSensor, bool hasKeypad)
@@ -65,6 +93,7 @@ void HomeAssistantDiscovery::setupHASS(int type, uint32_t nukiId, char* nukiName
void HomeAssistantDiscovery::disableHASS()
{
removeHASSConfig(_nukiHubUidString);
+ delay(3000);
char uidString[20];
@@ -72,11 +101,13 @@ void HomeAssistantDiscovery::disableHASS()
{
itoa(_preferences->getUInt(preference_nuki_id_lock, 0), uidString, 16);
removeHASSConfig(uidString);
+ delay(3000);
}
if(_preferences->getUInt(preference_nuki_id_opener, 0) != 0)
{
itoa(_preferences->getUInt(preference_nuki_id_opener, 0), uidString, 16);
removeHASSConfig(uidString);
+ delay(3000);
}
}
@@ -592,7 +623,7 @@ void HomeAssistantDiscovery::publishHASSDeviceConfig(char* deviceType, const cha
{(char*)"pl_off", (char*)"0"},
{(char*)"val_tpl", (char*)"{{value_json.charging}}" }
});
-
+
// Battery voltage
publishHassTopic("sensor",
"battery_voltage",
@@ -2973,9 +3004,12 @@ void HomeAssistantDiscovery::removeHassTopic(const String& mqttDeviceType, const
void HomeAssistantDiscovery::removeHASSConfig(char* uidString)
{
+ Log->println("Removing HASS entities with ID:");
+ Log->println(uidString);
+
removeHassTopic((char*)"lock", (char*)"smartlock", uidString);
removeHassTopic((char*)"binary_sensor", (char*)"battery_low", uidString);
- removeHassTopic((char*)"binary_sensor", (char*)"battery_charging", uidString);
+ removeHassTopic((char*)"binary_sensor", (char*)"battery_charging", uidString);
removeHassTopic((char*)"binary_sensor", (char*)"keypad_battery_low", uidString);
removeHassTopic((char*)"sensor", (char*)"battery_voltage", uidString);
removeHassTopic((char*)"sensor", (char*)"trigger", uidString);
diff --git a/src/PreferencesKeys.h b/src/PreferencesKeys.h
index 149e70a..f1b961a 100644
--- a/src/PreferencesKeys.h
+++ b/src/PreferencesKeys.h
@@ -138,8 +138,8 @@
#define preference_lock_max_timecontrol_entry_count (char*)"maxtc"
#define preference_opener_max_timecontrol_entry_count (char*)"opmaxtc"
#define preference_latest_version (char*)"latest"
-#define preference_wifi_converted (char*)"wifiConv"
#define preference_reset_mqtt_topics (char*)"rstMqtt"
+#define preference_nukihub_id (char*)"nukihubId"
//OBSOLETE
#define preference_access_level (char*)"accLvl"
@@ -386,7 +386,7 @@ private:
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_auth_max_entries, preference_wifi_ssid, preference_wifi_pass,
preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_mqtt_hass_enabled, preference_hass_device_discovery, preference_retain_gpio,
preference_debug_connect, preference_debug_communication, preference_debug_readable_data, preference_debug_hex_data, preference_debug_command, preference_connect_mode,
- preference_lock_force_id, preference_lock_force_doorsensor, preference_lock_force_keypad, preference_opener_force_id, preference_opener_force_keypad
+ preference_lock_force_id, preference_lock_force_doorsensor, preference_lock_force_keypad, preference_opener_force_id, preference_opener_force_keypad, preference_nukihub_id
};
std::vector _redact =
{
diff --git a/src/WebCfgServer.cpp b/src/WebCfgServer.cpp
index 7b04285..ebf4d31 100644
--- a/src/WebCfgServer.cpp
+++ b/src/WebCfgServer.cpp
@@ -1265,14 +1265,6 @@ esp_err_t WebCfgServer::sendSettings(PsychicRequest *request)
{
continue;
}
- if(strcmp(key, preference_device_id_lock) == 0)
- {
- continue;
- }
- if(strcmp(key, preference_device_id_opener) == 0)
- {
- continue;
- }
if(!redacted) if(std::find(redactedPrefs.begin(), redactedPrefs.end(), key) != redactedPrefs.end())
{
continue;
@@ -4475,6 +4467,8 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request)
response.print(_preferences->getString(preference_mqtt_hass_discovery, "") + "/");
response.print("\nNuki Hub configuration URL for HA: ");
response.print(_preferences->getString(preference_mqtt_hass_cu_url, "").length() > 0 ? _preferences->getString(preference_mqtt_hass_cu_url, "") : "http://" + _network->localIP());
+ response.print("\nNuki Hub ID: ");
+ response.print(_preferences->getUInt(preference_nukihub_id, 0));
}
else
{