From 960399536d916f68b6ca804580ab8d32f944ef67 Mon Sep 17 00:00:00 2001 From: iranl Date: Wed, 29 May 2024 20:25:00 +0200 Subject: [PATCH] Add battery JSON --- README.md | 2 ++ src/MqttTopics.h | 2 ++ src/Network.cpp | 20 ++++++++----- src/NetworkLock.cpp | 70 ++++++++++++++++++++++++++++++++----------- src/NetworkOpener.cpp | 37 ++++++++++++++++++++--- 5 files changed, 101 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 55361dc..8b2ae84 100644 --- a/README.md +++ b/README.md @@ -264,6 +264,8 @@ In a browser navigate to the IP address assigned to the ESP32. - battery/maxTurnCurrent: The highest current of the turn motor during the last lock action (A) (Lock only). - battery/lockDistance: The total distance during the last lock action in centidegrees (Lock only). - battery/keypadCritical: 1 if the battery level of a connected keypad is critical, otherwise 0. +- battery/basicJson: The current battery state (critical, charging, level and keypad critical) of the Nuki Lock/Opener as JSON data. +- battery/advancedJson: : The current battery state (critical, batteryDrain, batteryVoltage, lockAction, startVoltage, lowestVoltage, lockDistance, startTemperature, maxTurnCurrent and batteryResistance) of the Nuki Lock/Opener as JSON data. ### Keypad diff --git a/src/MqttTopics.h b/src/MqttTopics.h index af639a2..ff2caa3 100644 --- a/src/MqttTopics.h +++ b/src/MqttTopics.h @@ -48,6 +48,8 @@ #define mqtt_topic_battery_max_turn_current "/battery/maxTurnCurrent" #define mqtt_topic_battery_lock_distance "/battery/lockDistance" #define mqtt_topic_battery_keypad_critical "/battery/keypadCritical" +#define mqtt_topic_battery_basic_json "/battery/basicJson" +#define mqtt_topic_battery_advanced_json "/battery/advancedJson" #define mqtt_topic_keypad "/keypad" #define mqtt_topic_keypad_command_action "/keypad/command/action" diff --git a/src/Network.cpp b/src/Network.cpp index 5359cfd..6ae2b05 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -806,14 +806,15 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n "Battery low", name, baseTopic, - String("~") + mqtt_topic_battery_critical, + String("~") + mqtt_topic_battery_basic_json, deviceType, "battery", "", "diagnostic", "", {{(char*)"pl_on", (char*)"1"}, - {(char*)"pl_off", (char*)"0"}}); + {(char*)"pl_off", (char*)"0"}, + {(char*)"val_tpl", (char*)"{{value_json.critical}}" }}); // Battery voltage publishHassTopic("sensor", @@ -823,13 +824,14 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n "Battery voltage", name, baseTopic, - String("~") + mqtt_topic_battery_voltage, + String("~") + mqtt_topic_battery_advanced_json, deviceType, "voltage", "measurement", "diagnostic", "", - { {(char*)"unit_of_meas", (char*)"V"} }); + { {(char*)"unit_of_meas", (char*)"V"}, + {(char*)"val_tpl", (char*)"{{value_json.level}}" }}); // Trigger publishHassTopic("sensor", @@ -1333,13 +1335,14 @@ void Network::publishHASSConfigAdditionalLockEntities(char *deviceType, const ch "Battery level", name, baseTopic, - String("~") + mqtt_topic_battery_level, + String("~") + mqtt_topic_battery_basic_json, deviceType, "battery", "measurement", "diagnostic", "", - { {(char*)"unit_of_meas", (char*)"%"} }); + { {(char*)"unit_of_meas", (char*)"%"}, + {(char*)"val_tpl", (char*)"{{value_json.level}}" }}); if((int)basicLockConfigAclPrefs[7] == 1) { @@ -3032,14 +3035,15 @@ void Network::publishHASSConfigKeypad(char *deviceType, const char *baseTopic, c "Keypad battery low", name, baseTopic, - String("~") + mqtt_topic_battery_keypad_critical, + String("~") + mqtt_topic_battery_basic_json, deviceType, "battery", "", "diagnostic", "", {{(char*)"pl_on", (char*)"1"}, - {(char*)"pl_off", (char*)"0"}}); + {(char*)"pl_off", (char*)"0"}, + {(char*)"val_tpl", (char*)"{{value_json.keypadCritical}}" }}); // Query Keypad publishHassTopic("button", diff --git a/src/NetworkLock.cpp b/src/NetworkLock.cpp index b7ed93b..da3d7a6 100644 --- a/src/NetworkLock.cpp +++ b/src/NetworkLock.cpp @@ -77,6 +77,14 @@ void NetworkLock::initialize() _network->removeTopic(_mqttPath, mqtt_topic_config_auto_unlock); _network->removeTopic(_mqttPath, mqtt_topic_config_auto_lock); _network->removeTopic(_mqttPath, mqtt_topic_config_single_lock); + _network->removeTopic(_mqttPath, mqtt_topic_battery_level); + _network->removeTopic(_mqttPath, mqtt_topic_battery_critical); + _network->removeTopic(_mqttPath, mqtt_topic_battery_charging); + _network->removeTopic(_mqttPath, mqtt_topic_battery_voltage); + _network->removeTopic(_mqttPath, mqtt_topic_battery_drain); + _network->removeTopic(_mqttPath, mqtt_topic_battery_max_turn_current); + _network->removeTopic(_mqttPath, mqtt_topic_battery_lock_distance); + _network->removeTopic(_mqttPath, mqtt_topic_battery_keypad_critical); //_network->removeTopic(_mqttPath, mqtt_topic_presence); } @@ -291,6 +299,7 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne memset(&str, 0, sizeof(str)); JsonDocument json; + JsonDocument jsonBattery; lockstateToString(keyTurnerState.lockState, str); @@ -358,27 +367,26 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne json["door_sensor_state"] = str; - if(_firstTunerStatePublish || keyTurnerState.criticalBatteryState != lastKeyTurnerState.criticalBatteryState) + bool critical = (keyTurnerState.criticalBatteryState & 0b00000001) > 0; + bool charging = (keyTurnerState.criticalBatteryState & 0b00000010) > 0; + uint8_t level = (keyTurnerState.criticalBatteryState & 0b11111100) >> 1; + bool keypadCritical = (keyTurnerState.accessoryBatteryState & (1 << 7)) != 0 ? (keyTurnerState.accessoryBatteryState & (1 << 6)) != 0 : false; + + jsonBattery["critical"] = critical ? "1" : "0"; + jsonBattery["charging"] = charging ? "1" : "0"; + jsonBattery["level"] = level; + jsonBattery["keypadCritical"] = keypadCritical ? "1" : "0"; + + if((_firstTunerStatePublish || keyTurnerState.criticalBatteryState != lastKeyTurnerState.criticalBatteryState) && !_preferences->getBool(preference_disable_non_json, false)) { - bool critical = (keyTurnerState.criticalBatteryState & 0b00000001) > 0; publishBool(mqtt_topic_battery_critical, critical); - - bool charging = (keyTurnerState.criticalBatteryState & 0b00000010) > 0; publishBool(mqtt_topic_battery_charging, charging); - - uint8_t level = (keyTurnerState.criticalBatteryState & 0b11111100) >> 1; publishInt(mqtt_topic_battery_level, level); } - if(_firstTunerStatePublish || keyTurnerState.accessoryBatteryState != lastKeyTurnerState.accessoryBatteryState) + if((_firstTunerStatePublish || keyTurnerState.accessoryBatteryState != lastKeyTurnerState.accessoryBatteryState) && !_preferences->getBool(preference_disable_non_json, false)) { - if((keyTurnerState.accessoryBatteryState & (1 << 7)) != 0) { - publishBool(mqtt_topic_battery_keypad_critical, (keyTurnerState.accessoryBatteryState & (1 << 6)) != 0); - } - else - { - publishBool(mqtt_topic_battery_keypad_critical, false); - } + publishBool(mqtt_topic_battery_keypad_critical, keypadCritical); } json["auth_id"] = _authId; @@ -386,6 +394,9 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne serializeJson(json, _buffer, _bufferSize); publishString(mqtt_topic_lock_json, _buffer); + + serializeJson(jsonBattery, _buffer, _bufferSize); + publishString(mqtt_topic_battery_basic_json, _buffer); _firstTunerStatePublish = false; } @@ -552,10 +563,33 @@ void NetworkLock::publishLockstateCommandResult(const char *resultStr) void NetworkLock::publishBatteryReport(const NukiLock::BatteryReport& batteryReport) { - publishFloat(mqtt_topic_battery_voltage, (float)batteryReport.batteryVoltage / 1000.0); - 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 + if(!_preferences->getBool(preference_disable_non_json, false)) + { + publishFloat(mqtt_topic_battery_voltage, (float)batteryReport.batteryVoltage / 1000.0); + 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 + } + + char str[50]; + memset(&str, 0, sizeof(str)); + + JsonDocument json; + + json["batteryDrain"] = batteryReport.batteryDrain; + json["batteryVoltage"] = (float)batteryReport.batteryVoltage / 1000.0; + json["critical"] = batteryReport.criticalBatteryState; + lockactionToString(batteryReport.lockAction, str); + json["lockAction"] = str; + json["startVoltage"] = (float)batteryReport.startVoltage / 1000.0; + json["lowestVoltage"] = (float)batteryReport.lowestVoltage / 1000.0; + json["lockDistance"] = (float)batteryReport.lockDistance / 1000.0; + json["startTemperature"] = batteryReport.startTemperature; + json["maxTurnCurrent"] = (float)batteryReport.maxTurnCurrent / 1000.0; + json["batteryResistance"] = (float)batteryReport.batteryResistance / 1000.0; + + serializeJson(json, _buffer, _bufferSize); + publishString(mqtt_topic_battery_advanced_json, _buffer); } void NetworkLock::publishConfig(const NukiLock::Config &config) diff --git a/src/NetworkOpener.cpp b/src/NetworkOpener.cpp index 8625127..f06f01d 100644 --- a/src/NetworkOpener.cpp +++ b/src/NetworkOpener.cpp @@ -61,6 +61,11 @@ void NetworkOpener::initialize() _network->removeTopic(_mqttPath, mqtt_topic_config_led_enabled); _network->removeTopic(_mqttPath, mqtt_topic_config_sound_level); _network->removeTopic(_mqttPath, mqtt_topic_keypad_command_result); + _network->removeTopic(_mqttPath, mqtt_topic_battery_level); + _network->removeTopic(_mqttPath, mqtt_topic_battery_critical); + _network->removeTopic(_mqttPath, mqtt_topic_battery_charging); + _network->removeTopic(_mqttPath, mqtt_topic_battery_voltage); + _network->removeTopic(_mqttPath, mqtt_topic_battery_keypad_critical); //_network->removeTopic(_mqttPath, mqtt_topic_presence); } @@ -254,6 +259,7 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn memset(&str, 0, sizeof(str)); JsonDocument json; + JsonDocument jsonBattery; lockstateToString(keyTurnerState.lockState, str); @@ -327,9 +333,11 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn json["door_sensor_state"] = str; - if(_firstTunerStatePublish || keyTurnerState.criticalBatteryState != lastKeyTurnerState.criticalBatteryState) + bool critical = (keyTurnerState.criticalBatteryState & 0b00000001) > 0; + jsonBattery["critical"] = critical ? "1" : "0"; + + if((_firstTunerStatePublish || keyTurnerState.criticalBatteryState != lastKeyTurnerState.criticalBatteryState) && !_preferences->getBool(preference_disable_non_json, false)) { - bool critical = (keyTurnerState.criticalBatteryState & 0b00000001) > 0; publishBool(mqtt_topic_battery_critical, critical); } @@ -339,6 +347,9 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn serializeJson(json, _buffer, _bufferSize); publishString(mqtt_topic_lock_json, _buffer); + serializeJson(jsonBattery, _buffer, _bufferSize); + publishString(mqtt_topic_battery_basic_json, _buffer); + _firstTunerStatePublish = false; } @@ -543,7 +554,25 @@ void NetworkOpener::publishLockstateCommandResult(const char *resultStr) void NetworkOpener::publishBatteryReport(const NukiOpener::BatteryReport& batteryReport) { - publishFloat(mqtt_topic_battery_voltage, (float)batteryReport.batteryVoltage / 1000.0); + if(!_preferences->getBool(preference_disable_non_json, false)) + { + publishFloat(mqtt_topic_battery_voltage, (float)batteryReport.batteryVoltage / 1000.0); + } + + char str[50]; + memset(&str, 0, sizeof(str)); + + JsonDocument json; + + json["batteryVoltage"] = (float)batteryReport.batteryVoltage / 1000.0; + json["critical"] = batteryReport.criticalBatteryState; + lockactionToString(batteryReport.lockAction, str); + json["lockAction"] = str; + json["startVoltage"] = (float)batteryReport.startVoltage / 1000.0; + json["lowestVoltage"] = (float)batteryReport.lowestVoltage / 1000.0; + + serializeJson(json, _buffer, _bufferSize); + publishString(mqtt_topic_battery_advanced_json, _buffer); } void NetworkOpener::publishConfig(const NukiOpener::Config &config) @@ -595,7 +624,7 @@ void NetworkOpener::publishConfig(const NukiOpener::Config &config) serializeJson(json, _buffer, _bufferSize); publishString(mqtt_topic_config_basic_json, _buffer); - + if(!_preferences->getBool(preference_disable_non_json, false)) { publishBool(mqtt_topic_config_button_enabled, config.buttonEnabled == 1);