diff --git a/Gpio.cpp b/Gpio.cpp index 0ad2c4a0..c3b26017 100644 --- a/Gpio.cpp +++ b/Gpio.cpp @@ -74,6 +74,14 @@ void Gpio::init() pinMode(entry.pin, INPUT_PULLUP); attachInterrupt(entry.pin, isrDeactivateRtoCm, FALLING); break; + case PinRole::InputDeactivateRTO: + pinMode(entry.pin, INPUT_PULLUP); + attachInterrupt(entry.pin, isrDeactivateRTO, FALLING); + break; + case PinRole::InputDeactivateCM: + pinMode(entry.pin, INPUT_PULLUP); + attachInterrupt(entry.pin, isrDeactivateCM, FALLING); + break; case PinRole::OutputHighLocked: case PinRole::OutputHighUnlocked: case PinRole::OutputHighMotorBlocked: @@ -199,6 +207,10 @@ String Gpio::getRoleDescription(PinRole role) const return "Input: Activate CM"; case PinRole::InputDeactivateRtoCm: return "Input: Deactivate RTO/CM"; + case PinRole::InputDeactivateRTO: + return "Input: Deactivate RTO"; + case PinRole::InputDeactivateCM: + return "Input: Deactivate CM"; case PinRole::OutputHighLocked: return "Output: High when locked"; case PinRole::OutputHighUnlocked: @@ -327,6 +339,20 @@ void Gpio::isrDeactivateRtoCm() _debounceTs = millis() + _debounceTime; } +void Gpio::isrDeactivateRTO() +{ + if(millis() < _debounceTs) return; + _inst->notify(GpioAction::DeactivateRTO, -1); + _debounceTs = millis() + _debounceTime; +} + +void Gpio::isrDeactivateCM() +{ + if(millis() < _debounceTs) return; + _inst->notify(GpioAction::DeactivateCM, -1); + _debounceTs = millis() + _debounceTime; +} + void Gpio::setPinOutput(const uint8_t& pin, const uint8_t& state) { digitalWrite(pin, state); diff --git a/Gpio.h b/Gpio.h index 1203c660..a7823dab 100644 --- a/Gpio.h +++ b/Gpio.h @@ -16,6 +16,8 @@ enum class PinRole InputActivateRTO, InputActivateCM, InputDeactivateRtoCm, + InputDeactivateRTO, + InputDeactivateCM, OutputHighLocked, OutputHighUnlocked, OutputHighMotorBlocked, @@ -38,6 +40,8 @@ enum class GpioAction ActivateRTO, ActivateCM, DeactivateRtoCm, + DeactivateRTO, + DeactivateCM, GeneralInput }; @@ -88,6 +92,8 @@ class Gpio PinRole::InputActivateRTO, PinRole::InputActivateCM, PinRole::InputDeactivateRtoCm, + PinRole::InputDeactivateRTO, + PinRole::InputDeactivateCM, PinRole::OutputHighLocked, PinRole::OutputHighUnlocked, PinRole::OutputHighRtoActive, @@ -110,6 +116,8 @@ class Gpio static void IRAM_ATTR isrActivateRTO(); static void IRAM_ATTR isrActivateCM(); static void IRAM_ATTR isrDeactivateRtoCm(); + static void IRAM_ATTR isrDeactivateRTO(); + static void IRAM_ATTR isrDeactivateCM(); std::vector> _callbacks; diff --git a/MqttTopics.h b/MqttTopics.h index 2ae01871..eb707a10 100644 --- a/MqttTopics.h +++ b/MqttTopics.h @@ -10,6 +10,7 @@ #define mqtt_topic_battery_keypad_critical "/battery/keypadCritical" #define mqtt_topic_lock_state "/lock/state" +#define mqtt_topic_lock_ha_state "/lock/hastate" #define mqtt_topic_lock_json "/lock/json" #define mqtt_topic_query_config "/lock/query/config" #define mqtt_topic_query_lockstate "/lock/query/lockstate" @@ -17,6 +18,7 @@ #define mqtt_topic_query_battery "/lock/query/battery" #define mqtt_topic_query_lockstate_command_result "/lock/query/lockstateCommandResult" #define mqtt_topic_lock_binary_state "/lock/binaryState" +#define mqtt_topic_lock_continuous_mode "/lock/continuousMode" #define mqtt_topic_lock_trigger "/lock/trigger" #define mqtt_topic_lock_last_lock_action "/lock/lastLockAction" #define mqtt_topic_lock_log "/lock/log" diff --git a/Network.cpp b/Network.cpp index 428c05a1..e002e335 100644 --- a/Network.cpp +++ b/Network.cpp @@ -736,7 +736,7 @@ bool Network::publishString(const char* prefix, const char *topic, const char *v return _device->mqttPublish(path, MQTT_QOS_LEVEL, true, value) > 0; } -void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const char* availabilityTopic, const bool& hasKeypad, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState) +void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const char* availabilityTopic, const bool& hasKeypad, char* lockAction, char* unlockAction, char* openAction) { String discoveryTopic = _preferences->getString(preference_mqtt_hass_discovery); @@ -770,9 +770,12 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n json["pl_lock"] = lockAction; json["pl_unlk"] = unlockAction; json["pl_open"] = openAction; - json["stat_t"] = String("~") + mqtt_topic_lock_binary_state; - json["stat_locked"] = lockedState; - json["stat_unlocked"] = unlockedState; + json["stat_t"] = String("~") + mqtt_topic_lock_ha_state; + json["stat_jammed"] = "jammed"; + json["stat_locked"] = "locked"; + json["stat_locking"] = "locking"; + json["stat_unlocked"] = "unlocked"; + json["stat_unlocking"] = "unlocking"; json["opt"] = "false"; serializeJson(json, _buffer, _bufferSize); @@ -1072,7 +1075,7 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n } -void Network::publishHASSConfigAdditionalButtons(char *deviceType, const char *baseTopic, char *name, char *uidString, const char *availabilityTopic, const bool &hasKeypad, char *lockAction, char *unlockAction, char *openAction, char *lockedState, char *unlockedState) +void Network::publishHASSConfigAdditionalButtons(char *deviceType, const char *baseTopic, char *name, char *uidString) { // Lock 'n' Go publishHassTopic("button", @@ -1132,9 +1135,7 @@ void Network::publishHASSConfigBatLevel(char *deviceType, const char *baseTopic, } } -void Network::publishHASSConfigDoorSensor(char *deviceType, const char *baseTopic, char *name, char *uidString, - char *lockAction, char *unlockAction, char *openAction, char *lockedState, - char *unlockedState) +void Network::publishHASSConfigDoorSensor(char *deviceType, const char *baseTopic, char *name, char *uidString) { String discoveryTopic = _preferences->getString(preference_mqtt_hass_discovery); @@ -1159,6 +1160,50 @@ void Network::publishHASSConfigDoorSensor(char *deviceType, const char *baseTopi } } +void Network::publishHASSConfigContinuousMode(char *deviceType, const char *baseTopic, char *name, char *uidString) +{ + String discoveryTopic = _preferences->getString(preference_mqtt_hass_discovery); + + if (discoveryTopic != "") + { + + publishHassTopic("binary_sensor", + "continuous_mode", + uidString, + "_continuous_mode", + "Continuous mode", + name, + baseTopic, + String("~") + mqtt_topic_lock_continuous_mode, + deviceType, + "lock", + "", + "", + "", + {{"pl_on", "on"}, + {"pl_off", "off"}}); + + publishHassTopic("switch", + "continuous_mode", + uidString, + "_continuous_mode", + "Continuous mode", + name, + baseTopic, + String("~") + mqtt_topic_lock_continuous_mode, + deviceType, + "lock", + "", + "", + String("~") + mqtt_topic_lock_action, + {{ "enabled_by_default", "false" }, + {"state_on", "on"}, + {"state_on", "off"}, + {"pl_on", "activateCM"}, + {"pl_off", "deactivateCM"}}); + } +} + void Network::publishHASSConfigRingDetect(char *deviceType, const char *baseTopic, char *name, char *uidString) { String discoveryTopic = _preferences->getString(preference_mqtt_hass_discovery); @@ -1190,7 +1235,6 @@ void Network::publishHASSConfigRingDetect(char *deviceType, const char *baseTopi } } - void Network::publishHASSConfigLedBrightness(char *deviceType, const char *baseTopic, char *name, char *uidString) { publishHassTopic("number", @@ -1412,6 +1456,8 @@ void Network::removeHASSConfig(char* uidString) removeHassTopic("sensor", "keypad_status", uidString); removeHassTopic("sensor", "wifi_signal_strength", uidString); removeHassTopic("sensor", "bluetooth_signal_strength", uidString); + removeHassTopic("binary_sensor", "continuous_mode", uidString); + removeHassTopic("switch", "continuous_mode", uidString); } } diff --git a/Network.h b/Network.h index 38a3ab4f..21c41331 100644 --- a/Network.h +++ b/Network.h @@ -45,11 +45,12 @@ class Network void publishBool(const char* prefix, const char* topic, const bool value); bool publishString(const char* prefix, const char* topic, const char* value); - void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const char* availabilityTopic, const bool& hasKeypad, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState); - void publishHASSConfigAdditionalButtons(char* deviceType, const char* baseTopic, char* name, char* uidString, const char* availabilityTopic, const bool& hasKeypad, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState); + void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const char* availabilityTopic, const bool& hasKeypad, char* lockAction, char* unlockAction, char* openAction); + void publishHASSConfigAdditionalButtons(char* deviceType, const char* baseTopic, char* name, char* uidString); void publishHASSConfigBatLevel(char* deviceType, const char* baseTopic, char* name, char* uidString); - void publishHASSConfigDoorSensor(char* deviceType, const char* baseTopic, char* name, char* uidString, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState); + void publishHASSConfigDoorSensor(char* deviceType, const char* baseTopic, char* name, char* uidString); void publishHASSConfigRingDetect(char* deviceType, const char* baseTopic, char* name, char* uidString); + void publishHASSConfigContinuousMode(char* deviceType, const char* baseTopic, char* name, char* uidString); void publishHASSConfigLedBrightness(char* deviceType, const char* baseTopic, char* name, char* uidString); void publishHASSConfigSoundLevel(char* deviceType, const char* baseTopic, char* name, char* uidString); void publishHASSConfigAccessLog(char* deviceType, const char* baseTopic, char* name, char* uidString); diff --git a/NetworkLock.cpp b/NetworkLock.cpp index 01c877b7..f6faf691 100644 --- a/NetworkLock.cpp +++ b/NetworkLock.cpp @@ -222,7 +222,7 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne if(_haEnabled) { - publishBinaryState(keyTurnerState.lockState); + publishState(keyTurnerState.lockState); } } @@ -300,21 +300,35 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne _firstTunerStatePublish = false; } -void NetworkLock::publishBinaryState(NukiLock::LockState lockState) +void NetworkLock::publishState(NukiLock::LockState lockState) { switch(lockState) { case NukiLock::LockState::Locked: + publishString(mqtt_topic_lock_ha_state, "locked"); + publishString(mqtt_topic_lock_binary_state, "locked"); + break; case NukiLock::LockState::Locking: + publishString(mqtt_topic_lock_ha_state, "locking"); publishString(mqtt_topic_lock_binary_state, "locked"); break; - case NukiLock::LockState::Unlocked: case NukiLock::LockState::Unlocking: + publishString(mqtt_topic_lock_ha_state, "unlocking"); + publishString(mqtt_topic_lock_binary_state, "unlocked"); + break; + case NukiLock::LockState::Unlocked: case NukiLock::LockState::Unlatched: case NukiLock::LockState::Unlatching: case NukiLock::LockState::UnlockedLnga: + publishString(mqtt_topic_lock_ha_state, "unlocked"); publishString(mqtt_topic_lock_binary_state, "unlocked"); break; + case NukiLock::LockState::Uncalibrated: + case NukiLock::LockState::Calibration: + case NukiLock::LockState::BootRun: + case NukiLock::LockState::MotorBlocked: + publishString(mqtt_topic_lock_ha_state, "jammed"); + break; default: break; } @@ -571,15 +585,15 @@ bool NetworkLock::comparePrefixedPath(const char *fullPath, const char *subPath) } void NetworkLock::publishHASSConfig(char *deviceType, const char *baseTopic, char *name, char *uidString, const bool& hasDoorSensor, const bool& hasKeypad, const bool& publishAuthData, char *lockAction, - char *unlockAction, char *openAction, char *lockedState, char *unlockedState) + char *unlockAction, char *openAction) { - _network->publishHASSConfig(deviceType, baseTopic, name, uidString, "~/maintenance/mqttConnectionState", hasKeypad, lockAction, unlockAction, openAction, lockedState, unlockedState); - _network->publishHASSConfigAdditionalButtons(deviceType, baseTopic, name, uidString, "~/maintenance/mqttConnectionState", hasKeypad, lockAction, unlockAction, openAction, lockedState, unlockedState); + _network->publishHASSConfig(deviceType, baseTopic, name, uidString, "~/maintenance/mqttConnectionState", hasKeypad, lockAction, unlockAction, openAction); + _network->publishHASSConfigAdditionalButtons(deviceType, baseTopic, name, uidString); _network->publishHASSConfigBatLevel(deviceType, baseTopic, name, uidString); _network->publishHASSConfigLedBrightness(deviceType, baseTopic, name, uidString); if(hasDoorSensor) { - _network->publishHASSConfigDoorSensor(deviceType, baseTopic, name, uidString, lockAction, unlockAction, openAction, lockedState, unlockedState); + _network->publishHASSConfigDoorSensor(deviceType, baseTopic, name, uidString); } else { diff --git a/NetworkLock.h b/NetworkLock.h index 866a18a6..977aaba1 100644 --- a/NetworkLock.h +++ b/NetworkLock.h @@ -23,7 +23,7 @@ class NetworkLock : public MqttReceiver void initialize(); void publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurnerState, const NukiLock::KeyTurnerState& lastKeyTurnerState); - void publishBinaryState(NukiLock::LockState lockState); + void publishState(NukiLock::LockState lockState); void publishAuthorizationInfo(const std::list& logEntries); void clearAuthorizationInfo(); void publishCommandResult(const char* resultStr); @@ -34,7 +34,7 @@ class NetworkLock : public MqttReceiver void publishRssi(const int& rssi); void publishRetry(const std::string& message); void publishBleAddress(const std::string& address); - void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const bool& hasDoorSensor, const bool& hasKeypad, const bool& publishAuthData, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState); + void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const bool& hasDoorSensor, const bool& hasKeypad, const bool& publishAuthData, char* lockAction, char* unlockAction, char* openAction); void removeHASSConfig(char* uidString); void publishKeypad(const std::list& entries, uint maxKeypadCodeCount); void publishKeypadCommandResult(const char* result); diff --git a/NetworkOpener.cpp b/NetworkOpener.cpp index e24751a7..7d2bdc0a 100644 --- a/NetworkOpener.cpp +++ b/NetworkOpener.cpp @@ -210,18 +210,11 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn if((_firstTunerStatePublish || keyTurnerState.lockState != lastKeyTurnerState.lockState || keyTurnerState.nukiState != lastKeyTurnerState.nukiState) && keyTurnerState.lockState != NukiOpener::LockState::Undefined) { - if(keyTurnerState.nukiState == NukiOpener::State::ContinuousMode) - { - publishString(mqtt_topic_lock_state, "ContinuousMode"); - } - else - { - publishString(mqtt_topic_lock_state, str); - } + publishString(mqtt_topic_lock_state, str); if(_haEnabled) { - publishBinaryState(keyTurnerState); + publishState(keyTurnerState); } } @@ -229,8 +222,10 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn if(keyTurnerState.nukiState == NukiOpener::State::ContinuousMode) { + publishString(mqtt_topic_lock_continuous_mode, "on"); json["continuous_mode"] = 1; } else { + publishString(mqtt_topic_lock_continuous_mode, "off"); json["continuous_mode"] = 0; } @@ -285,10 +280,11 @@ void NetworkOpener::publishRing() _resetLockStateTs = millis() + 2000; } -void NetworkOpener::publishBinaryState(NukiOpener::OpenerState lockState) +void NetworkOpener::publishState(NukiOpener::OpenerState lockState) { if(lockState.nukiState == NukiOpener::State::ContinuousMode) { + publishString(mqtt_topic_lock_ha_state, "unlocked"); publishString(mqtt_topic_lock_binary_state, "unlocked"); } else @@ -296,13 +292,22 @@ void NetworkOpener::publishBinaryState(NukiOpener::OpenerState lockState) switch (lockState.lockState) { case NukiOpener::LockState::Locked: + publishString(mqtt_topic_lock_ha_state, "locked"); publishString(mqtt_topic_lock_binary_state, "locked"); break; case NukiOpener::LockState::RTOactive: case NukiOpener::LockState::Open: + publishString(mqtt_topic_lock_ha_state, "unlocked"); + publishString(mqtt_topic_lock_binary_state, "unlocked"); + break; case NukiOpener::LockState::Opening: + publishString(mqtt_topic_lock_ha_state, "unlocking"); publishString(mqtt_topic_lock_binary_state, "unlocked"); break; + case NukiOpener::LockState::Undefined: + case NukiOpener::LockState::Uncalibrated: + publishString(mqtt_topic_lock_ha_state, "jammed"); + break; default: break; } @@ -517,13 +522,14 @@ void NetworkOpener::publishBleAddress(const std::string &address) publishString(mqtt_topic_lock_address, address); } -void NetworkOpener::publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState) +void NetworkOpener::publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, char* lockAction, char* unlockAction, char* openAction) { String availabilityTopic = _preferences->getString("mqttpath"); availabilityTopic.concat("/maintenance/mqttConnectionState"); - _network->publishHASSConfig(deviceType, baseTopic, name, uidString, availabilityTopic.c_str(), false, lockAction, unlockAction, openAction, lockedState, unlockedState); + _network->publishHASSConfig(deviceType, baseTopic, name, uidString, availabilityTopic.c_str(), false, lockAction, unlockAction, openAction); _network->publishHASSConfigRingDetect(deviceType, baseTopic, name, uidString); + _network->publishHASSConfigContinuousMode(deviceType, baseTopic, name, uidString); _network->publishHASSConfigSoundLevel(deviceType, baseTopic, name, uidString); _network->publishHASSBleRssiConfig(deviceType, baseTopic, name, uidString); } @@ -545,7 +551,7 @@ void NetworkOpener::publishKeypad(const std::list& entrie basePath.concat("/code_"); basePath.concat(std::to_string(index).c_str()); publishKeypadEntry(basePath, entry); - + auto jsonEntry = json.add(); jsonEntry["id"] = entry.codeId; diff --git a/NetworkOpener.h b/NetworkOpener.h index 166ed73e..212bd09a 100644 --- a/NetworkOpener.h +++ b/NetworkOpener.h @@ -20,7 +20,7 @@ class NetworkOpener : public MqttReceiver void publishKeyTurnerState(const NukiOpener::OpenerState& keyTurnerState, const NukiOpener::OpenerState& lastKeyTurnerState); void publishRing(); - void publishBinaryState(NukiOpener::OpenerState lockState); + void publishState(NukiOpener::OpenerState lockState); void publishAuthorizationInfo(const std::list& logEntries); void clearAuthorizationInfo(); void publishCommandResult(const char* resultStr); @@ -31,7 +31,7 @@ class NetworkOpener : public MqttReceiver void publishRssi(const int& rssi); void publishRetry(const std::string& message); void publishBleAddress(const std::string& address); - void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState); + void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, char* lockAction, char* unlockAction, char* openAction); void removeHASSConfig(char* uidString); void publishKeypad(const std::list& entries, uint maxKeypadCodeCount); void publishKeypadCommandResult(const char* result); diff --git a/NukiOpenerWrapper.cpp b/NukiOpenerWrapper.cpp index 9cf86073..fab2f545 100644 --- a/NukiOpenerWrapper.cpp +++ b/NukiOpenerWrapper.cpp @@ -291,6 +291,16 @@ void NukiOpenerWrapper::deactivateRtoCm() } } +void NukiOpenerWrapper::deactivateRTO() +{ + _nextLockAction = NukiOpener::LockAction::DeactivateRTO; +} + +void NukiOpenerWrapper::deactivateCM() +{ + _nextLockAction = NukiOpener::LockAction::DeactivateCM; +} + bool NukiOpenerWrapper::isPinSet() { return _nukiOpener.getSecurityPincode() != 0; @@ -347,12 +357,10 @@ void NukiOpenerWrapper::updateKeyTurnerState() { Log->println(F("Continuous Mode")); } - else - { - char lockStateStr[20]; - lockstateToString(_keyTurnerState.lockState, lockStateStr); - Log->println(lockStateStr); - } + + char lockStateStr[20]; + lockstateToString(_keyTurnerState.lockState, lockStateStr); + Log->println(lockStateStr); } if(_publishAuthData) @@ -535,6 +543,12 @@ void NukiOpenerWrapper::gpioActionCallback(const GpioAction &action, const int& case GpioAction::DeactivateRtoCm: nukiOpenerInst->deactivateRtoCm(); break; + case GpioAction::DeactivateRTO: + nukiOpenerInst->deactivateRTO(); + break; + case GpioAction::DeactivateCM: + nukiOpenerInst->deactivateCM(); + break; } } @@ -740,7 +754,16 @@ void NukiOpenerWrapper::setupHASS() String baseTopic = _preferences->getString(preference_mqtt_opener_path); char uidString[20]; itoa(_nukiConfig.nukiId, uidString, 16); - _network->publishHASSConfig("Opener",baseTopic.c_str(),(char*)_nukiConfig.name,uidString, "deactivateRTO","activateRTO","electricStrikeActuation","locked","unlocked"); + + if (_preferences->getBool(preference_opener_continuous_mode)) + { + _network->publishHASSConfig("Opener",baseTopic.c_str(),(char*)_nukiConfig.name,uidString, "deactivateCM","activateCM","electricStrikeActuation"); + } + else + { + _network->publishHASSConfig("Opener",baseTopic.c_str(),(char*)_nukiConfig.name,uidString, "deactivateRTO","activateRTO","electricStrikeActuation"); + } + _hassSetupCompleted = true; Log->println("HASS setup for opener completed."); diff --git a/NukiOpenerWrapper.h b/NukiOpenerWrapper.h index b6169774..619ce04b 100644 --- a/NukiOpenerWrapper.h +++ b/NukiOpenerWrapper.h @@ -22,12 +22,14 @@ class NukiOpenerWrapper : public NukiOpener::SmartlockEventHandler void activateRTO(); void activateCM(); void deactivateRtoCm(); + void deactivateRTO(); + void deactivateCM(); bool isPinSet(); void setPin(const uint16_t pin); void unpair(); - + void disableHASS(); void disableWatchdog(); @@ -63,7 +65,7 @@ class NukiOpenerWrapper : public NukiOpener::SmartlockEventHandler void readConfig(); void readAdvancedConfig(); - + void setupHASS(); void printCommandResult(Nuki::CmdResult result); diff --git a/NukiWrapper.cpp b/NukiWrapper.cpp index 56764cea..3726382d 100644 --- a/NukiWrapper.cpp +++ b/NukiWrapper.cpp @@ -740,7 +740,7 @@ void NukiWrapper::setupHASS() char uidString[20]; itoa(_nukiConfig.nukiId, uidString, 16); - _network->publishHASSConfig("SmartLock", baseTopic.c_str(),(char*)_nukiConfig.name, uidString, hasDoorSensor(), _hasKeypad, _publishAuthData,"lock", "unlock", "unlatch", "locked", "unlocked"); + _network->publishHASSConfig("SmartLock", baseTopic.c_str(),(char*)_nukiConfig.name, uidString, hasDoorSensor(), _hasKeypad, _publishAuthData,"lock", "unlock", "unlatch"); _hassSetupCompleted = true; Log->println("HASS setup for lock completed."); diff --git a/PreferencesKeys.h b/PreferencesKeys.h index a7638aa0..b8356d5f 100644 --- a/PreferencesKeys.h +++ b/PreferencesKeys.h @@ -14,6 +14,7 @@ #define preference_lock_enabled "lockena" #define preference_mqtt_lock_path "mqttpath" #define preference_opener_enabled "openerena" +#define preference_opener_continuous_mode "openercont" #define preference_mqtt_opener_path "mqttoppath" #define preference_check_updates "checkupdates" #define preference_lock_max_keypad_code_count "maxkpad" @@ -65,7 +66,7 @@ class DebugPreferences { preference_started_before, preference_config_version, 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_check_updates, preference_lock_enabled, - preference_mqtt_lock_path, preference_opener_enabled, preference_mqtt_opener_path, + preference_mqtt_lock_path, preference_opener_enabled, preference_opener_continuous_mode, 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, preference_ip_dhcp_enabled, preference_ip_address, preference_ip_subnet, preference_ip_gateway, preference_ip_dns_server, @@ -87,7 +88,7 @@ class DebugPreferences }; std::vector _boolPrefs = { - preference_started_before, preference_mqtt_log_enabled, preference_check_updates, preference_lock_enabled, preference_opener_enabled, + preference_started_before, preference_mqtt_log_enabled, preference_check_updates, preference_lock_enabled, preference_opener_enabled, preference_opener_continuous_mode, 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/README.md b/README.md index 22aecdb8..b9386726 100644 --- a/README.md +++ b/README.md @@ -199,7 +199,9 @@ can be configured for a specific role: - Input: Electric strike actuation: When connect to Ground, an electric strike actuation command is sent to the opener (open door for configured amount of time) - Input: Activate RTO: When connect to Ground, Ring-to-open is activated (opener) - Input: Activate CM: When connect to Ground, Continuous mode is activated (opener) -- Input: Deactivate RTO/CM: Disable RTO or CM, depending on which is active +- Input: Deactivate RTO/CM: Disable RTO or CM, depending on which is active (opener) +- Input: Dectivate RTO: When connect to Ground, Ring-to-open is deactivated (opener) +- Input: Dectivate CM: When connect to Ground, Continuous mode is deactivated (opener) - Output: High when locked: Outputs a high signal when the door is locked - Output: High when unlocked: Outputs a high signal when the door is unlocked - Output: High when motor blocked: Outputs a high signal when the motor is blocked (lock) diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index 413e6a42..b509ab39 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -352,6 +352,11 @@ bool WebCfgServer::processArgs(String& message) configChanged = true; } } + else if(key == "OPENERCONT") + { + _preferences->putBool(preference_opener_continuous_mode, (value == "1")); + configChanged = true; + } else if(key == "HASSCUURL") { _preferences->putString(preference_mqtt_hass_cu_url, value); @@ -798,6 +803,7 @@ void WebCfgServer::buildMqttConfigHtml(String &response) response.concat(""); printInputField(response, "HASSDISCOVERY", "Home Assistant discovery topic (empty to disable; usually homeassistant)", _preferences->getString(preference_mqtt_hass_discovery).c_str(), 30); printInputField(response, "HASSCUURL", "Home Assistant device configuration URL (empty to use http://LOCALIP; fill when using a reverse proxy for example)", _preferences->getString(preference_mqtt_hass_cu_url).c_str(), 261); + if(_nukiOpener != nullptr) printCheckBox(response, "OPENERCONT", "Set Nuki Opener Lock/Unlock action in Home Assistant to Continuous mode", _preferences->getBool(preference_opener_continuous_mode)); printTextarea(response, "MQTTCA", "MQTT SSL CA Certificate (*, optional)", _preferences->getString(preference_mqtt_ca).c_str(), TLS_CA_MAX_SIZE, _network->encryptionSupported(), true); printTextarea(response, "MQTTCRT", "MQTT SSL Client Certificate (*, optional)", _preferences->getString(preference_mqtt_crt).c_str(), TLS_CERT_MAX_SIZE, _network->encryptionSupported(), true); printTextarea(response, "MQTTKEY", "MQTT SSL Client Key (*, optional)", _preferences->getString(preference_mqtt_key).c_str(), TLS_KEY_MAX_SIZE, _network->encryptionSupported(), true);