diff --git a/src/MqttTopics.h b/src/MqttTopics.h index f53ae46..52d2f4d 100644 --- a/src/MqttTopics.h +++ b/src/MqttTopics.h @@ -104,6 +104,7 @@ #define mqtt_topic_restart_reason_esp "/maintenance/restartReasonNukiEsp" #define mqtt_topic_mqtt_connection_state "/maintenance/mqttConnectionState" #define mqtt_topic_network_device "/maintenance/networkDevice" +#define mqtt_hybrid_state "/maintenance/hybridConnected" #define mqtt_topic_presence "/presence/devices" diff --git a/src/NukiNetwork.cpp b/src/NukiNetwork.cpp index 690e422..1e4519b 100644 --- a/src/NukiNetwork.cpp +++ b/src/NukiNetwork.cpp @@ -364,7 +364,7 @@ bool NukiNetwork::update() _firstDisconnected = false; _device->mqttDisconnect(true); } - + if(_restartOnDisconnect && (esp_timer_get_time() / 1000) > 60000) { restartEsp(RestartReason::RestartOnDisconnectWatchdog); @@ -418,11 +418,11 @@ bool NukiNetwork::update() delay(200); restartEsp(RestartReason::NetworkTimeoutWatchdog); } - + delay(2000); return false; } - + _lastConnectedTs = ts; #if PRESENCE_DETECTION_ENABLED @@ -846,7 +846,7 @@ void NukiNetwork::publishLongLong(const char* prefix, const char *topic, int64_t char c; uint8_t base = 10; - while (value) + while (value) { int num = value % base; value /= base; @@ -1015,6 +1015,105 @@ void NukiNetwork::publishHASSConfig(char* deviceType, const char* baseTopic, cha { (char*)"stat_on", (char*)"1" }, { (char*)"stat_off", (char*)"0" }}); + // Network device + publishHassTopic("sensor", + "network_device", + uidString, + "_network_device", + "Network device", + name, + baseTopic, + _lockPath + mqtt_topic_network_device, + deviceType, + "", + "", + "diagnostic", + "", + { { (char*)"en", (char*)"true" }}); + + // Nuki Hub Webserver enabled + publishHassTopic("switch", + "webserver", + uidString, + "_webserver", + "Nuki Hub webserver enabled", + name, + baseTopic, + _lockPath + mqtt_topic_webserver_state, + deviceType, + "", + "", + "diagnostic", + _lockPath + mqtt_topic_webserver_action, + { { (char*)"pl_on", (char*)"1" }, + { (char*)"pl_off", (char*)"0" }, + { (char*)"stat_on", (char*)"1" }, + { (char*)"stat_off", (char*)"0" }}); + + // Uptime + publishHassTopic("sensor", + "uptime", + uidString, + "_uptime", + "Uptime", + name, + baseTopic, + _lockPath + mqtt_topic_uptime, + deviceType, + "", + "", + "diagnostic", + "", + { { (char*)"en", (char*)"true" }}); + + if(_preferences->getBool(preference_mqtt_log_enabled, false)) + { + // MQTT Log + publishHassTopic("sensor", + "mqtt_log", + uidString, + "_mqtt_log", + "MQTT Log", + name, + baseTopic, + _lockPath + mqtt_topic_log, + deviceType, + "", + "", + "diagnostic", + "", + { { (char*)"en", (char*)"true" }}); + } + else + { + removeHassTopic((char*)"sensor", (char*)"mqtt_log", uidString); + } + + if(_preferences->getBool(preference_official_hybrid, false)) + { + // Hybrid connected + publishHassTopic("binary_sensor", + "hybrid_connected", + uidString, + "_hybrid_connected", + "Hybrid connected", + name, + baseTopic, + _lockPath + mqtt_hybrid_state, + deviceType, + "", + "", + "diagnostic", + "", + { {(char*)"pl_on", (char*)"1"}, + {(char*)"pl_off", (char*)"0"}, + { (char*)"en", (char*)"true" }}); + } + else + { + removeHassTopic((char*)"binary_sensor", (char*)"hybrid_connected", uidString); + } + // Firmware version publishHassTopic("sensor", "firmware_version", @@ -3437,6 +3536,11 @@ void NukiNetwork::removeHASSConfig(char* uidString) removeHassTopic((char*)"number", (char*)"unlocked_position_offset_degrees", uidString); removeHassTopic((char*)"switch", (char*)"pairing_enabled", uidString); removeHassTopic((char*)"switch", (char*)"auto_unlatch", uidString); + removeHassTopic((char*)"sensor", (char*)"network_device", uidString); + removeHassTopic((char*)"switch", (char*)"webserver", uidString); + removeHassTopic((char*)"sensor", (char*)"uptime", uidString); + removeHassTopic((char*)"sensor", (char*)"mqtt_log", uidString); + removeHassTopic((char*)"binary_sensor", (char*)"hybrid_connected", uidString); } void NukiNetwork::removeHASSConfigTopic(char *deviceType, char *name, char *uidString) diff --git a/src/NukiWrapper.cpp b/src/NukiWrapper.cpp index 27ad603..e470001 100644 --- a/src/NukiWrapper.cpp +++ b/src/NukiWrapper.cpp @@ -864,6 +864,11 @@ void NukiWrapper::onConfigUpdateReceivedCallback(const char *value) nukiInst->onConfigUpdateReceived(value); } +bool NukiWrapper::offConnected() +{ + return _network->_offConnected; +} + Nuki::AdvertisingMode NukiWrapper::advertisingModeToEnum(const char *str) { if(strcmp(str, "Automatic") == 0) return Nuki::AdvertisingMode::Automatic; @@ -972,6 +977,7 @@ void NukiWrapper::onOfficialUpdateReceived(const char *topic, const char *value) Log->print(F("Connected: ")); Log->println((strcmp(value, "true") == 0 ? 1 : 0)); _network->_offConnected = (strcmp(value, "true") == 0 ? 1 : 0); + _network->publishBool(mqtt_hybrid_state, _network->_offConnected, true); if(!_network->_offConnected) _nextHybridLockStateUpdateTs = (esp_timer_get_time() / 1000) + _intervalHybridLockstate * 1000; else _nextHybridLockStateUpdateTs = 0; diff --git a/src/NukiWrapper.h b/src/NukiWrapper.h index 16bc463..6ebcaf2 100644 --- a/src/NukiWrapper.h +++ b/src/NukiWrapper.h @@ -37,6 +37,7 @@ public: const bool isPaired() const; const bool hasKeypad() const; bool hasDoorSensor() const; + bool offConnected(); const BLEAddress getBleAddress() const; std::string firmwareVersion() const; @@ -126,13 +127,13 @@ private: int _retryConfigCount = 0; int _retryLockstateCount = 0; int _rssiPublishInterval = 0; - int64_t _nextRetryTs = 0; + int64_t _nextRetryTs = 0; int64_t _nextLockStateUpdateTs = 0; int64_t _nextHybridLockStateUpdateTs = 0; int64_t _nextBatteryReportTs = 0; int64_t _nextConfigUpdateTs = 0; int64_t _waitAuthLogUpdateTs = 0; - int64_t _waitKeypadUpdateTs = 0; + int64_t _waitKeypadUpdateTs = 0; int64_t _waitTimeControlUpdateTs = 0; int64_t _nextKeypadUpdateTs = 0; int64_t _nextRssiTs = 0; diff --git a/src/WebCfgServer.cpp b/src/WebCfgServer.cpp index 98b5272..db68321 100644 --- a/src/WebCfgServer.cpp +++ b/src/WebCfgServer.cpp @@ -2000,6 +2000,12 @@ void WebCfgServer::buildHtml(String& response) { String lockState = pinStateToString(_preferences->getInt(preference_lock_pin_status, 4)); printParameter(response, "Nuki Lock PIN status", lockState.c_str(), "", "lockPin"); + + if(_preferences->getBool(preference_official_hybrid, false)) + { + String offConnected = _nuki->offConnected() ? "Yes": "No"; + printParameter(response, "Nuki Lock hybrid mode connected", offConnected.c_str(), "", "lockHybrid"); + } } } if(_nukiOpener != nullptr)