From 623eccda1ee51a890be4f0b5828a8a3911b0f809 Mon Sep 17 00:00:00 2001 From: technyon Date: Sat, 2 Apr 2022 19:10:42 +0200 Subject: [PATCH] allow to configure the mqtt path --- MqttTopics.h | 24 +++++++------- Network.cpp | 79 ++++++++++++++++++++++++++++++++++++++++------- Network.h | 4 +++ PreferencesKeys.h | 1 + WebCfgServer.cpp | 13 ++++++++ WebCfgServer.h | 1 + 6 files changed, 98 insertions(+), 24 deletions(-) diff --git a/MqttTopics.h b/MqttTopics.h index 322e77d..7eac839 100644 --- a/MqttTopics.h +++ b/MqttTopics.h @@ -1,15 +1,15 @@ #pragma once -#define mqtt_topic_battery_level "nuki/battery/level" -#define mqtt_topic_battery_critical "nuki/battery/critical" -#define mqtt_topic_battery_charging "nuki/battery/charging" -#define mqtt_topic_battery_voltage "nuki/battery/voltage" -#define mqtt_topic_battery_drain "nuki/battery/drain" -#define mqtt_topic_battery_max_turn_current "nuki/battery/maxTurnCurrent" -#define mqtt_topic_battery_lock_distance "nuki/battery/lockDistance" +#define mqtt_topic_battery_level "/battery/level" +#define mqtt_topic_battery_critical "/battery/critical" +#define mqtt_topic_battery_charging "/battery/charging" +#define mqtt_topic_battery_voltage "/battery/voltage" +#define mqtt_topic_battery_drain "/battery/drain" +#define mqtt_topic_battery_max_turn_current "/battery/maxTurnCurrent" +#define mqtt_topic_battery_lock_distance "/battery/lockDistance" -#define mqtt_topic_lockstate_state "nuki/lock/state" -#define mqtt_topic_lockstate_trigger "nuki/lock/trigger" -#define mqtt_topic_lockstate_completionStatus "nuki/lock/completionStatus" -#define mqtt_topic_lockstate_action "nuki/lock/action" -#define mqtt_topic_door_sensor_state "nuki/lock/doorSensorState" +#define mqtt_topic_lockstate_state "/lock/state" +#define mqtt_topic_lockstate_trigger "/lock/trigger" +#define mqtt_topic_lockstate_completionStatus "/lock/completionStatus" +#define mqtt_topic_door_sensor_state "/lock/doorSensorState" +#define mqtt_topic_lockstate_action "/lock/action" diff --git a/Network.cpp b/Network.cpp index 7c72ceb..3102bdd 100644 --- a/Network.cpp +++ b/Network.cpp @@ -48,6 +48,21 @@ void Network::initialize() _preferences->putInt(preference_mqtt_broker_port, port); } + String mqttPath = _preferences->getString(preference_mqtt_path); + if(mqttPath.length() > 0) + { + size_t len = mqttPath.length(); + for(int i=0; i < len; i++) + { + _mqttPath[i] = mqttPath.charAt(i); + } + } + else + { + strcpy(_mqttPath, "nuki"); + _preferences->putString(preference_mqtt_path, _mqttPath); + } + Serial.print(F("MQTT Broker: ")); Serial.print(_mqttBrokerAddr); Serial.print(F(":")); @@ -67,8 +82,10 @@ bool Network::reconnect() Serial.println(F("MQTT connected")); _mqttConnected = true; + char path[200] = {0}; + buildMqttPath(mqtt_topic_lockstate_action, path); // ... and resubscribe - _mqttClient.subscribe(mqtt_topic_lockstate_action); + _mqttClient.subscribe(path); } else { @@ -120,7 +137,10 @@ void Network::onMqttDataReceived(char *&topic, byte *&payload, unsigned int &len value[l] = 0; - if(strcmp(topic, mqtt_topic_lockstate_action) == 0) + char path[200] = {0}; + buildMqttPath(mqtt_topic_lockstate_action, path); + + if(strcmp(topic, path) == 0) { if(strcmp(value, "") == 0) return; @@ -130,7 +150,7 @@ void Network::onMqttDataReceived(char *&topic, byte *&payload, unsigned int &len { _lockActionReceivedCallback(value); } - _mqttClient.publish(mqtt_topic_lockstate_action, ""); + publishString(mqtt_topic_lockstate_action, ""); } } @@ -142,28 +162,28 @@ void Network::publishKeyTurnerState(const Nuki::KeyTurnerState& keyTurnerState, { memset(&str, 0, sizeof(str)); lockstateToString(keyTurnerState.lockState, str); - _mqttClient.publish(mqtt_topic_lockstate_state, str); + publishString(mqtt_topic_lockstate_state, str); } if(keyTurnerState.trigger != lastKeyTurnerState.trigger) { memset(&str, 0, sizeof(str)); triggerToString(keyTurnerState.trigger, str); - _mqttClient.publish(mqtt_topic_lockstate_trigger, str); + publishString(mqtt_topic_lockstate_trigger, str); } if(keyTurnerState.lastLockActionCompletionStatus != lastKeyTurnerState.lastLockActionCompletionStatus) { memset(&str, 0, sizeof(str)); completionStatusToString(keyTurnerState.lastLockActionCompletionStatus, str); - _mqttClient.publish(mqtt_topic_lockstate_completionStatus, str); + publishString(mqtt_topic_lockstate_completionStatus, str); } if(keyTurnerState.doorSensorState != lastKeyTurnerState.doorSensorState) { memset(&str, 0, sizeof(str)); doorSensorStateToString(keyTurnerState.doorSensorState, str); - _mqttClient.publish(mqtt_topic_door_sensor_state, str); + publishString(mqtt_topic_door_sensor_state, str); } if(keyTurnerState.criticalBatteryState != lastKeyTurnerState.criticalBatteryState) @@ -183,8 +203,6 @@ void Network::publishBatteryReport(const Nuki::BatteryReport& batteryReport) publishInt(mqtt_topic_battery_drain, batteryReport.batteryDrain); // milliwatt seconds publishFloat(mqtt_topic_battery_max_turn_current, (float)batteryReport.maxTurnCurrent / 1000.0); publishInt(mqtt_topic_battery_lock_distance, batteryReport.lockDistance); // degrees - - } void Network::setLockActionReceived(void (*lockActionReceivedCallback)(const char *)) @@ -196,24 +214,61 @@ void Network::publishFloat(const char* topic, const float value, const uint8_t p { char str[30]; dtostrf(value, 0, precision, str); - _mqttClient.publish(topic, str); + char path[200] = {0}; + buildMqttPath(topic, path); + _mqttClient.publish(path, str); } void Network::publishInt(const char *topic, const int value) { + char str[30]; itoa(value, str, 10); - _mqttClient.publish(topic, str); + char path[200] = {0}; + buildMqttPath(topic, path); + _mqttClient.publish(path, str); } void Network::publishBool(const char *topic, const bool value) { char str[2] = {0}; str[0] = value ? '1' : '0'; - _mqttClient.publish(topic, str); + char path[200] = {0}; + buildMqttPath(topic, path); + _mqttClient.publish(path, str); } +void Network::publishString(const char *topic, const char *value) +{ + char path[200] = {0}; + buildMqttPath(topic, path); + _mqttClient.publish(path, value); +} + + bool Network::isMqttConnected() { return _mqttConnected; } + +void Network::buildMqttPath(const char* path, char* outPath) +{ + int offset = 0; + for(const char& c : _mqttPath) + { + if(c == 0x00) + { + break; + } + outPath[offset] = c; + ++offset; + } + int i=0; + while(outPath[i] != 0x00) + { + outPath[offset] = path[i]; + ++i; + ++offset; + } + outPath[i+1] = 0x00; +} diff --git a/Network.h b/Network.h index 97dcf05..89a74e5 100644 --- a/Network.h +++ b/Network.h @@ -28,6 +28,9 @@ private: void publishFloat(const char* topic, const float value, const uint8_t precision = 2); void publishInt(const char* topic, const int value); void publishBool(const char* topic, const bool value); + void publishString(const char* topic, const char* value); + + void buildMqttPath(const char* path, char* outPath); bool reconnect(); @@ -39,6 +42,7 @@ private: unsigned long _nextReconnect = 0; char _mqttBrokerAddr[100] = {0}; + char _mqttPath[100] = {0}; void (*_lockActionReceivedCallback)(const char* value) = NULL; }; diff --git a/PreferencesKeys.h b/PreferencesKeys.h index c9ecf22..f795f7d 100644 --- a/PreferencesKeys.h +++ b/PreferencesKeys.h @@ -3,6 +3,7 @@ #define preference_deviceId "deviceId" #define preference_mqtt_broker "mqttbroker" #define preference_mqtt_broker_port "mqttport" +#define preference_mqtt_path "mqttpath" #define preference_query_interval_lockstate "lockStInterval" #define preference_query_interval_battery "batInterval" diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index 8128e14..8ebe0d8 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -73,6 +73,11 @@ void WebCfgServer::update() _preferences->putInt(preference_mqtt_broker_port, String(token).toInt()); configChanged = true; } + else if(lastTokenType == TokenType::MqttPath && tokenType == TokenType::None) + { + _preferences->putString(preference_mqtt_path, token); + configChanged = true; + } else if(lastTokenType == TokenType::QueryIntervalLockstate && tokenType == TokenType::None) { _preferences->putInt(preference_query_interval_lockstate, String(token).toInt()); @@ -134,6 +139,10 @@ void WebCfgServer::serveHtml(WiFiClient &client) client.print(_preferences->getInt(preference_mqtt_broker_port)); client.println("\" NAME=\"MQTTPORT\" SIZE=\"25\" MAXLENGTH=\"40\">
"); + client.print("MQTT Path: getString(preference_mqtt_path)); + client.println("\" NAME=\"MQTTPATH\" SIZE=\"25\" MAXLENGTH=\"40\">
"); + client.print("Query interval lock state (seconds): getInt(preference_query_interval_lockstate)); client.println("\" NAME=\"LSTINT\" SIZE=\"25\" MAXLENGTH=\"16\">
"); @@ -170,6 +179,10 @@ TokenType WebCfgServer::getParameterType(char *&token) { return TokenType::MqttPort; } + if (strcmp(token, "MQTTPATH") == 0) + { + return TokenType::MqttPath; + } return TokenType::None; } diff --git a/WebCfgServer.h b/WebCfgServer.h index 5c1c341..7e81ef5 100644 --- a/WebCfgServer.h +++ b/WebCfgServer.h @@ -10,6 +10,7 @@ enum class TokenType None, MqttServer, MqttPort, + MqttPath, QueryIntervalLockstate, QueryIntervalBattery, };