@@ -314,5 +328,15 @@ export default {
}
}
}
+
+ .value {
+ &.url {
+ text-align: right;
+ }
+
+ .entity-image {
+ max-height: 5em;
+ }
+ }
}
diff --git a/platypush/entities/_base.py b/platypush/entities/_base.py
index 86567aa72..7893342c1 100644
--- a/platypush/entities/_base.py
+++ b/platypush/entities/_base.py
@@ -54,6 +54,9 @@ if 'entity' not in Base.metadata:
is_write_only = Column(Boolean, default=False)
is_query_disabled = Column(Boolean, default=False)
is_configuration = Column(Boolean, default=False)
+ external_url = Column(String)
+ image_url = Column(String)
+
created_at = Column(
DateTime(timezone=False), default=datetime.utcnow(), nullable=False
)
diff --git a/platypush/plugins/zigbee/mqtt/__init__.py b/platypush/plugins/zigbee/mqtt/__init__.py
index 1089b20dc..862bf396a 100644
--- a/platypush/plugins/zigbee/mqtt/__init__.py
+++ b/platypush/plugins/zigbee/mqtt/__init__.py
@@ -292,6 +292,8 @@ class ZigbeeMqttPlugin(MqttPlugin): # lgtm [py/missing-call-to-init]
id=dev['ieee_address'],
name=dev.get('friendly_name'),
description=dev_def.get('description'),
+ external_url=self._get_device_url(dev),
+ image_url=self._get_image_url(dev),
reachable=reachable,
)
@@ -303,6 +305,22 @@ class ZigbeeMqttPlugin(MqttPlugin): # lgtm [py/missing-call-to-init]
return super().transform_entities(compatible_entities) # type: ignore
+ @staticmethod
+ def _get_device_url(device_info: dict) -> Optional[str]:
+ model = device_info.get('definition', {}).get('model')
+ if not model:
+ return
+
+ return f'https://www.zigbee2mqtt.io/devices/{model}.html'
+
+ @staticmethod
+ def _get_image_url(device_info: dict) -> Optional[str]:
+ model = device_info.get('definition', {}).get('model')
+ if not model:
+ return
+
+ return f'https://www.zigbee2mqtt.io/images/devices/{model}.jpg'
+
def _get_network_info(self, **kwargs) -> dict:
self.logger.info('Fetching Zigbee network information')
client = None
diff --git a/platypush/plugins/zwave/mqtt/__init__.py b/platypush/plugins/zwave/mqtt/__init__.py
index 0330d99bb..14d8a5940 100644
--- a/platypush/plugins/zwave/mqtt/__init__.py
+++ b/platypush/plugins/zwave/mqtt/__init__.py
@@ -767,6 +767,7 @@ class ZwaveMqttPlugin(MqttPlugin, ZwaveBasePlugin):
parent = parent_entities[node_id] = Device(
id=node['device_id'],
name=node.get('name'),
+ external_url=self._build_external_url(node),
reachable=(
node.get('is_available', False) and node.get('is_ready', False)
),
@@ -777,6 +778,20 @@ class ZwaveMqttPlugin(MqttPlugin, ZwaveBasePlugin):
entity.parent = parent
entity.reachable = parent.reachable
+ @staticmethod
+ def _build_external_url(node: dict) -> Optional[str]:
+ manufacturer_id = node.get('manufacturer_id')
+ product_id = node.get('product_id')
+ product_type = node.get('product_type')
+ firmware_version = node.get('firmware_version', '0.0')
+ if not (manufacturer_id and product_id and product_type):
+ return
+
+ return (
+ 'https://devices.zwave-js.io/?jumpTo='
+ f'{manufacturer_id}:{product_type}:{product_id}:{firmware_version}'
+ )
+
@classmethod
def _merge_current_and_target_values(cls, values: Iterable[dict]) -> List[dict]:
values_by_id = OrderedDict({v.get('id'): v for v in values})