From 13494d69c59ea9fee82185a6b67af3fad1625534 Mon Sep 17 00:00:00 2001 From: iranl Date: Wed, 22 Jan 2025 22:08:27 +0100 Subject: [PATCH] Set entities as unavailable in HA if state undefined --- src/HomeAssistantDiscovery.cpp | 16 ++++++++++++---- src/MqttTopics.h | 1 + src/NukiNetworkLock.cpp | 9 +++++++++ src/NukiNetworkOpener.cpp | 9 +++++++++ src/WebCfgServer.cpp | 18 ++++++++++++++++-- src/main.cpp | 4 +++- 6 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/HomeAssistantDiscovery.cpp b/src/HomeAssistantDiscovery.cpp index e40bf5b..7b7473b 100644 --- a/src/HomeAssistantDiscovery.cpp +++ b/src/HomeAssistantDiscovery.cpp @@ -475,7 +475,7 @@ void HomeAssistantDiscovery::publishHASSConfig(char *deviceType, const char *bas removeHASSConfigTopic((char*)"sensor", (char*)"last_action_authorization", uidString); } else - { + { removeHASSConfigTopic((char*)"sensor", (char*)"rolling_log", uidString); } if(hasKeypad) @@ -519,6 +519,8 @@ void HomeAssistantDiscovery::publishHASSDeviceConfig(char* deviceType, const cha json["unique_id"] = String(uidString) + "_lock"; json["cmd_t"] = String("~") + String(mqtt_topic_lock_action); json["avty"][0]["t"] = availabilityTopic; + json["avty"][1]["t"] = String("~") + String(mqtt_topic_lock_availability); + json["avty_mode"] = "all"; json["pl_lock"] = lockAction; json["pl_unlk"] = unlockAction; @@ -1878,7 +1880,7 @@ void HomeAssistantDiscovery::publishHASSConfigAdditionalLockEntities(char *devic { removeHassTopic((char*)"switch", (char*)"auto_update_enabled", uidString); } - + // Motor speed if((int)advancedLockConfigAclPrefs[23] == 1) { @@ -1895,7 +1897,7 @@ void HomeAssistantDiscovery::publishHASSConfigAdditionalLockEntities(char *devic { removeHassTopic((char*)"select", (char*)"motor_speed", uidString); } - + if((int)advancedLockConfigAclPrefs[24] == 1) { // Slow speed during night mode enabled @@ -3172,7 +3174,13 @@ JsonDocument HomeAssistantDiscovery::createHassJson(const String& uidString, json["cmd_t"] = commandTopic; } - json["avty"]["t"] = _baseTopic + mqtt_topic_mqtt_connection_state; + json["avty"][0]["t"] = _baseTopic + mqtt_topic_mqtt_connection_state; + + if (uidString != "query_lockstate") + { + json["avty"][1]["t"] = String("~") + String(mqtt_topic_lock_availability); + json["avty_mode"] = "all"; + } for(const auto& entry : additionalEntries) { diff --git a/src/MqttTopics.h b/src/MqttTopics.h index ef8f5de..8b84d18 100644 --- a/src/MqttTopics.h +++ b/src/MqttTopics.h @@ -25,6 +25,7 @@ #define mqtt_topic_lock_rssi (char*)"/rssi" #define mqtt_topic_lock_address (char*)"/address" #define mqtt_topic_lock_retry (char*)"/retry" +#define mqtt_topic_lock_availability (char*)"/availability" #define mqtt_topic_official_lock_action (char*)"/lockAction" //#define mqtt_topic_official_mode (char*)"/mode" diff --git a/src/NukiNetworkLock.cpp b/src/NukiNetworkLock.cpp index 8ecd0b1..4a79b01 100644 --- a/src/NukiNetworkLock.cpp +++ b/src/NukiNetworkLock.cpp @@ -420,6 +420,15 @@ void NukiNetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyT lockstateToString((NukiLock::LockState)_nukiOfficial->getOffState(), str); json["lock_state"] = str; } + + if(strcmp(str, "undefined") == 0) + { + _nukiPublisher->publishString(mqtt_topic_lock_availability, "offline", true); + } + else + { + _nukiPublisher->publishString(mqtt_topic_lock_availability, "online", true); + } json["lockngo_state"] = keyTurnerState.lockNgoTimer != 255 ? keyTurnerState.lockNgoTimer : 0; diff --git a/src/NukiNetworkOpener.cpp b/src/NukiNetworkOpener.cpp index 160608a..7031720 100644 --- a/src/NukiNetworkOpener.cpp +++ b/src/NukiNetworkOpener.cpp @@ -347,6 +347,15 @@ void NukiNetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& key publishState(keyTurnerState); } } + + if(strcmp(str, "undefined") == 0) + { + _nukiPublisher->publishString(mqtt_topic_lock_availability, "offline", true); + } + else + { + _nukiPublisher->publishString(mqtt_topic_lock_availability, "online", true); + } json["lock_state"] = str; diff --git a/src/WebCfgServer.cpp b/src/WebCfgServer.cpp index 800a5ea..b603468 100644 --- a/src/WebCfgServer.cpp +++ b/src/WebCfgServer.cpp @@ -20,6 +20,7 @@ extern const uint8_t x509_crt_imported_bundle_bin_start[] asm("_binary_x509_crt_bundle_start"); extern const uint8_t x509_crt_imported_bundle_bin_end[] asm("_binary_x509_crt_bundle_end"); +extern bool timeSynced; #ifndef NUKI_HUB_UPDATER #include @@ -736,7 +737,11 @@ void WebCfgServer::initialize() { if(_preferences->getBool(preference_cred_duo_approval, false)) { - if (startDuoAuth((char*)"Approve Nuki Hub export")) + if (!timeSynced) + { + return buildConfirmHtml(request, resp, "NTP time not synced yet, Duo not available, please wait for NTP to sync", 3, true); + } + else if (startDuoAuth((char*)"Approve Nuki Hub export")) { int duoResult = 2; @@ -949,7 +954,11 @@ void WebCfgServer::initialize() if(_preferences->getBool(preference_cred_duo_approval, false)) { - if (startDuoAuth((char*)"Approve Nuki Hub setting change")) + if (!timeSynced) + { + return buildConfirmHtml(request, resp, "NTP time not synced yet, Duo not available, please wait for NTP to sync", 3, true); + } + else if (startDuoAuth((char*)"Approve Nuki Hub setting change")) { int duoResult = 2; @@ -1953,6 +1962,11 @@ esp_err_t WebCfgServer::buildCoredumpHtml(PsychicRequest *request, PsychicRespon esp_err_t WebCfgServer::buildDuoHtml(PsychicRequest *request, PsychicResponse* resp) { + if (!timeSynced) + { + return buildConfirmHtml(request, resp, "NTP time not synced yet, Duo not available, please wait for NTP to sync", 3, true); + } + bool duo = startDuoAuth((char*)"Approve Nuki Hub login"); if (!duo) diff --git a/src/main.cpp b/src/main.cpp index 18ee425..9da9be3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -90,6 +90,7 @@ RTC_NOINIT_ATTR bool disableNetwork; RTC_NOINIT_ATTR bool wifiFallback; RTC_NOINIT_ATTR bool ethCriticalFailure; bool coredumpPrinted = true; +bool timeSynced = false; int lastHTTPeventId = -1; bool doOta = false; @@ -182,7 +183,8 @@ uint8_t checkPartition() } void cbSyncTime(struct timeval *tv) { - Log->println("NTP time synched"); + Log->println("NTP time synced"); + timeSynced = true; } void networkTask(void *pvParameters)