Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT JSON Lock/Opener and keypad #301

Merged
merged 6 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions MqttTopics.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define mqtt_topic_battery_keypad_critical "/battery/keypadCritical"

#define mqtt_topic_lock_state "/lock/state"
#define mqtt_topic_lock_json "/lock/json"
#define mqtt_topic_query_config "/lock/query/config"
#define mqtt_topic_query_lockstate "/lock/query/lockstate"
#define mqtt_topic_query_keypad "/lock/query/keypad"
Expand Down Expand Up @@ -51,6 +52,7 @@
#define mqtt_topic_keypad_command_code "/keypad/command/code"
#define mqtt_topic_keypad_command_enabled "/keypad/command/enabled"
#define mqtt_topic_keypad_command_result "/keypad/command/commandResult"
#define mqtt_topic_keypad_json "/keypad/json"

#define mqtt_topic_presence "/presence/devices"

Expand Down
52 changes: 26 additions & 26 deletions Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,13 +357,13 @@ bool Network::update()
}
_lastMaintenanceTs = ts;
}

if(_preferences->getBool(preference_check_updates))
{
if(_lastUpdateCheckTs == 0 || (ts - _lastUpdateCheckTs) > 86400000)
{
_lastUpdateCheckTs = ts;

https.useHTTP10(true);
https.begin(GITHUB_LATEST_RELEASE_API_URL);

Expand All @@ -373,16 +373,16 @@ bool Network::update()
DynamicJsonDocument doc(6144);
DeserializationError jsonError = deserializeJson(doc, https.getStream());

if (!jsonError) {
if (!jsonError) {
_latestVersion = doc["tag_name"];
publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion);
}
}
}

https.end();
}
}

for(const auto& gpioTs : _gpioTs)
{
uint8_t pin = gpioTs.first;
Expand Down Expand Up @@ -750,7 +750,7 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n
json["dev"]["mf"] = "Nuki";
json["dev"]["mdl"] = deviceType;
json["dev"]["name"] = name;

String cuUrl = _preferences->getString(preference_mqtt_hass_cu_url);

if (cuUrl != "")
Expand All @@ -761,7 +761,7 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n
{
json["dev"]["cu"] = "http://" + _device->localIP();
}

json["~"] = baseTopic;
json["name"] = nullptr;
json["unique_id"] = String(uidString) + "_lock";
Expand Down Expand Up @@ -945,11 +945,11 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n
"",
{ { "enabled_by_default", "true" },
{"ic", "mdi:counter"}});

if(_preferences->getBool(preference_check_updates))
{
// NUKI Hub latest
publishHassTopic("sensor",
publishHassTopic("sensor",
"nuki_hub_latest",
uidString,
"_nuki_hub_latest",
Expand All @@ -964,13 +964,13 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n
"",
{ { "enabled_by_default", "true" },
{"ic", "mdi:counter"}});

// NUKI Hub update
char latest_version_topic[250];
_lockPath.toCharArray(latest_version_topic,_lockPath.length() + 1);
strcat(latest_version_topic, mqtt_topic_info_nuki_hub_latest);

publishHassTopic("update",
publishHassTopic("update",
"nuki_hub_update",
uidString,
"_nuki_hub_update",
Expand All @@ -986,7 +986,7 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n
{ { "enabled_by_default", "true" },
{ "entity_picture", "https://raw.githubusercontent.com/technyon/nuki_hub/master/icon/favicon-32x32.png" },
{ "release_url", GITHUB_LATEST_RELEASE_URL },
{ "latest_version_topic", latest_version_topic }});
{ "latest_version_topic", latest_version_topic }});
}
else
{
Expand Down Expand Up @@ -1050,7 +1050,7 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n
{ "pl_off", "0" },
{ "state_on", "1" },
{ "state_off", "0" }});

// Unlatch
publishHassTopic("button",
"unlatch",
Expand All @@ -1066,8 +1066,8 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n
"",
String("~") + mqtt_topic_lock_action,
{ { "enabled_by_default", "false" },
{ "pl_prs", "unlatch" }});
{ "pl_prs", "unlatch" }});

}
}

Expand Down Expand Up @@ -1362,7 +1362,7 @@ String Network::createHassTopicPath(const String& mqttDeviceType, const String&
path.concat("/");
path.concat(mqttDeviceName);
path.concat("/config");

return path;
}

