Merge pull request #296 from iranl/publish-additional-states
Enable Additional Lock states in Home Assistant + Make Opener Continuous mode an option for lock/unlock
This commit is contained in:
26
Gpio.cpp
26
Gpio.cpp
@@ -74,6 +74,14 @@ void Gpio::init()
|
|||||||
pinMode(entry.pin, INPUT_PULLUP);
|
pinMode(entry.pin, INPUT_PULLUP);
|
||||||
attachInterrupt(entry.pin, isrDeactivateRtoCm, FALLING);
|
attachInterrupt(entry.pin, isrDeactivateRtoCm, FALLING);
|
||||||
break;
|
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::OutputHighLocked:
|
||||||
case PinRole::OutputHighUnlocked:
|
case PinRole::OutputHighUnlocked:
|
||||||
case PinRole::OutputHighMotorBlocked:
|
case PinRole::OutputHighMotorBlocked:
|
||||||
@@ -199,6 +207,10 @@ String Gpio::getRoleDescription(PinRole role) const
|
|||||||
return "Input: Activate CM";
|
return "Input: Activate CM";
|
||||||
case PinRole::InputDeactivateRtoCm:
|
case PinRole::InputDeactivateRtoCm:
|
||||||
return "Input: Deactivate RTO/CM";
|
return "Input: Deactivate RTO/CM";
|
||||||
|
case PinRole::InputDeactivateRTO:
|
||||||
|
return "Input: Deactivate RTO";
|
||||||
|
case PinRole::InputDeactivateCM:
|
||||||
|
return "Input: Deactivate CM";
|
||||||
case PinRole::OutputHighLocked:
|
case PinRole::OutputHighLocked:
|
||||||
return "Output: High when locked";
|
return "Output: High when locked";
|
||||||
case PinRole::OutputHighUnlocked:
|
case PinRole::OutputHighUnlocked:
|
||||||
@@ -327,6 +339,20 @@ void Gpio::isrDeactivateRtoCm()
|
|||||||
_debounceTs = millis() + _debounceTime;
|
_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)
|
void Gpio::setPinOutput(const uint8_t& pin, const uint8_t& state)
|
||||||
{
|
{
|
||||||
digitalWrite(pin, state);
|
digitalWrite(pin, state);
|
||||||
|
|||||||
8
Gpio.h
8
Gpio.h
@@ -16,6 +16,8 @@ enum class PinRole
|
|||||||
InputActivateRTO,
|
InputActivateRTO,
|
||||||
InputActivateCM,
|
InputActivateCM,
|
||||||
InputDeactivateRtoCm,
|
InputDeactivateRtoCm,
|
||||||
|
InputDeactivateRTO,
|
||||||
|
InputDeactivateCM,
|
||||||
OutputHighLocked,
|
OutputHighLocked,
|
||||||
OutputHighUnlocked,
|
OutputHighUnlocked,
|
||||||
OutputHighMotorBlocked,
|
OutputHighMotorBlocked,
|
||||||
@@ -38,6 +40,8 @@ enum class GpioAction
|
|||||||
ActivateRTO,
|
ActivateRTO,
|
||||||
ActivateCM,
|
ActivateCM,
|
||||||
DeactivateRtoCm,
|
DeactivateRtoCm,
|
||||||
|
DeactivateRTO,
|
||||||
|
DeactivateCM,
|
||||||
GeneralInput
|
GeneralInput
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -88,6 +92,8 @@ private:
|
|||||||
PinRole::InputActivateRTO,
|
PinRole::InputActivateRTO,
|
||||||
PinRole::InputActivateCM,
|
PinRole::InputActivateCM,
|
||||||
PinRole::InputDeactivateRtoCm,
|
PinRole::InputDeactivateRtoCm,
|
||||||
|
PinRole::InputDeactivateRTO,
|
||||||
|
PinRole::InputDeactivateCM,
|
||||||
PinRole::OutputHighLocked,
|
PinRole::OutputHighLocked,
|
||||||
PinRole::OutputHighUnlocked,
|
PinRole::OutputHighUnlocked,
|
||||||
PinRole::OutputHighRtoActive,
|
PinRole::OutputHighRtoActive,
|
||||||
@@ -110,6 +116,8 @@ private:
|
|||||||
static void IRAM_ATTR isrActivateRTO();
|
static void IRAM_ATTR isrActivateRTO();
|
||||||
static void IRAM_ATTR isrActivateCM();
|
static void IRAM_ATTR isrActivateCM();
|
||||||
static void IRAM_ATTR isrDeactivateRtoCm();
|
static void IRAM_ATTR isrDeactivateRtoCm();
|
||||||
|
static void IRAM_ATTR isrDeactivateRTO();
|
||||||
|
static void IRAM_ATTR isrDeactivateCM();
|
||||||
|
|
||||||
std::vector<std::function<void(const GpioAction&, const int&)>> _callbacks;
|
std::vector<std::function<void(const GpioAction&, const int&)>> _callbacks;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#define mqtt_topic_battery_keypad_critical "/battery/keypadCritical"
|
#define mqtt_topic_battery_keypad_critical "/battery/keypadCritical"
|
||||||
|
|
||||||
#define mqtt_topic_lock_state "/lock/state"
|
#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_lock_json "/lock/json"
|
||||||
#define mqtt_topic_query_config "/lock/query/config"
|
#define mqtt_topic_query_config "/lock/query/config"
|
||||||
#define mqtt_topic_query_lockstate "/lock/query/lockstate"
|
#define mqtt_topic_query_lockstate "/lock/query/lockstate"
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
#define mqtt_topic_query_battery "/lock/query/battery"
|
#define mqtt_topic_query_battery "/lock/query/battery"
|
||||||
#define mqtt_topic_query_lockstate_command_result "/lock/query/lockstateCommandResult"
|
#define mqtt_topic_query_lockstate_command_result "/lock/query/lockstateCommandResult"
|
||||||
#define mqtt_topic_lock_binary_state "/lock/binaryState"
|
#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_trigger "/lock/trigger"
|
||||||
#define mqtt_topic_lock_last_lock_action "/lock/lastLockAction"
|
#define mqtt_topic_lock_last_lock_action "/lock/lastLockAction"
|
||||||
#define mqtt_topic_lock_log "/lock/log"
|
#define mqtt_topic_lock_log "/lock/log"
|
||||||
|
|||||||
64
Network.cpp
64
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;
|
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);
|
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_lock"] = lockAction;
|
||||||
json["pl_unlk"] = unlockAction;
|
json["pl_unlk"] = unlockAction;
|
||||||
json["pl_open"] = openAction;
|
json["pl_open"] = openAction;
|
||||||
json["stat_t"] = String("~") + mqtt_topic_lock_binary_state;
|
json["stat_t"] = String("~") + mqtt_topic_lock_ha_state;
|
||||||
json["stat_locked"] = lockedState;
|
json["stat_jammed"] = "jammed";
|
||||||
json["stat_unlocked"] = unlockedState;
|
json["stat_locked"] = "locked";
|
||||||
|
json["stat_locking"] = "locking";
|
||||||
|
json["stat_unlocked"] = "unlocked";
|
||||||
|
json["stat_unlocking"] = "unlocking";
|
||||||
json["opt"] = "false";
|
json["opt"] = "false";
|
||||||
|
|
||||||
serializeJson(json, _buffer, _bufferSize);
|
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
|
// Lock 'n' Go
|
||||||
publishHassTopic("button",
|
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,
|
void Network::publishHASSConfigDoorSensor(char *deviceType, const char *baseTopic, char *name, char *uidString)
|
||||||
char *lockAction, char *unlockAction, char *openAction, char *lockedState,
|
|
||||||
char *unlockedState)
|
|
||||||
{
|
{
|
||||||
String discoveryTopic = _preferences->getString(preference_mqtt_hass_discovery);
|
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)
|
void Network::publishHASSConfigRingDetect(char *deviceType, const char *baseTopic, char *name, char *uidString)
|
||||||
{
|
{
|
||||||
String discoveryTopic = _preferences->getString(preference_mqtt_hass_discovery);
|
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)
|
void Network::publishHASSConfigLedBrightness(char *deviceType, const char *baseTopic, char *name, char *uidString)
|
||||||
{
|
{
|
||||||
publishHassTopic("number",
|
publishHassTopic("number",
|
||||||
@@ -1412,6 +1456,8 @@ void Network::removeHASSConfig(char* uidString)
|
|||||||
removeHassTopic("sensor", "keypad_status", uidString);
|
removeHassTopic("sensor", "keypad_status", uidString);
|
||||||
removeHassTopic("sensor", "wifi_signal_strength", uidString);
|
removeHassTopic("sensor", "wifi_signal_strength", uidString);
|
||||||
removeHassTopic("sensor", "bluetooth_signal_strength", uidString);
|
removeHassTopic("sensor", "bluetooth_signal_strength", uidString);
|
||||||
|
removeHassTopic("binary_sensor", "continuous_mode", uidString);
|
||||||
|
removeHassTopic("switch", "continuous_mode", uidString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,12 @@ public:
|
|||||||
void publishBool(const char* prefix, const char* topic, const bool value);
|
void publishBool(const char* prefix, const char* topic, const bool value);
|
||||||
bool publishString(const char* prefix, const char* topic, const char* 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 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, 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);
|
||||||
void publishHASSConfigBatLevel(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 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 publishHASSConfigLedBrightness(char* deviceType, const char* baseTopic, char* name, char* uidString);
|
||||||
void publishHASSConfigSoundLevel(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);
|
void publishHASSConfigAccessLog(char* deviceType, const char* baseTopic, char* name, char* uidString);
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne
|
|||||||
|
|
||||||
if(_haEnabled)
|
if(_haEnabled)
|
||||||
{
|
{
|
||||||
publishBinaryState(keyTurnerState.lockState);
|
publishState(keyTurnerState.lockState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,21 +300,35 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne
|
|||||||
_firstTunerStatePublish = false;
|
_firstTunerStatePublish = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkLock::publishBinaryState(NukiLock::LockState lockState)
|
void NetworkLock::publishState(NukiLock::LockState lockState)
|
||||||
{
|
{
|
||||||
switch(lockState)
|
switch(lockState)
|
||||||
{
|
{
|
||||||
case NukiLock::LockState::Locked:
|
case NukiLock::LockState::Locked:
|
||||||
case NukiLock::LockState::Locking:
|
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");
|
publishString(mqtt_topic_lock_binary_state, "locked");
|
||||||
break;
|
break;
|
||||||
case NukiLock::LockState::Unlocked:
|
|
||||||
case NukiLock::LockState::Unlocking:
|
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::Unlatched:
|
||||||
case NukiLock::LockState::Unlatching:
|
case NukiLock::LockState::Unlatching:
|
||||||
case NukiLock::LockState::UnlockedLnga:
|
case NukiLock::LockState::UnlockedLnga:
|
||||||
|
publishString(mqtt_topic_lock_ha_state, "unlocked");
|
||||||
publishString(mqtt_topic_lock_binary_state, "unlocked");
|
publishString(mqtt_topic_lock_binary_state, "unlocked");
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
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,
|
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->publishHASSConfig(deviceType, baseTopic, name, uidString, "~/maintenance/mqttConnectionState", hasKeypad, lockAction, unlockAction, openAction);
|
||||||
_network->publishHASSConfigAdditionalButtons(deviceType, baseTopic, name, uidString, "~/maintenance/mqttConnectionState", hasKeypad, lockAction, unlockAction, openAction, lockedState, unlockedState);
|
_network->publishHASSConfigAdditionalButtons(deviceType, baseTopic, name, uidString);
|
||||||
_network->publishHASSConfigBatLevel(deviceType, baseTopic, name, uidString);
|
_network->publishHASSConfigBatLevel(deviceType, baseTopic, name, uidString);
|
||||||
_network->publishHASSConfigLedBrightness(deviceType, baseTopic, name, uidString);
|
_network->publishHASSConfigLedBrightness(deviceType, baseTopic, name, uidString);
|
||||||
if(hasDoorSensor)
|
if(hasDoorSensor)
|
||||||
{
|
{
|
||||||
_network->publishHASSConfigDoorSensor(deviceType, baseTopic, name, uidString, lockAction, unlockAction, openAction, lockedState, unlockedState);
|
_network->publishHASSConfigDoorSensor(deviceType, baseTopic, name, uidString);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
void publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurnerState, const NukiLock::KeyTurnerState& lastKeyTurnerState);
|
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<NukiLock::LogEntry>& logEntries);
|
void publishAuthorizationInfo(const std::list<NukiLock::LogEntry>& logEntries);
|
||||||
void clearAuthorizationInfo();
|
void clearAuthorizationInfo();
|
||||||
void publishCommandResult(const char* resultStr);
|
void publishCommandResult(const char* resultStr);
|
||||||
@@ -34,7 +34,7 @@ public:
|
|||||||
void publishRssi(const int& rssi);
|
void publishRssi(const int& rssi);
|
||||||
void publishRetry(const std::string& message);
|
void publishRetry(const std::string& message);
|
||||||
void publishBleAddress(const std::string& address);
|
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 removeHASSConfig(char* uidString);
|
||||||
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
|
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
|
||||||
void publishKeypadCommandResult(const char* result);
|
void publishKeypadCommandResult(const char* result);
|
||||||
|
|||||||
@@ -209,19 +209,12 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn
|
|||||||
lockstateToString(keyTurnerState.lockState, str);
|
lockstateToString(keyTurnerState.lockState, str);
|
||||||
|
|
||||||
if((_firstTunerStatePublish || keyTurnerState.lockState != lastKeyTurnerState.lockState || keyTurnerState.nukiState != lastKeyTurnerState.nukiState) && keyTurnerState.lockState != NukiOpener::LockState::Undefined)
|
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)
|
if(_haEnabled)
|
||||||
{
|
{
|
||||||
publishBinaryState(keyTurnerState);
|
publishState(keyTurnerState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,8 +222,10 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn
|
|||||||
|
|
||||||
if(keyTurnerState.nukiState == NukiOpener::State::ContinuousMode)
|
if(keyTurnerState.nukiState == NukiOpener::State::ContinuousMode)
|
||||||
{
|
{
|
||||||
|
publishString(mqtt_topic_lock_continuous_mode, "on");
|
||||||
json["continuous_mode"] = 1;
|
json["continuous_mode"] = 1;
|
||||||
} else {
|
} else {
|
||||||
|
publishString(mqtt_topic_lock_continuous_mode, "off");
|
||||||
json["continuous_mode"] = 0;
|
json["continuous_mode"] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,10 +280,11 @@ void NetworkOpener::publishRing()
|
|||||||
_resetLockStateTs = millis() + 2000;
|
_resetLockStateTs = millis() + 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkOpener::publishBinaryState(NukiOpener::OpenerState lockState)
|
void NetworkOpener::publishState(NukiOpener::OpenerState lockState)
|
||||||
{
|
{
|
||||||
if(lockState.nukiState == NukiOpener::State::ContinuousMode)
|
if(lockState.nukiState == NukiOpener::State::ContinuousMode)
|
||||||
{
|
{
|
||||||
|
publishString(mqtt_topic_lock_ha_state, "unlocked");
|
||||||
publishString(mqtt_topic_lock_binary_state, "unlocked");
|
publishString(mqtt_topic_lock_binary_state, "unlocked");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -296,13 +292,22 @@ void NetworkOpener::publishBinaryState(NukiOpener::OpenerState lockState)
|
|||||||
switch (lockState.lockState)
|
switch (lockState.lockState)
|
||||||
{
|
{
|
||||||
case NukiOpener::LockState::Locked:
|
case NukiOpener::LockState::Locked:
|
||||||
|
publishString(mqtt_topic_lock_ha_state, "locked");
|
||||||
publishString(mqtt_topic_lock_binary_state, "locked");
|
publishString(mqtt_topic_lock_binary_state, "locked");
|
||||||
break;
|
break;
|
||||||
case NukiOpener::LockState::RTOactive:
|
case NukiOpener::LockState::RTOactive:
|
||||||
case NukiOpener::LockState::Open:
|
case NukiOpener::LockState::Open:
|
||||||
case NukiOpener::LockState::Opening:
|
publishString(mqtt_topic_lock_ha_state, "unlocked");
|
||||||
publishString(mqtt_topic_lock_binary_state, "unlocked");
|
publishString(mqtt_topic_lock_binary_state, "unlocked");
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -517,13 +522,14 @@ void NetworkOpener::publishBleAddress(const std::string &address)
|
|||||||
publishString(mqtt_topic_lock_address, 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");
|
String availabilityTopic = _preferences->getString("mqttpath");
|
||||||
availabilityTopic.concat("/maintenance/mqttConnectionState");
|
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->publishHASSConfigRingDetect(deviceType, baseTopic, name, uidString);
|
||||||
|
_network->publishHASSConfigContinuousMode(deviceType, baseTopic, name, uidString);
|
||||||
_network->publishHASSConfigSoundLevel(deviceType, baseTopic, name, uidString);
|
_network->publishHASSConfigSoundLevel(deviceType, baseTopic, name, uidString);
|
||||||
_network->publishHASSBleRssiConfig(deviceType, baseTopic, name, uidString);
|
_network->publishHASSBleRssiConfig(deviceType, baseTopic, name, uidString);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
|
|
||||||
void publishKeyTurnerState(const NukiOpener::OpenerState& keyTurnerState, const NukiOpener::OpenerState& lastKeyTurnerState);
|
void publishKeyTurnerState(const NukiOpener::OpenerState& keyTurnerState, const NukiOpener::OpenerState& lastKeyTurnerState);
|
||||||
void publishRing();
|
void publishRing();
|
||||||
void publishBinaryState(NukiOpener::OpenerState lockState);
|
void publishState(NukiOpener::OpenerState lockState);
|
||||||
void publishAuthorizationInfo(const std::list<NukiOpener::LogEntry>& logEntries);
|
void publishAuthorizationInfo(const std::list<NukiOpener::LogEntry>& logEntries);
|
||||||
void clearAuthorizationInfo();
|
void clearAuthorizationInfo();
|
||||||
void publishCommandResult(const char* resultStr);
|
void publishCommandResult(const char* resultStr);
|
||||||
@@ -31,7 +31,7 @@ public:
|
|||||||
void publishRssi(const int& rssi);
|
void publishRssi(const int& rssi);
|
||||||
void publishRetry(const std::string& message);
|
void publishRetry(const std::string& message);
|
||||||
void publishBleAddress(const std::string& address);
|
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 removeHASSConfig(char* uidString);
|
||||||
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
|
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
|
||||||
void publishKeypadCommandResult(const char* result);
|
void publishKeypadCommandResult(const char* result);
|
||||||
|
|||||||
@@ -291,6 +291,16 @@ void NukiOpenerWrapper::deactivateRtoCm()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NukiOpenerWrapper::deactivateRTO()
|
||||||
|
{
|
||||||
|
_nextLockAction = NukiOpener::LockAction::DeactivateRTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiOpenerWrapper::deactivateCM()
|
||||||
|
{
|
||||||
|
_nextLockAction = NukiOpener::LockAction::DeactivateCM;
|
||||||
|
}
|
||||||
|
|
||||||
bool NukiOpenerWrapper::isPinSet()
|
bool NukiOpenerWrapper::isPinSet()
|
||||||
{
|
{
|
||||||
return _nukiOpener.getSecurityPincode() != 0;
|
return _nukiOpener.getSecurityPincode() != 0;
|
||||||
@@ -347,13 +357,11 @@ void NukiOpenerWrapper::updateKeyTurnerState()
|
|||||||
{
|
{
|
||||||
Log->println(F("Continuous Mode"));
|
Log->println(F("Continuous Mode"));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
char lockStateStr[20];
|
char lockStateStr[20];
|
||||||
lockstateToString(_keyTurnerState.lockState, lockStateStr);
|
lockstateToString(_keyTurnerState.lockState, lockStateStr);
|
||||||
Log->println(lockStateStr);
|
Log->println(lockStateStr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(_publishAuthData)
|
if(_publishAuthData)
|
||||||
{
|
{
|
||||||
@@ -535,6 +543,12 @@ void NukiOpenerWrapper::gpioActionCallback(const GpioAction &action, const int&
|
|||||||
case GpioAction::DeactivateRtoCm:
|
case GpioAction::DeactivateRtoCm:
|
||||||
nukiOpenerInst->deactivateRtoCm();
|
nukiOpenerInst->deactivateRtoCm();
|
||||||
break;
|
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);
|
String baseTopic = _preferences->getString(preference_mqtt_opener_path);
|
||||||
char uidString[20];
|
char uidString[20];
|
||||||
itoa(_nukiConfig.nukiId, uidString, 16);
|
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;
|
_hassSetupCompleted = true;
|
||||||
|
|
||||||
Log->println("HASS setup for opener completed.");
|
Log->println("HASS setup for opener completed.");
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ public:
|
|||||||
void activateRTO();
|
void activateRTO();
|
||||||
void activateCM();
|
void activateCM();
|
||||||
void deactivateRtoCm();
|
void deactivateRtoCm();
|
||||||
|
void deactivateRTO();
|
||||||
|
void deactivateCM();
|
||||||
|
|
||||||
bool isPinSet();
|
bool isPinSet();
|
||||||
void setPin(const uint16_t pin);
|
void setPin(const uint16_t pin);
|
||||||
|
|||||||
@@ -740,7 +740,7 @@ void NukiWrapper::setupHASS()
|
|||||||
char uidString[20];
|
char uidString[20];
|
||||||
itoa(_nukiConfig.nukiId, uidString, 16);
|
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;
|
_hassSetupCompleted = true;
|
||||||
|
|
||||||
Log->println("HASS setup for lock completed.");
|
Log->println("HASS setup for lock completed.");
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#define preference_lock_enabled "lockena"
|
#define preference_lock_enabled "lockena"
|
||||||
#define preference_mqtt_lock_path "mqttpath"
|
#define preference_mqtt_lock_path "mqttpath"
|
||||||
#define preference_opener_enabled "openerena"
|
#define preference_opener_enabled "openerena"
|
||||||
|
#define preference_opener_continuous_mode "openercont"
|
||||||
#define preference_mqtt_opener_path "mqttoppath"
|
#define preference_mqtt_opener_path "mqttoppath"
|
||||||
#define preference_check_updates "checkupdates"
|
#define preference_check_updates "checkupdates"
|
||||||
#define preference_lock_max_keypad_code_count "maxkpad"
|
#define preference_lock_max_keypad_code_count "maxkpad"
|
||||||
@@ -65,7 +66,7 @@ private:
|
|||||||
{
|
{
|
||||||
preference_started_before, preference_config_version, preference_device_id_lock, preference_device_id_opener, preference_mqtt_broker,
|
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_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_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_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,
|
preference_ip_dhcp_enabled, preference_ip_address, preference_ip_subnet, preference_ip_gateway, preference_ip_dns_server,
|
||||||
@@ -87,7 +88,7 @@ private:
|
|||||||
};
|
};
|
||||||
std::vector<char*> _boolPrefs =
|
std::vector<char*> _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_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
|
preference_publish_authdata, preference_has_mac_saved, preference_publish_debug_info, preference_network_wifi_fallback_disabled
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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: 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 RTO: When connect to Ground, Ring-to-open is activated (opener)
|
||||||
- Input: Activate CM: When connect to Ground, Continuous mode 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 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 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)
|
- Output: High when motor blocked: Outputs a high signal when the motor is blocked (lock)
|
||||||
|
|||||||
@@ -352,6 +352,11 @@ bool WebCfgServer::processArgs(String& message)
|
|||||||
configChanged = true;
|
configChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(key == "OPENERCONT")
|
||||||
|
{
|
||||||
|
_preferences->putBool(preference_opener_continuous_mode, (value == "1"));
|
||||||
|
configChanged = true;
|
||||||
|
}
|
||||||
else if(key == "HASSCUURL")
|
else if(key == "HASSCUURL")
|
||||||
{
|
{
|
||||||
_preferences->putString(preference_mqtt_hass_cu_url, value);
|
_preferences->putString(preference_mqtt_hass_cu_url, value);
|
||||||
@@ -798,6 +803,7 @@ void WebCfgServer::buildMqttConfigHtml(String &response)
|
|||||||
response.concat("<table>");
|
response.concat("<table>");
|
||||||
printInputField(response, "HASSDISCOVERY", "Home Assistant discovery topic (empty to disable; usually homeassistant)", _preferences->getString(preference_mqtt_hass_discovery).c_str(), 30);
|
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);
|
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, "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, "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);
|
printTextarea(response, "MQTTKEY", "MQTT SSL Client Key (*, optional)", _preferences->getString(preference_mqtt_key).c_str(), TLS_KEY_MAX_SIZE, _network->encryptionSupported(), true);
|
||||||
|
|||||||
Reference in New Issue
Block a user