Support for battery sensors on zigbee.mqtt

This commit is contained in:
Fabio Manganiello 2022-10-29 18:15:45 +02:00
parent 42651e937b
commit 71ccf6d04a
Signed by untrusted user: blacklight
GPG key ID: D90FBA7F76362774

View file

@ -169,7 +169,7 @@ class ZigbeeMqttPlugin(MqttPlugin): # lgtm [py/missing-call-to-init]
if not dev: if not dev:
continue continue
converted_entity = None converted_entities = []
dev_def = dev.get("definition") or {} dev_def = dev.get("definition") or {}
dev_info = { dev_info = {
"type": dev.get("type"), "type": dev.get("type"),
@ -186,12 +186,15 @@ class ZigbeeMqttPlugin(MqttPlugin): # lgtm [py/missing-call-to-init]
light_info = self._get_light_meta(dev) light_info = self._get_light_meta(dev)
switch_info = self._get_switch_meta(dev) switch_info = self._get_switch_meta(dev)
battery_info = self._get_battery_meta(dev)
if light_info: if light_info:
converted_entity = Light( converted_entities.append(
Light(
id=dev['ieee_address'], id=dev['ieee_address'],
name=dev.get('friendly_name'), name=dev.get('friendly_name'),
on=dev.get('state', {}).get('state') == switch_info.get('value_on'), on=dev.get('state', {}).get('state')
== switch_info.get('value_on'),
brightness_min=light_info.get('brightness_min'), brightness_min=light_info.get('brightness_min'),
brightness_max=light_info.get('brightness_max'), brightness_max=light_info.get('brightness_max'),
temperature_min=light_info.get('temperature_min'), temperature_min=light_info.get('temperature_min'),
@ -233,17 +236,34 @@ class ZigbeeMqttPlugin(MqttPlugin): # lgtm [py/missing-call-to-init]
description=dev_def.get('description'), description=dev_def.get('description'),
data=dev_info, data=dev_info,
) )
)
elif switch_info and dev.get('state', {}).get('state') is not None: elif switch_info and dev.get('state', {}).get('state') is not None:
converted_entity = Switch( converted_entities.append(
Switch(
id=dev['ieee_address'], id=dev['ieee_address'],
name=dev.get('friendly_name'), name=dev.get('friendly_name'),
state=dev.get('state', {}).get('state') == switch_info['value_on'], state=dev.get('state', {}).get('state')
== switch_info['value_on'],
description=dev_def.get("description"), description=dev_def.get("description"),
data=dev_info, data=dev_info,
) )
)
if converted_entity: if battery_info:
compatible_entities.append(converted_entity) converted_entities.append(
Battery(
id=dev['ieee_address'],
name=battery_info.get('friendly_name'),
value=dev.get('battery'),
description=battery_info.get('description'),
min=battery_info['min'],
max=battery_info['max'],
data=dev_info,
)
)
if converted_entities:
compatible_entities += converted_entities
return super().transform_entities(compatible_entities) # type: ignore return super().transform_entities(compatible_entities) # type: ignore
@ -1423,6 +1443,32 @@ class ZigbeeMqttPlugin(MqttPlugin): # lgtm [py/missing-call-to-init]
return {} return {}
@staticmethod
def _get_battery_meta(device_info: dict) -> dict:
exposes = (device_info.get('definition', {}) or {}).get('exposes', [])
for exposed in exposes:
for feature in exposed.get('features', []):
if (
feature.get('property') == 'battery'
and feature.get('type') == 'numeric'
):
return {
'friendly_name': (
device_info.get('friendly_name', '[Unnamed device]')
+ ' [Battery]'
),
'ieee_address': device_info.get('friendly_name'),
'property': feature['property'],
'description': feature.get('description'),
'value_min': feature.get('value_min', 0),
'value_max': feature.get('value_max', 100),
'unit': feature.get('unit', '%'),
'is_read_only': not bool(feature.get('access', 0) & 2),
'is_write_only': not bool(feature.get('access', 0) & 1),
}
return {}
@staticmethod @staticmethod
def _get_light_meta(device_info: dict) -> dict: def _get_light_meta(device_info: dict) -> dict:
exposes = (device_info.get('definition', {}) or {}).get('exposes', []) exposes = (device_info.get('definition', {}) or {}).get('exposes', [])