Expand All @@ -1387,26 +1387,26 @@ void Network::removeHASSConfig(char* uidString)
removeHassTopic("lock", "smartlock", uidString);
removeHassTopic("binary_sensor", "battery_low", uidString);
removeHassTopic("binary_sensor", "keypad_battery_low", uidString);
removeHassTopic("sensor", "battery_voltage", uidString);
removeHassTopic("sensor", "battery_voltage", uidString);
removeHassTopic("sensor", "trigger", uidString);
removeHassTopic("binary_sensor", "mqtt_connected", uidString);
removeHassTopic("switch", "reset", uidString);
removeHassTopic("switch", "reset", uidString);
removeHassTopic("sensor", "firmware_version", uidString);
removeHassTopic("sensor", "hardware_version", uidString);
removeHassTopic("sensor", "nuki_hub_version", uidString);
removeHassTopic("sensor", "nuki_hub_latest", uidString);
removeHassTopic("update", "nuki_hub_update", uidString);
removeHassTopic("sensor", "nuki_hub_ip", uidString);
removeHassTopic("switch", "led_enabled", uidString);
removeHassTopic("switch", "button_enabled", uidString);
removeHassTopic("switch", "led_enabled", uidString);
removeHassTopic("switch", "button_enabled", uidString);
removeHassTopic("button", "unlatch", uidString);
removeHassTopic("button", "lockngo", uidString);
removeHassTopic("button", "lockngounlatch", uidString);
removeHassTopic("sensor", "battery_level", uidString);
removeHassTopic("binary_sensor", "door_sensor", uidString);
removeHassTopic("binary_sensor", "ring", uidString);
removeHassTopic("number", "led_brightness", uidString);
removeHassTopic("sensor", "sound_level", uidString);
removeHassTopic("sensor", "sound_level", uidString);
removeHassTopic("number", "sound_level", uidString);
removeHassTopic("sensor", "last_action_authorization", uidString);
removeHassTopic("sensor", "keypad_status", uidString);
Expand Down Expand Up @@ -1451,17 +1451,17 @@ DynamicJsonDocument Network::createHassJson(const String& uidString,
{
json["dev_cla"] = deviceClass;
}

if(stateTopic != "")
{
json["stat_t"] = stateTopic;
}

if(stateClass != "")
{
json["stat_cla"] = stateClass;
}

if(entityCat != "")
{
json["ent_cat"] = entityCat;
Expand All @@ -1471,7 +1471,7 @@ DynamicJsonDocument Network::createHassJson(const String& uidString,
{
json["cmd_t"] = commandTopic;
}

json["avty"]["t"] = _lockPath + mqtt_topic_mqtt_connection_state;

for(const auto& entry : additionalEntries)
Expand All @@ -1489,7 +1489,7 @@ DynamicJsonDocument Network::createHassJson(const String& uidString,
json[entry.first] = entry.second;
}
}

return json;
}

Expand Down
68 changes: 55 additions & 13 deletions NetworkLock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,15 @@ void NetworkLock::onMqttDataReceived(const char* topic, byte* payload, const uns
void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurnerState, const NukiLock::KeyTurnerState& lastKeyTurnerState)
{
char str[50];
memset(&str, 0, sizeof(str));

DynamicJsonDocument json(_bufferSize);

lockstateToString(keyTurnerState.lockState, str);

if((_firstTunerStatePublish || keyTurnerState.lockState != lastKeyTurnerState.lockState) && keyTurnerState.lockState != NukiLock::LockState::Undefined)
{
memset(&str, 0, sizeof(str));
lockstateToString(keyTurnerState.lockState, str);

publishString(mqtt_topic_lock_state, str);

if(_haEnabled)
Expand All @@ -222,34 +226,48 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne
}
}

json["lock_state"] = str;

memset(&str, 0, sizeof(str));
triggerToString(keyTurnerState.trigger, str);

if(_firstTunerStatePublish || keyTurnerState.trigger != lastKeyTurnerState.trigger)
{
memset(&str, 0, sizeof(str));
triggerToString(keyTurnerState.trigger, str);
publishString(mqtt_topic_lock_trigger, str);
}

json["trigger"] = str;

memset(&str, 0, sizeof(str));
lockactionToString(keyTurnerState.lastLockAction, str);

if(_firstTunerStatePublish || keyTurnerState.lastLockAction != lastKeyTurnerState.lastLockAction)
{
memset(&str, 0, sizeof(str));
lockactionToString(keyTurnerState.lastLockAction, str);
publishString(mqtt_topic_lock_last_lock_action, str);
}

json["last_lock_action"] = str;

memset(&str, 0, sizeof(str));
NukiLock::completionStatusToString(keyTurnerState.lastLockActionCompletionStatus, str);

if(_firstTunerStatePublish || keyTurnerState.lastLockActionCompletionStatus != lastKeyTurnerState.lastLockActionCompletionStatus)
{
memset(&str, 0, sizeof(str));
NukiLock::completionStatusToString(keyTurnerState.lastLockActionCompletionStatus, str);
publishString(mqtt_topic_lock_completionStatus, str);
}

json["lock_completion_status"] = str;

memset(&str, 0, sizeof(str));
NukiLock::doorSensorStateToString(keyTurnerState.doorSensorState, str);

if(_firstTunerStatePublish || keyTurnerState.doorSensorState != lastKeyTurnerState.doorSensorState)
{
memset(&str, 0, sizeof(str));
NukiLock::doorSensorStateToString(keyTurnerState.doorSensorState, str);
publishString(mqtt_topic_lock_door_sensor_state, str);
}

json["door_sensor_state"] = str;

if(_firstTunerStatePublish || keyTurnerState.criticalBatteryState != lastKeyTurnerState.criticalBatteryState)
{
bool critical = (keyTurnerState.criticalBatteryState & 0b00000001) > 0;
Expand All @@ -273,6 +291,12 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne
}
}

