forked from platypush/platypush
Support for battery sensors on zigbee.mqtt
This commit is contained in:
parent
42651e937b
commit
71ccf6d04a
1 changed files with 99 additions and 53 deletions
|
@ -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,64 +186,84 @@ 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(
|
||||||
id=dev['ieee_address'],
|
Light(
|
||||||
name=dev.get('friendly_name'),
|
id=dev['ieee_address'],
|
||||||
on=dev.get('state', {}).get('state') == switch_info.get('value_on'),
|
name=dev.get('friendly_name'),
|
||||||
brightness_min=light_info.get('brightness_min'),
|
on=dev.get('state', {}).get('state')
|
||||||
brightness_max=light_info.get('brightness_max'),
|
== switch_info.get('value_on'),
|
||||||
temperature_min=light_info.get('temperature_min'),
|
brightness_min=light_info.get('brightness_min'),
|
||||||
temperature_max=light_info.get('temperature_max'),
|
brightness_max=light_info.get('brightness_max'),
|
||||||
hue_min=light_info.get('hue_min'),
|
temperature_min=light_info.get('temperature_min'),
|
||||||
hue_max=light_info.get('hue_max'),
|
temperature_max=light_info.get('temperature_max'),
|
||||||
saturation_min=light_info.get('saturation_min'),
|
hue_min=light_info.get('hue_min'),
|
||||||
saturation_max=light_info.get('saturation_max'),
|
hue_max=light_info.get('hue_max'),
|
||||||
brightness=(
|
saturation_min=light_info.get('saturation_min'),
|
||||||
dev.get('state', {})
|
saturation_max=light_info.get('saturation_max'),
|
||||||
.get('color', {})
|
brightness=(
|
||||||
.get(light_info.get('brightness_name', 'brightness'))
|
dev.get('state', {})
|
||||||
),
|
.get('color', {})
|
||||||
temperature=(
|
.get(light_info.get('brightness_name', 'brightness'))
|
||||||
dev.get('state', {})
|
),
|
||||||
.get('color', {})
|
temperature=(
|
||||||
.get(light_info.get('temperature_name', 'temperature'))
|
dev.get('state', {})
|
||||||
),
|
.get('color', {})
|
||||||
hue=(
|
.get(light_info.get('temperature_name', 'temperature'))
|
||||||
dev.get('state', {})
|
),
|
||||||
.get('color', {})
|
hue=(
|
||||||
.get(light_info.get('hue_name', 'hue'))
|
dev.get('state', {})
|
||||||
),
|
.get('color', {})
|
||||||
saturation=(
|
.get(light_info.get('hue_name', 'hue'))
|
||||||
dev.get('state', {})
|
),
|
||||||
.get('color', {})
|
saturation=(
|
||||||
.get(light_info.get('saturation_name', 'saturation'))
|
dev.get('state', {})
|
||||||
),
|
.get('color', {})
|
||||||
x=(
|
.get(light_info.get('saturation_name', 'saturation'))
|
||||||
dev.get('state', {})
|
),
|
||||||
.get('color', {})
|
x=(
|
||||||
.get(light_info.get('x_name', 'x'))
|
dev.get('state', {})
|
||||||
),
|
.get('color', {})
|
||||||
y=(
|
.get(light_info.get('x_name', 'x'))
|
||||||
dev.get('state', {})
|
),
|
||||||
.get('color', {})
|
y=(
|
||||||
.get(light_info.get('y_name', 'y'))
|
dev.get('state', {})
|
||||||
),
|
.get('color', {})
|
||||||
description=dev_def.get('description'),
|
.get(light_info.get('y_name', 'y'))
|
||||||
data=dev_info,
|
),
|
||||||
|
description=dev_def.get('description'),
|
||||||
|
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(
|
||||||
id=dev['ieee_address'],
|
Switch(
|
||||||
name=dev.get('friendly_name'),
|
id=dev['ieee_address'],
|
||||||
state=dev.get('state', {}).get('state') == switch_info['value_on'],
|
name=dev.get('friendly_name'),
|
||||||
description=dev_def.get("description"),
|
state=dev.get('state', {}).get('state')
|
||||||
data=dev_info,
|
== switch_info['value_on'],
|
||||||
|
description=dev_def.get("description"),
|
||||||
|
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', [])
|
||||||
|
|
Loading…
Reference in a new issue