forked from platypush/platypush
Fixed device_get and device_rename to use the new zigbee2mqtt API
This commit is contained in:
parent
452533db17
commit
15d2e1116b
1 changed files with 81 additions and 23 deletions
|
@ -124,6 +124,10 @@ class ZigbeeMqttPlugin(MqttPlugin):
|
|||
|
||||
self.base_topic = base_topic
|
||||
self.timeout = timeout
|
||||
self._info = {
|
||||
'devices': {},
|
||||
'groups': {},
|
||||
}
|
||||
|
||||
def _get_network_info(self, **kwargs):
|
||||
self.logger.info('Fetching Zigbee network information')
|
||||
|
@ -166,6 +170,18 @@ class ZigbeeMqttPlugin(MqttPlugin):
|
|||
if not info_ready:
|
||||
raise TimeoutError('A timeout occurred while fetching the Zigbee network information')
|
||||
|
||||
# Cache the new results
|
||||
self._info['devices'] = {
|
||||
device.get('friendly_name', device['ieee_address']): device
|
||||
for device in info.get('devices', [])
|
||||
}
|
||||
|
||||
self._info['groups'] = {
|
||||
group.get('name'): group
|
||||
for group in info.get('groups', [])
|
||||
}
|
||||
|
||||
self.logger.info('Zigbee network configuration updated')
|
||||
return info
|
||||
finally:
|
||||
try:
|
||||
|
@ -174,21 +190,18 @@ class ZigbeeMqttPlugin(MqttPlugin):
|
|||
except Exception as e:
|
||||
self.logger.warning('Error on MQTT client disconnection: {}'.format(str(e)))
|
||||
|
||||
def _mqtt_args(self, host: Optional[str] = None, **kwargs):
|
||||
if not host:
|
||||
return {
|
||||
'host': self.host,
|
||||
'port': self.port,
|
||||
'timeout': self.timeout,
|
||||
'tls_certfile': self.tls_certfile,
|
||||
'tls_keyfile': self.tls_keyfile,
|
||||
'tls_version': self.tls_version,
|
||||
'tls_ciphers': self.tls_ciphers,
|
||||
'username': self.username,
|
||||
'password': self.password,
|
||||
}
|
||||
|
||||
return kwargs
|
||||
def _mqtt_args(self, **kwargs):
|
||||
return {
|
||||
'host': kwargs.get('host', self.host),
|
||||
'port': kwargs.get('port', self.port),
|
||||
'timeout': kwargs.get('timeout', self.timeout),
|
||||
'tls_certfile': kwargs.get('tls_certfile', self.tls_certfile),
|
||||
'tls_keyfile': kwargs.get('tls_keyfile', self.tls_keyfile),
|
||||
'tls_version': kwargs.get('tls_version', self.tls_version),
|
||||
'tls_ciphers': kwargs.get('tls_ciphers', self.tls_ciphers),
|
||||
'username': kwargs.get('username', self.username),
|
||||
'password': kwargs.get('password', self.password),
|
||||
}
|
||||
|
||||
def _topic(self, topic):
|
||||
return self.base_topic + '/' + topic
|
||||
|
@ -497,10 +510,45 @@ class ZigbeeMqttPlugin(MqttPlugin):
|
|||
assert not [dev for dev in devices if dev.get('friendly_name') == name], \
|
||||
'A device named {} already exists on the network'.format(name)
|
||||
|
||||
if device:
|
||||
req = {
|
||||
'from': device,
|
||||
'to': name,
|
||||
}
|
||||
else:
|
||||
req = {
|
||||
'last': True,
|
||||
'to': name,
|
||||
}
|
||||
|
||||
self.publish(
|
||||
topic=self._topic('bridge/config/rename{}'.format('_last' if not device else '')),
|
||||
msg={'old': device, 'new': name} if device else name,
|
||||
**self._mqtt_args(**kwargs))
|
||||
topic=self._topic('bridge/request/device/rename'),
|
||||
msg=req, **self._mqtt_args(**kwargs))
|
||||
|
||||
@staticmethod
|
||||
def _build_device_get_request(values: List[Dict[str, Any]]) -> dict:
|
||||
def extract_value(value: dict, root: dict):
|
||||
if not value.get('access', 1) & 0x1:
|
||||
# Property not readable
|
||||
return
|
||||
|
||||
if 'features' not in value:
|
||||
if 'property' in value:
|
||||
root[value['property']] = ''
|
||||
return
|
||||
|
||||
if 'property' in value:
|
||||
root[value['property']] = root.get(value['property'], {})
|
||||
root = root[value['property']]
|
||||
|
||||
for feature in value['features']:
|
||||
extract_value(feature, root)
|
||||
|
||||
ret = {}
|
||||
for value in values:
|
||||
extract_value(value, root=ret)
|
||||
|
||||
return ret
|
||||
|
||||
# noinspection PyShadowingBuiltins
|
||||
@action
|
||||
|
@ -516,16 +564,26 @@ class ZigbeeMqttPlugin(MqttPlugin):
|
|||
(default: query the default configured device).
|
||||
:return: Key->value map of the device properties.
|
||||
"""
|
||||
properties = self.publish(topic=self._topic(device + ('/get' if property else '')),
|
||||
reply_topic=self._topic(device),
|
||||
msg={property: ''} if property else '',
|
||||
**self._mqtt_args(**kwargs)).output
|
||||
kwargs = self._mqtt_args(**kwargs)
|
||||
|
||||
if property:
|
||||
properties = self.publish(topic=self._topic(device) + '/get/' + property, reply_topic=self._topic(device),
|
||||
msg={property: ''}, **kwargs).output
|
||||
|
||||
assert property in properties, 'No such property: ' + property
|
||||
return {property: properties[property]}
|
||||
|
||||
return properties
|
||||
if device not in self._info.get('devices', {}):
|
||||
# Refresh devices info
|
||||
self._get_network_info(**kwargs)
|
||||
|
||||
assert self._info.get('devices', {}).get(device), 'No such device: ' + device
|
||||
exposes = (self._info.get('devices', {}).get(device, {}).get('definition', {}) or {}).get('exposes', [])
|
||||
if not exposes:
|
||||
return {}
|
||||
|
||||
return self.publish(topic=self._topic(device) + '/get', reply_topic=self._topic(device),
|
||||
msg=self._build_device_get_request(exposes), **kwargs)
|
||||
|
||||
# noinspection PyShadowingBuiltins,DuplicatedCode
|
||||
@action
|
||||
|
|
Loading…
Reference in a new issue