json["auth_id"] = authId;
json["auth_name"] = authName;

serializeJson(json, _buffer, _bufferSize);
publishString(mqtt_topic_lock_json, _buffer);

_firstTunerStatePublish = false;
}

Expand Down Expand Up @@ -301,8 +325,6 @@ void NetworkLock::publishAuthorizationInfo(const std::list<NukiLock::LogEntry>&
char str[50];

bool authFound = false;
uint32_t authId = 0;
char authName[33];
memset(authName, 0, sizeof(authName));

DynamicJsonDocument json(_bufferSize);
Expand Down Expand Up @@ -457,15 +479,35 @@ void NetworkLock::publishBleAddress(const std::string &address)
void NetworkLock::publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount)
{
uint index = 0;

DynamicJsonDocument json(_bufferSize);

for(const auto& entry : entries)
{
String basePath = mqtt_topic_keypad;
basePath.concat("/code_");
basePath.concat(std::to_string(index).c_str());
publishKeypadEntry(basePath, entry);


auto jsonEntry = json.add();

jsonEntry["id"] = entry.codeId;
jsonEntry["enabled"] = entry.enabled;
jsonEntry["name"] = entry.name;
jsonEntry["createdYear"] = entry.dateCreatedYear;
jsonEntry["createdMonth"] = entry.dateCreatedMonth;
jsonEntry["createdDay"] = entry.dateCreatedDay;
jsonEntry["createdHour"] = entry.dateCreatedHour;
jsonEntry["createdMin"] = entry.dateCreatedMin;
jsonEntry["createdSec"] = entry.dateCreatedSec;
jsonEntry["lockCount"] = entry.lockCount;

++index;
}

serializeJson(json, _buffer, _bufferSize);
publishString(mqtt_topic_keypad_json, _buffer);

while(index < maxKeypadCodeCount)
{
NukiLock::KeypadEntry entry;
Expand Down
6 changes: 4 additions & 2 deletions NetworkLock.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,16 @@ class NetworkLock : public MqttReceiver

bool _firstTunerStatePublish = true;
unsigned long _lastMaintenanceTs = 0;
bool _haEnabled= false;
bool _haEnabled = false;
bool _reconnected = false;

String _keypadCommandName = "";
String _keypadCommandCode = "";
uint _keypadCommandId = 0;
int _keypadCommandEnabled = 1;
uint8_t _queryCommands = 0;
uint8_t _queryCommands = 0;
uint32_t authId = 0;
char authName[33];

char* _buffer;
size_t _bufferSize;
Expand Down
Loading
Loading