Move MQTT discovery information into devices.json.

We inject some "magic" overrides when `devices.json` is created, rather
than at runtime; this means that users can update the discovery
information directly in their `devices.json` configuration rather than
in the code. This way, they can change existing or add new discovery
information without needing a code change.
This commit is contained in:
James Muscat
2024-08-11 14:48:56 +01:00
parent d9196ad5bf
commit 5a2611967b
2 changed files with 25 additions and 11 deletions

View File

@@ -12,8 +12,14 @@ def decamelcase(str):
HA_DISCOVERY_PREFIX = "homeassistant"
# These "magic overrides" provide HA MQTT autodiscovery data that is injected
# into devices.json when `hc-login.py` is run; the data is then read from
# devices.json at runtime.
#
# Note: keys should be integer (not string) taken from a device's feature
# mapping.
MAGIC_OVERRIDES = {
"BackendConnected": {
5: { # BSH.Common.Status.BackendConnected
"component_type": "binary_sensor",
"payload_values": {
"device_class": "connectivity",
@@ -21,14 +27,14 @@ MAGIC_OVERRIDES = {
"payload_off": False
}
},
"SoftwareUpdateAvailable": {
21: { # BSH.Common.Event.SoftwareUpdateAvailable
"component_type": "binary_sensor",
"payload_values": {
"device_class": "update",
"payload_on": "Present"
}
},
"DoorState": {
527: { # BSH.Common.Status.DoorState
"component_type": "binary_sensor",
"payload_values": {
"device_class": "door",
@@ -36,41 +42,41 @@ MAGIC_OVERRIDES = {
"payload_off": "Closed"
}
},
"PowerState": {
539: { # BSH.Common.Setting.PowerState
"component_type": "binary_sensor",
"payload_values": {
"device_class": "power"
}
},
"RinseAidLack": {
4612: { # Dishcare.Dishwasher.Event.WaterheaterCalcified
"component_type": "binary_sensor",
"payload_values": {
"device_class": "problem",
"payload_on": "Present"
}
},
"SaltLack": {
5624: { # Dishcare.Dishwasher.Event.SaltLack
"component_type": "binary_sensor",
"payload_values": {
"device_class": "problem",
"payload_on": "Present"
}
},
"RinseAidNearlyEmpty": {
5625: { # Dishcare.Dishwasher.Event.RinseAidLack
"component_type": "binary_sensor",
"payload_values": {
"device_class": "problem",
"payload_on": "Present"
}
},
"SaltNearlyEmpty": {
4626: { # Dishcare.Dishwasher.Event.SaltNearlyEmpty
"component_type": "binary_sensor",
"payload_values": {
"device_class": "problem",
"payload_on": "Present"
}
},
"WaterheaterCalcified": {
5627: { # Dishcare.Dishwasher.Event.RinseAidNearlyEmpty
"component_type": "binary_sensor",
"payload_values": {
"device_class": "problem",
@@ -80,6 +86,13 @@ MAGIC_OVERRIDES = {
}
def augment_device_features(features):
for id, feature in features.items():
if id in MAGIC_OVERRIDES:
feature["discovery"] = MAGIC_OVERRIDES[id]
return features
def publish_ha_discovery(device, client, mqtt_topic):
print(f"{now()} Publishing HA discovery for {device}")
@@ -117,7 +130,7 @@ def publish_ha_discovery(device, client, mqtt_topic):
default_component_type = "binary_sensor" if feature_type == "Event" else "sensor" # TODO use more appropriate types
overrides = MAGIC_OVERRIDES.get(name, {})
overrides = feature.get("discovery", {})
component_type = overrides.get("component_type", default_component_type)

View File

@@ -17,6 +17,7 @@ from Crypto.Hash import SHA256
from Crypto.Random import get_random_bytes
from HCxml2json import xml2json
from HADiscovery import augment_device_features
# These two lines enable debugging at httplib level (requests->urllib3->http.client)
# You will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA.
@@ -310,6 +311,6 @@ for app in account["data"]["homeAppliances"]:
machine = xml2json(features, description)
config["description"] = machine["description"]
config["features"] = machine["features"]
config["features"] = augment_device_features(machine["features"])
print(json.dumps(configs, indent=4))