Add update platform to ZHA (bumps zigpy to 0.61.0) (#107612)
* stub out zha update entity * update matcher * updates based on assumptions / conversation * hook into current installed version * post rebase cleanup * incorporate zigpy changes * fix async_setup_entry * fix sw_version * make ota work with config diagnostic match * fix version format * sync up with latest Zigpy changes * fix name attribute * disable ota providers for tests * update device list * review comment * add current_file_version to Ota ZCL_INIT_ATTRS * updates to update and start tests * get installed version from restore data * better version handling * remove done todo notes * reorganize test * move image notify to cluster handler * add test for manual update check * firmware update success test * coverage * use zigpy defs * clean up after rebase * bump Zigpy * cleanup from review comments * fix busted F string * fix empty error * move inside check * guard zigbee network from bulk check for updates
This commit is contained in:
parent
2f9f0bae46
commit
3115af1041
13 changed files with 1291 additions and 19 deletions
|
@ -56,6 +56,7 @@ from ..const import (
|
|||
SIGNAL_MOVE_LEVEL,
|
||||
SIGNAL_SET_LEVEL,
|
||||
SIGNAL_UPDATE_DEVICE,
|
||||
UNKNOWN as ZHA_UNKNOWN,
|
||||
)
|
||||
from . import (
|
||||
AttrReportConfig,
|
||||
|
@ -523,12 +524,47 @@ class OnOffConfigurationClusterHandler(ClusterHandler):
|
|||
|
||||
|
||||
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Ota.cluster_id)
|
||||
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(Ota.cluster_id)
|
||||
class OtaClientClusterHandler(ClientClusterHandler):
|
||||
class OtaClusterHandler(ClusterHandler):
|
||||
"""OTA cluster handler."""
|
||||
|
||||
BIND: bool = False
|
||||
|
||||
# Some devices have this cluster in the wrong collection (e.g. Third Reality)
|
||||
ZCL_INIT_ATTRS = {
|
||||
Ota.AttributeDefs.current_file_version.name: True,
|
||||
}
|
||||
|
||||
@property
|
||||
def current_file_version(self) -> str:
|
||||
"""Return cached value of current_file_version attribute."""
|
||||
current_file_version = self.cluster.get(
|
||||
Ota.AttributeDefs.current_file_version.name
|
||||
)
|
||||
if current_file_version is not None:
|
||||
return f"0x{int(current_file_version):08x}"
|
||||
return ZHA_UNKNOWN
|
||||
|
||||
|
||||
@registries.CLIENT_CLUSTER_HANDLER_REGISTRY.register(Ota.cluster_id)
|
||||
class OtaClientClusterHandler(ClientClusterHandler):
|
||||
"""OTA client cluster handler."""
|
||||
|
||||
BIND: bool = False
|
||||
|
||||
ZCL_INIT_ATTRS = {
|
||||
Ota.AttributeDefs.current_file_version.name: True,
|
||||
}
|
||||
|
||||
@property
|
||||
def current_file_version(self) -> str:
|
||||
"""Return cached value of current_file_version attribute."""
|
||||
current_file_version = self.cluster.get(
|
||||
Ota.AttributeDefs.current_file_version.name
|
||||
)
|
||||
if current_file_version is not None:
|
||||
return f"0x{int(current_file_version):08x}"
|
||||
return ZHA_UNKNOWN
|
||||
|
||||
@callback
|
||||
def cluster_command(
|
||||
self, tsn: int, command_id: int, args: list[Any] | None
|
||||
|
@ -540,10 +576,17 @@ class OtaClientClusterHandler(ClientClusterHandler):
|
|||
cmd_name = command_id
|
||||
|
||||
signal_id = self._endpoint.unique_id.split("-")[0]
|
||||
if cmd_name == "query_next_image":
|
||||
if cmd_name == Ota.ServerCommandDefs.query_next_image.name:
|
||||
assert args
|
||||
self.async_send_signal(SIGNAL_UPDATE_DEVICE.format(signal_id), args[3])
|
||||
|
||||
async def async_check_for_update(self):
|
||||
"""Check for firmware availability by issuing an image notify command."""
|
||||
await self.cluster.image_notify(
|
||||
payload_type=(self.cluster.ImageNotifyCommand.PayloadType.QueryJitter),
|
||||
query_jitter=100,
|
||||
)
|
||||
|
||||
|
||||
@registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.register(Partition.cluster_id)
|
||||
class PartitionClusterHandler(ClusterHandler):
|
||||
|
|
|
@ -89,6 +89,7 @@ CLUSTER_HANDLER_LEVEL = ATTR_LEVEL
|
|||
CLUSTER_HANDLER_MULTISTATE_INPUT = "multistate_input"
|
||||
CLUSTER_HANDLER_OCCUPANCY = "occupancy"
|
||||
CLUSTER_HANDLER_ON_OFF = "on_off"
|
||||
CLUSTER_HANDLER_OTA = "ota"
|
||||
CLUSTER_HANDLER_POWER_CONFIGURATION = "power"
|
||||
CLUSTER_HANDLER_PRESSURE = "pressure"
|
||||
CLUSTER_HANDLER_SHADE = "shade"
|
||||
|
@ -120,6 +121,7 @@ PLATFORMS = (
|
|||
Platform.SENSOR,
|
||||
Platform.SIREN,
|
||||
Platform.SWITCH,
|
||||
Platform.UPDATE,
|
||||
)
|
||||
|
||||
CONF_ALARM_MASTER_CODE = "alarm_master_code"
|
||||
|
|
|
@ -26,6 +26,7 @@ from homeassistant.const import ATTR_COMMAND, ATTR_DEVICE_ID, ATTR_NAME
|
|||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.device_registry import DeviceEntry
|
||||
from homeassistant.helpers.dispatcher import (
|
||||
async_dispatcher_connect,
|
||||
async_dispatcher_send,
|
||||
|
@ -406,6 +407,15 @@ class ZHADevice(LogMixin):
|
|||
ATTR_MODEL: self.model,
|
||||
}
|
||||
|
||||
@property
|
||||
def sw_version(self) -> str | None:
|
||||
"""Return the software version for this device."""
|
||||
device_registry = dr.async_get(self.hass)
|
||||
reg_device: DeviceEntry | None = device_registry.async_get(self.device_id)
|
||||
if reg_device is None:
|
||||
return None
|
||||
return reg_device.sw_version
|
||||
|
||||
@classmethod
|
||||
def new(
|
||||
cls,
|
||||
|
|
|
@ -6,6 +6,8 @@ from collections.abc import Callable
|
|||
import logging
|
||||
from typing import TYPE_CHECKING, cast
|
||||
|
||||
from zigpy.zcl.clusters.general import Ota
|
||||
|
||||
from homeassistant.const import CONF_TYPE, Platform
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
@ -32,6 +34,7 @@ from .. import ( # noqa: F401
|
|||
sensor,
|
||||
siren,
|
||||
switch,
|
||||
update,
|
||||
)
|
||||
from . import const as zha_const, registries as zha_regs
|
||||
|
||||
|
@ -233,10 +236,16 @@ class ProbeEndpoint:
|
|||
cmpt_by_dev_type = zha_regs.DEVICE_CLASS[ep_profile_id].get(ep_device_type)
|
||||
|
||||
if config_diagnostic_entities:
|
||||
cluster_handlers = list(endpoint.all_cluster_handlers.values())
|
||||
ota_handler_id = f"{endpoint.id}:0x{Ota.cluster_id:04x}"
|
||||
if ota_handler_id in endpoint.client_cluster_handlers:
|
||||
cluster_handlers.append(
|
||||
endpoint.client_cluster_handlers[ota_handler_id]
|
||||
)
|
||||
matches, claimed = zha_regs.ZHA_ENTITIES.get_config_diagnostic_entity(
|
||||
endpoint.device.manufacturer,
|
||||
endpoint.device.model,
|
||||
list(endpoint.all_cluster_handlers.values()),
|
||||
cluster_handlers,
|
||||
endpoint.device.quirk_id,
|
||||
)
|
||||
else:
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
"pyserial-asyncio==0.6",
|
||||
"zha-quirks==0.0.110",
|
||||
"zigpy-deconz==0.22.4",
|
||||
"zigpy==0.60.7",
|
||||
"zigpy==0.61.0",
|
||||
"zigpy-xbee==0.20.1",
|
||||
"zigpy-zigate==0.12.0",
|
||||
"zigpy-znp==0.12.1",
|
||||
|
|
235
homeassistant/components/zha/update.py
Normal file
235
homeassistant/components/zha/update.py
Normal file
|
@ -0,0 +1,235 @@
|
|||
"""Representation of ZHA updates."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import functools
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from zigpy.ota.image import BaseOTAImage
|
||||
from zigpy.types import uint16_t
|
||||
from zigpy.zcl.foundation import Status
|
||||
|
||||
from homeassistant.components.update import (
|
||||
ATTR_INSTALLED_VERSION,
|
||||
ATTR_LATEST_VERSION,
|
||||
UpdateDeviceClass,
|
||||
UpdateEntity,
|
||||
UpdateEntityFeature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory, Platform
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.restore_state import ExtraStoredData
|
||||
|
||||
from .core import discovery
|
||||
from .core.const import CLUSTER_HANDLER_OTA, SIGNAL_ADD_ENTITIES, UNKNOWN
|
||||
from .core.helpers import get_zha_data
|
||||
from .core.registries import ZHA_ENTITIES
|
||||
from .entity import ZhaEntity
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .core.cluster_handlers import ClusterHandler
|
||||
from .core.device import ZHADevice
|
||||
|
||||
CONFIG_DIAGNOSTIC_MATCH = functools.partial(
|
||||
ZHA_ENTITIES.config_diagnostic_match, Platform.UPDATE
|
||||
)
|
||||
|
||||
# don't let homeassistant check for updates button hammer the zigbee network
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
|
||||
@dataclass
|
||||
class ZHAFirmwareUpdateExtraStoredData(ExtraStoredData):
|
||||
"""Extra stored data for ZHA firmware update entity."""
|
||||
|
||||
image_type: uint16_t | None
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
"""Return a dict representation of the extra data."""
|
||||
return {"image_type": self.image_type}
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Zigbee Home Automation update from config entry."""
|
||||
zha_data = get_zha_data(hass)
|
||||
entities_to_create = zha_data.platforms[Platform.UPDATE]
|
||||
|
||||
unsub = async_dispatcher_connect(
|
||||
hass,
|
||||
SIGNAL_ADD_ENTITIES,
|
||||
functools.partial(
|
||||
discovery.async_add_entities, async_add_entities, entities_to_create
|
||||
),
|
||||
)
|
||||
config_entry.async_on_unload(unsub)
|
||||
|
||||
|
||||
@CONFIG_DIAGNOSTIC_MATCH(cluster_handler_names=CLUSTER_HANDLER_OTA)
|
||||
class ZHAFirmwareUpdateEntity(ZhaEntity, UpdateEntity):
|
||||
"""Representation of a ZHA firmware update entity."""
|
||||
|
||||
_unique_id_suffix = "firmware_update"
|
||||
_attr_entity_category = EntityCategory.CONFIG
|
||||
_attr_device_class = UpdateDeviceClass.FIRMWARE
|
||||
_attr_supported_features = (
|
||||
UpdateEntityFeature.INSTALL
|
||||
| UpdateEntityFeature.PROGRESS
|
||||
| UpdateEntityFeature.SPECIFIC_VERSION
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
unique_id: str,
|
||||
zha_device: ZHADevice,
|
||||
channels: list[ClusterHandler],
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Initialize the ZHA update entity."""
|
||||
super().__init__(unique_id, zha_device, channels, **kwargs)
|
||||
self._ota_cluster_handler: ClusterHandler = self.cluster_handlers[
|
||||
CLUSTER_HANDLER_OTA
|
||||
]
|
||||
self._attr_installed_version: str = self.determine_installed_version()
|
||||
self._image_type: uint16_t | None = None
|
||||
self._latest_version_firmware: BaseOTAImage | None = None
|
||||
self._result = None
|
||||
|
||||
@callback
|
||||
def determine_installed_version(self) -> str:
|
||||
"""Determine the currently installed firmware version."""
|
||||
currently_installed_version = self._ota_cluster_handler.current_file_version
|
||||
version_from_dr = self.zha_device.sw_version
|
||||
if currently_installed_version == UNKNOWN and version_from_dr:
|
||||
currently_installed_version = version_from_dr
|
||||
return currently_installed_version
|
||||
|
||||
@property
|
||||
def extra_restore_state_data(self) -> ZHAFirmwareUpdateExtraStoredData:
|
||||
"""Return ZHA firmware update specific state data to be restored."""
|
||||
return ZHAFirmwareUpdateExtraStoredData(self._image_type)
|
||||
|
||||
@callback
|
||||
def device_ota_update_available(self, image: BaseOTAImage) -> None:
|
||||
"""Handle ota update available signal from Zigpy."""
|
||||
self._latest_version_firmware = image
|
||||
self._attr_latest_version = f"0x{image.header.file_version:08x}"
|
||||
self._image_type = image.header.image_type
|
||||
self.async_write_ha_state()
|
||||
|
||||
@callback
|
||||
def _update_progress(self, current: int, total: int, progress: float) -> None:
|
||||
"""Update install progress on event."""
|
||||
assert self._latest_version_firmware
|
||||
self._attr_in_progress = int(progress)
|
||||
self.async_write_ha_state()
|
||||
|
||||
@callback
|
||||
def _reset_progress(self, write_state: bool = True) -> None:
|
||||
"""Reset update install progress."""
|
||||
self._result = None
|
||||
self._attr_in_progress = False
|
||||
if write_state:
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Handle the update entity service call to manually check for available firmware updates."""
|
||||
await super().async_update()
|
||||
# check for updates in the HA settings menu can invoke this so we need to check if the device
|
||||
# is mains powered so we don't get a ton of errors in the logs from sleepy devices.
|
||||
if self.zha_device.available and self.zha_device.is_mains_powered:
|
||||
await self._ota_cluster_handler.async_check_for_update()
|
||||
|
||||
async def async_install(
|
||||
self, version: str | None, backup: bool, **kwargs: Any
|
||||
) -> None:
|
||||
"""Install an update."""
|
||||
firmware = self._latest_version_firmware
|
||||
assert firmware
|
||||
self._reset_progress(False)
|
||||
self._attr_in_progress = True
|
||||
self.async_write_ha_state()
|
||||
|
||||
try:
|
||||
self._result = await self.zha_device.device.update_firmware(
|
||||
self._latest_version_firmware,
|
||||
self._update_progress,
|
||||
)
|
||||
except Exception as ex:
|
||||
self._reset_progress()
|
||||
raise HomeAssistantError(ex) from ex
|
||||
|
||||
assert self._result is not None
|
||||
|
||||
# If the update was not successful, we should throw an error to let the user know
|
||||
if self._result != Status.SUCCESS:
|
||||
# save result since reset_progress will clear it
|
||||
results = self._result
|
||||
self._reset_progress()
|
||||
raise HomeAssistantError(f"Update was not successful - result: {results}")
|
||||
|
||||
# If we get here, all files were installed successfully
|
||||
self._attr_installed_version = (
|
||||
self._attr_latest_version
|
||||
) = f"0x{firmware.header.file_version:08x}"
|
||||
self._latest_version_firmware = None
|
||||
self._reset_progress()
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Call when entity is added."""
|
||||
await super().async_added_to_hass()
|
||||
last_state = await self.async_get_last_state()
|
||||
# If we have a complete previous state, use that to set the installed version
|
||||
if (
|
||||
last_state
|
||||
and self._attr_installed_version == UNKNOWN
|
||||
and (installed_version := last_state.attributes.get(ATTR_INSTALLED_VERSION))
|
||||
):
|
||||
self._attr_installed_version = installed_version
|
||||
# If we have a complete previous state, use that to set the latest version
|
||||
if (
|
||||
last_state
|
||||
and (latest_version := last_state.attributes.get(ATTR_LATEST_VERSION))
|
||||
is not None
|
||||
and latest_version != UNKNOWN
|
||||
):
|
||||
self._attr_latest_version = latest_version
|
||||
# If we have no state or latest version to restore, or the latest version is
|
||||
# the same as the installed version, we can set the latest
|
||||
# version to installed so that the entity starts as off.
|
||||
elif (
|
||||
not last_state
|
||||
or not latest_version
|
||||
or latest_version == self._attr_installed_version
|
||||
):
|
||||
self._attr_latest_version = self._attr_installed_version
|
||||
|
||||
if self._attr_latest_version != self._attr_installed_version and (
|
||||
extra_data := await self.async_get_last_extra_data()
|
||||
):
|
||||
self._image_type = extra_data.as_dict()["image_type"]
|
||||
if self._image_type:
|
||||
self._latest_version_firmware = (
|
||||
await self.zha_device.device.application.ota.get_ota_image(
|
||||
self.zha_device.manufacturer_code, self._image_type
|
||||
)
|
||||
)
|
||||
# if we can't locate an image but we have a latest version that differs
|
||||
# we should set the latest version to the installed version to avoid
|
||||
# confusion and errors
|
||||
if not self._latest_version_firmware:
|
||||
self._attr_latest_version = self._attr_installed_version
|
||||
|
||||
self.zha_device.device.add_listener(self)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Call when entity will be removed."""
|
||||
await super().async_will_remove_from_hass()
|
||||
self._reset_progress(False)
|
|
@ -2930,7 +2930,7 @@ zigpy-zigate==0.12.0
|
|||
zigpy-znp==0.12.1
|
||||
|
||||
# homeassistant.components.zha
|
||||
zigpy==0.60.7
|
||||
zigpy==0.61.0
|
||||
|
||||
# homeassistant.components.zoneminder
|
||||
zm-py==0.5.4
|
||||
|
|
|
@ -2241,7 +2241,7 @@ zigpy-zigate==0.12.0
|
|||
zigpy-znp==0.12.1
|
||||
|
||||
# homeassistant.components.zha
|
||||
zigpy==0.60.7
|
||||
zigpy==0.61.0
|
||||
|
||||
# homeassistant.components.zwave_js
|
||||
zwave-js-server-python==0.55.3
|
||||
|
|
|
@ -54,7 +54,6 @@ def patch_cluster(cluster):
|
|||
cluster.configure_reporting_multiple = AsyncMock(
|
||||
return_value=zcl_f.ConfigureReportingResponse.deserialize(b"\x00")[0]
|
||||
)
|
||||
cluster.deserialize = Mock()
|
||||
cluster.handle_cluster_request = Mock()
|
||||
cluster.read_attributes = AsyncMock(wraps=cluster.read_attributes)
|
||||
cluster.read_attributes_raw = AsyncMock(side_effect=_read_attribute_raw)
|
||||
|
|
|
@ -154,6 +154,14 @@ async def zigpy_app_controller():
|
|||
zigpy.config.CONF_STARTUP_ENERGY_SCAN: False,
|
||||
zigpy.config.CONF_NWK_BACKUP_ENABLED: False,
|
||||
zigpy.config.CONF_TOPO_SCAN_ENABLED: False,
|
||||
zigpy.config.CONF_OTA: {
|
||||
zigpy.config.CONF_OTA_IKEA: False,
|
||||
zigpy.config.CONF_OTA_INOVELLI: False,
|
||||
zigpy.config.CONF_OTA_LEDVANCE: False,
|
||||
zigpy.config.CONF_OTA_SALUS: False,
|
||||
zigpy.config.CONF_OTA_SONOFF: False,
|
||||
zigpy.config.CONF_OTA_THIRDREALITY: False,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -990,15 +990,9 @@ async def test_cluster_handler_naming() -> None:
|
|||
assert issubclass(client_cluster_handler, cluster_handlers.ClientClusterHandler)
|
||||
assert client_cluster_handler.__name__.endswith("ClientClusterHandler")
|
||||
|
||||
server_cluster_handlers = []
|
||||
for cluster_handler_dict in registries.ZIGBEE_CLUSTER_HANDLER_REGISTRY.values():
|
||||
# remove this filter in the update platform PR
|
||||
server_cluster_handlers += [
|
||||
cluster_handler
|
||||
for cluster_handler in cluster_handler_dict.values()
|
||||
if cluster_handler.__name__ != "OtaClientClusterHandler"
|
||||
]
|
||||
|
||||
for cluster_handler in server_cluster_handlers:
|
||||
assert not issubclass(cluster_handler, cluster_handlers.ClientClusterHandler)
|
||||
assert cluster_handler.__name__.endswith("ClusterHandler")
|
||||
for cluster_handler in cluster_handler_dict.values():
|
||||
assert not issubclass(
|
||||
cluster_handler, cluster_handlers.ClientClusterHandler
|
||||
)
|
||||
assert cluster_handler.__name__.endswith("ClusterHandler")
|
||||
|
|
587
tests/components/zha/test_update.py
Normal file
587
tests/components/zha/test_update.py
Normal file
|
@ -0,0 +1,587 @@
|
|||
"""Test ZHA firmware updates."""
|
||||
from unittest.mock import AsyncMock, MagicMock, call, patch
|
||||
|
||||
import pytest
|
||||
from zigpy.exceptions import DeliveryError
|
||||
from zigpy.ota import CachedImage
|
||||
import zigpy.ota.image as firmware
|
||||
import zigpy.profiles.zha as zha
|
||||
import zigpy.types as t
|
||||
import zigpy.zcl.clusters.general as general
|
||||
import zigpy.zcl.foundation as foundation
|
||||
|
||||
from homeassistant.components.homeassistant import (
|
||||
DOMAIN as HA_DOMAIN,
|
||||
SERVICE_UPDATE_ENTITY,
|
||||
)
|
||||
from homeassistant.components.update import (
|
||||
ATTR_IN_PROGRESS,
|
||||
ATTR_INSTALLED_VERSION,
|
||||
ATTR_LATEST_VERSION,
|
||||
DOMAIN as UPDATE_DOMAIN,
|
||||
SERVICE_INSTALL,
|
||||
)
|
||||
from homeassistant.components.update.const import ATTR_SKIPPED_VERSION
|
||||
from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, Platform
|
||||
from homeassistant.core import HomeAssistant, State
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .common import async_enable_traffic, find_entity_id, update_attribute_cache
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_TYPE
|
||||
|
||||
from tests.common import mock_restore_cache_with_extra_data
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def update_platform_only():
|
||||
"""Only set up the update and required base platforms to speed up tests."""
|
||||
with patch(
|
||||
"homeassistant.components.zha.PLATFORMS",
|
||||
(
|
||||
Platform.UPDATE,
|
||||
Platform.SENSOR,
|
||||
Platform.SELECT,
|
||||
Platform.SWITCH,
|
||||
),
|
||||
):
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def zigpy_device(zigpy_device_mock):
|
||||
"""Device tracker zigpy device."""
|
||||
endpoints = {
|
||||
1: {
|
||||
SIG_EP_INPUT: [general.Basic.cluster_id, general.OnOff.cluster_id],
|
||||
SIG_EP_OUTPUT: [general.Ota.cluster_id],
|
||||
SIG_EP_TYPE: zha.DeviceType.ON_OFF_SWITCH,
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(
|
||||
endpoints, node_descriptor=b"\x02@\x84_\x11\x7fd\x00\x00,d\x00\x00"
|
||||
)
|
||||
|
||||
|
||||
async def setup_test_data(
|
||||
zha_device_joined_restored,
|
||||
zigpy_device,
|
||||
skip_attribute_plugs=False,
|
||||
file_not_found=False,
|
||||
):
|
||||
"""Set up test data for the tests."""
|
||||
fw_version = 0x12345678
|
||||
installed_fw_version = fw_version - 10
|
||||
cluster = zigpy_device.endpoints[1].out_clusters[general.Ota.cluster_id]
|
||||
if not skip_attribute_plugs:
|
||||
cluster.PLUGGED_ATTR_READS = {
|
||||
general.Ota.AttributeDefs.current_file_version.name: installed_fw_version
|
||||
}
|
||||
update_attribute_cache(cluster)
|
||||
|
||||
# set up firmware image
|
||||
fw_image = firmware.OTAImage()
|
||||
fw_image.subelements = [firmware.SubElement(tag_id=0x0000, data=b"fw_image")]
|
||||
fw_header = firmware.OTAImageHeader(
|
||||
file_version=fw_version,
|
||||
image_type=0x90,
|
||||
manufacturer_id=zigpy_device.manufacturer_id,
|
||||
upgrade_file_id=firmware.OTAImageHeader.MAGIC_VALUE,
|
||||
header_version=256,
|
||||
header_length=56,
|
||||
field_control=0,
|
||||
stack_version=2,
|
||||
header_string="This is a test header!",
|
||||
image_size=56 + 2 + 4 + 8,
|
||||
)
|
||||
fw_image.header = fw_header
|
||||
fw_image.should_update = MagicMock(return_value=True)
|
||||
cached_image = CachedImage(fw_image)
|
||||
|
||||
cluster.endpoint.device.application.ota.get_ota_image = AsyncMock(
|
||||
return_value=None if file_not_found else cached_image
|
||||
)
|
||||
|
||||
zha_device = await zha_device_joined_restored(zigpy_device)
|
||||
zha_device.async_update_sw_build_id(installed_fw_version)
|
||||
|
||||
return zha_device, cluster, fw_image, installed_fw_version
|
||||
|
||||
|
||||
async def test_firmware_update_notification_from_zigpy(
|
||||
hass: HomeAssistant, zha_device_joined_restored, zigpy_device
|
||||
) -> None:
|
||||
"""Test ZHA update platform - firmware update notification."""
|
||||
zha_device, cluster, fw_image, installed_fw_version = await setup_test_data(
|
||||
zha_device_joined_restored, zigpy_device
|
||||
)
|
||||
|
||||
entity_id = find_entity_id(Platform.UPDATE, zha_device, hass)
|
||||
assert entity_id is not None
|
||||
|
||||
# allow traffic to flow through the gateway and device
|
||||
await async_enable_traffic(hass, [zha_device])
|
||||
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
# simulate an image available notification
|
||||
await cluster._handle_query_next_image(
|
||||
fw_image.header.field_control,
|
||||
zha_device.manufacturer_code,
|
||||
fw_image.header.image_type,
|
||||
installed_fw_version,
|
||||
fw_image.header.header_version,
|
||||
tsn=15,
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == f"0x{installed_fw_version:08x}"
|
||||
assert not attrs[ATTR_IN_PROGRESS]
|
||||
assert attrs[ATTR_LATEST_VERSION] == f"0x{fw_image.header.file_version:08x}"
|
||||
|
||||
|
||||
async def test_firmware_update_notification_from_service_call(
|
||||
hass: HomeAssistant, zha_device_joined_restored, zigpy_device
|
||||
) -> None:
|
||||
"""Test ZHA update platform - firmware update manual check."""
|
||||
zha_device, cluster, fw_image, installed_fw_version = await setup_test_data(
|
||||
zha_device_joined_restored, zigpy_device
|
||||
)
|
||||
|
||||
entity_id = find_entity_id(Platform.UPDATE, zha_device, hass)
|
||||
assert entity_id is not None
|
||||
|
||||
# allow traffic to flow through the gateway and device
|
||||
await async_enable_traffic(hass, [zha_device])
|
||||
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
async def _async_image_notify_side_effect(*args, **kwargs):
|
||||
await cluster._handle_query_next_image(
|
||||
fw_image.header.field_control,
|
||||
zha_device.manufacturer_code,
|
||||
fw_image.header.image_type,
|
||||
installed_fw_version,
|
||||
fw_image.header.header_version,
|
||||
tsn=15,
|
||||
)
|
||||
|
||||
await async_setup_component(hass, HA_DOMAIN, {})
|
||||
cluster.image_notify = AsyncMock(side_effect=_async_image_notify_side_effect)
|
||||
await hass.services.async_call(
|
||||
HA_DOMAIN,
|
||||
SERVICE_UPDATE_ENTITY,
|
||||
service_data={ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
assert cluster.image_notify.await_count == 1
|
||||
assert cluster.image_notify.call_args_list[0] == call(
|
||||
payload_type=cluster.ImageNotifyCommand.PayloadType.QueryJitter,
|
||||
query_jitter=100,
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == f"0x{installed_fw_version:08x}"
|
||||
assert not attrs[ATTR_IN_PROGRESS]
|
||||
assert attrs[ATTR_LATEST_VERSION] == f"0x{fw_image.header.file_version:08x}"
|
||||
|
||||
|
||||
def make_packet(zigpy_device, cluster, cmd_name: str, **kwargs):
|
||||
"""Make a zigpy packet."""
|
||||
req_hdr, req_cmd = cluster._create_request(
|
||||
general=False,
|
||||
command_id=cluster.commands_by_name[cmd_name].id,
|
||||
schema=cluster.commands_by_name[cmd_name].schema,
|
||||
disable_default_response=False,
|
||||
direction=foundation.Direction.Server_to_Client,
|
||||
args=(),
|
||||
kwargs=kwargs,
|
||||
)
|
||||
|
||||
ota_packet = t.ZigbeePacket(
|
||||
src=t.AddrModeAddress(addr_mode=t.AddrMode.NWK, address=zigpy_device.nwk),
|
||||
src_ep=1,
|
||||
dst=t.AddrModeAddress(addr_mode=t.AddrMode.NWK, address=0x0000),
|
||||
dst_ep=1,
|
||||
tsn=req_hdr.tsn,
|
||||
profile_id=260,
|
||||
cluster_id=cluster.cluster_id,
|
||||
data=t.SerializableBytes(req_hdr.serialize() + req_cmd.serialize()),
|
||||
lqi=255,
|
||||
rssi=-30,
|
||||
)
|
||||
|
||||
return ota_packet
|
||||
|
||||
|
||||
async def test_firmware_update_success(
|
||||
hass: HomeAssistant, zha_device_joined_restored, zigpy_device
|
||||
) -> None:
|
||||
"""Test ZHA update platform - firmware update success."""
|
||||
zha_device, cluster, fw_image, installed_fw_version = await setup_test_data(
|
||||
zha_device_joined_restored, zigpy_device
|
||||
)
|
||||
|
||||
entity_id = find_entity_id(Platform.UPDATE, zha_device, hass)
|
||||
assert entity_id is not None
|
||||
|
||||
# allow traffic to flow through the gateway and device
|
||||
await async_enable_traffic(hass, [zha_device])
|
||||
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
# simulate an image available notification
|
||||
await cluster._handle_query_next_image(
|
||||
fw_image.header.field_control,
|
||||
zha_device.manufacturer_code,
|
||||
fw_image.header.image_type,
|
||||
installed_fw_version,
|
||||
fw_image.header.header_version,
|
||||
tsn=15,
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == f"0x{installed_fw_version:08x}"
|
||||
assert not attrs[ATTR_IN_PROGRESS]
|
||||
assert attrs[ATTR_LATEST_VERSION] == f"0x{fw_image.header.file_version:08x}"
|
||||
|
||||
async def endpoint_reply(cluster_id, tsn, data, command_id):
|
||||
if cluster_id == general.Ota.cluster_id:
|
||||
hdr, cmd = cluster.deserialize(data)
|
||||
if isinstance(cmd, general.Ota.ImageNotifyCommand):
|
||||
zigpy_device.packet_received(
|
||||
make_packet(
|
||||
zigpy_device,
|
||||
cluster,
|
||||
general.Ota.ServerCommandDefs.query_next_image.name,
|
||||
field_control=general.Ota.QueryNextImageCommand.FieldControl.HardwareVersion,
|
||||
manufacturer_code=fw_image.header.manufacturer_id,
|
||||
image_type=fw_image.header.image_type,
|
||||
current_file_version=fw_image.header.file_version - 10,
|
||||
hardware_version=1,
|
||||
)
|
||||
)
|
||||
elif isinstance(
|
||||
cmd, general.Ota.ClientCommandDefs.query_next_image_response.schema
|
||||
):
|
||||
assert cmd.status == foundation.Status.SUCCESS
|
||||
assert cmd.manufacturer_code == fw_image.header.manufacturer_id
|
||||
assert cmd.image_type == fw_image.header.image_type
|
||||
assert cmd.file_version == fw_image.header.file_version
|
||||
assert cmd.image_size == fw_image.header.image_size
|
||||
zigpy_device.packet_received(
|
||||
make_packet(
|
||||
zigpy_device,
|
||||
cluster,
|
||||
general.Ota.ServerCommandDefs.image_block.name,
|
||||
field_control=general.Ota.ImageBlockCommand.FieldControl.RequestNodeAddr,
|
||||
manufacturer_code=fw_image.header.manufacturer_id,
|
||||
image_type=fw_image.header.image_type,
|
||||
file_version=fw_image.header.file_version,
|
||||
file_offset=0,
|
||||
maximum_data_size=40,
|
||||
request_node_addr=zigpy_device.ieee,
|
||||
)
|
||||
)
|
||||
elif isinstance(
|
||||
cmd, general.Ota.ClientCommandDefs.image_block_response.schema
|
||||
):
|
||||
if cmd.file_offset == 0:
|
||||
assert cmd.status == foundation.Status.SUCCESS
|
||||
assert cmd.manufacturer_code == fw_image.header.manufacturer_id
|
||||
assert cmd.image_type == fw_image.header.image_type
|
||||
assert cmd.file_version == fw_image.header.file_version
|
||||
assert cmd.file_offset == 0
|
||||
assert cmd.image_data == fw_image.serialize()[0:40]
|
||||
zigpy_device.packet_received(
|
||||
make_packet(
|
||||
zigpy_device,
|
||||
cluster,
|
||||
general.Ota.ServerCommandDefs.image_block.name,
|
||||
field_control=general.Ota.ImageBlockCommand.FieldControl.RequestNodeAddr,
|
||||
manufacturer_code=fw_image.header.manufacturer_id,
|
||||
image_type=fw_image.header.image_type,
|
||||
file_version=fw_image.header.file_version,
|
||||
file_offset=40,
|
||||
maximum_data_size=40,
|
||||
request_node_addr=zigpy_device.ieee,
|
||||
)
|
||||
)
|
||||
elif cmd.file_offset == 40:
|
||||
assert cmd.status == foundation.Status.SUCCESS
|
||||
assert cmd.manufacturer_code == fw_image.header.manufacturer_id
|
||||
assert cmd.image_type == fw_image.header.image_type
|
||||
assert cmd.file_version == fw_image.header.file_version
|
||||
assert cmd.file_offset == 40
|
||||
assert cmd.image_data == fw_image.serialize()[40:70]
|
||||
|
||||
# make sure the state machine gets progress reports
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
||||
attrs = state.attributes
|
||||
assert (
|
||||
attrs[ATTR_INSTALLED_VERSION] == f"0x{installed_fw_version:08x}"
|
||||
)
|
||||
assert attrs[ATTR_IN_PROGRESS] == 57
|
||||
assert (
|
||||
attrs[ATTR_LATEST_VERSION]
|
||||
== f"0x{fw_image.header.file_version:08x}"
|
||||
)
|
||||
|
||||
zigpy_device.packet_received(
|
||||
make_packet(
|
||||
zigpy_device,
|
||||
cluster,
|
||||
general.Ota.ServerCommandDefs.upgrade_end.name,
|
||||
status=foundation.Status.SUCCESS,
|
||||
manufacturer_code=fw_image.header.manufacturer_id,
|
||||
image_type=fw_image.header.image_type,
|
||||
file_version=fw_image.header.file_version,
|
||||
)
|
||||
)
|
||||
|
||||
elif isinstance(
|
||||
cmd, general.Ota.ClientCommandDefs.upgrade_end_response.schema
|
||||
):
|
||||
assert cmd.manufacturer_code == fw_image.header.manufacturer_id
|
||||
assert cmd.image_type == fw_image.header.image_type
|
||||
assert cmd.file_version == fw_image.header.file_version
|
||||
assert cmd.current_time == 0
|
||||
assert cmd.upgrade_time == 0
|
||||
|
||||
cluster.endpoint.reply = AsyncMock(side_effect=endpoint_reply)
|
||||
await hass.services.async_call(
|
||||
UPDATE_DOMAIN,
|
||||
SERVICE_INSTALL,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_OFF
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == f"0x{fw_image.header.file_version:08x}"
|
||||
assert not attrs[ATTR_IN_PROGRESS]
|
||||
assert attrs[ATTR_LATEST_VERSION] == attrs[ATTR_INSTALLED_VERSION]
|
||||
|
||||
|
||||
async def test_firmware_update_raises(
|
||||
hass: HomeAssistant, zha_device_joined_restored, zigpy_device
|
||||
) -> None:
|
||||
"""Test ZHA update platform - firmware update raises."""
|
||||
zha_device, cluster, fw_image, installed_fw_version = await setup_test_data(
|
||||
zha_device_joined_restored, zigpy_device
|
||||
)
|
||||
|
||||
entity_id = find_entity_id(Platform.UPDATE, zha_device, hass)
|
||||
assert entity_id is not None
|
||||
|
||||
# allow traffic to flow through the gateway and device
|
||||
await async_enable_traffic(hass, [zha_device])
|
||||
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
# simulate an image available notification
|
||||
await cluster._handle_query_next_image(
|
||||
fw_image.header.field_control,
|
||||
zha_device.manufacturer_code,
|
||||
fw_image.header.image_type,
|
||||
installed_fw_version,
|
||||
fw_image.header.header_version,
|
||||
tsn=15,
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == f"0x{installed_fw_version:08x}"
|
||||
assert not attrs[ATTR_IN_PROGRESS]
|
||||
assert attrs[ATTR_LATEST_VERSION] == f"0x{fw_image.header.file_version:08x}"
|
||||
|
||||
async def endpoint_reply(cluster_id, tsn, data, command_id):
|
||||
if cluster_id == general.Ota.cluster_id:
|
||||
hdr, cmd = cluster.deserialize(data)
|
||||
if isinstance(cmd, general.Ota.ImageNotifyCommand):
|
||||
zigpy_device.packet_received(
|
||||
make_packet(
|
||||
zigpy_device,
|
||||
cluster,
|
||||
general.Ota.ServerCommandDefs.query_next_image.name,
|
||||
field_control=general.Ota.QueryNextImageCommand.FieldControl.HardwareVersion,
|
||||
manufacturer_code=fw_image.header.manufacturer_id,
|
||||
image_type=fw_image.header.image_type,
|
||||
current_file_version=fw_image.header.file_version - 10,
|
||||
hardware_version=1,
|
||||
)
|
||||
)
|
||||
elif isinstance(
|
||||
cmd, general.Ota.ClientCommandDefs.query_next_image_response.schema
|
||||
):
|
||||
assert cmd.status == foundation.Status.SUCCESS
|
||||
assert cmd.manufacturer_code == fw_image.header.manufacturer_id
|
||||
assert cmd.image_type == fw_image.header.image_type
|
||||
assert cmd.file_version == fw_image.header.file_version
|
||||
assert cmd.image_size == fw_image.header.image_size
|
||||
raise DeliveryError("failed to deliver")
|
||||
|
||||
cluster.endpoint.reply = AsyncMock(side_effect=endpoint_reply)
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
UPDATE_DOMAIN,
|
||||
SERVICE_INSTALL,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
with patch(
|
||||
"zigpy.device.Device.update_firmware",
|
||||
AsyncMock(side_effect=DeliveryError("failed to deliver")),
|
||||
), pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
UPDATE_DOMAIN,
|
||||
SERVICE_INSTALL,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
async def test_firmware_update_restore_data(
|
||||
hass: HomeAssistant, zha_device_joined_restored, zigpy_device
|
||||
) -> None:
|
||||
"""Test ZHA update platform - restore data."""
|
||||
fw_version = 0x12345678
|
||||
installed_fw_version = fw_version - 10
|
||||
mock_restore_cache_with_extra_data(
|
||||
hass,
|
||||
[
|
||||
(
|
||||
State(
|
||||
"update.fakemanufacturer_fakemodel_firmware",
|
||||
STATE_ON,
|
||||
{
|
||||
ATTR_INSTALLED_VERSION: f"0x{installed_fw_version:08x}",
|
||||
ATTR_LATEST_VERSION: f"0x{fw_version:08x}",
|
||||
ATTR_SKIPPED_VERSION: None,
|
||||
},
|
||||
),
|
||||
{"image_type": 0x90},
|
||||
)
|
||||
],
|
||||
)
|
||||
zha_device, cluster, fw_image, installed_fw_version = await setup_test_data(
|
||||
zha_device_joined_restored, zigpy_device
|
||||
)
|
||||
|
||||
entity_id = find_entity_id(Platform.UPDATE, zha_device, hass)
|
||||
assert entity_id is not None
|
||||
|
||||
# allow traffic to flow through the gateway and device
|
||||
await async_enable_traffic(hass, [zha_device])
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == f"0x{installed_fw_version:08x}"
|
||||
assert not attrs[ATTR_IN_PROGRESS]
|
||||
assert attrs[ATTR_LATEST_VERSION] == f"0x{fw_image.header.file_version:08x}"
|
||||
|
||||
|
||||
async def test_firmware_update_restore_file_not_found(
|
||||
hass: HomeAssistant, zha_device_joined_restored, zigpy_device
|
||||
) -> None:
|
||||
"""Test ZHA update platform - restore data - file not found."""
|
||||
fw_version = 0x12345678
|
||||
installed_fw_version = fw_version - 10
|
||||
mock_restore_cache_with_extra_data(
|
||||
hass,
|
||||
[
|
||||
(
|
||||
State(
|
||||
"update.fakemanufacturer_fakemodel_firmware",
|
||||
STATE_ON,
|
||||
{
|
||||
ATTR_INSTALLED_VERSION: f"0x{installed_fw_version:08x}",
|
||||
ATTR_LATEST_VERSION: f"0x{fw_version:08x}",
|
||||
ATTR_SKIPPED_VERSION: None,
|
||||
},
|
||||
),
|
||||
{"image_type": 0x90},
|
||||
)
|
||||
],
|
||||
)
|
||||
zha_device, cluster, fw_image, installed_fw_version = await setup_test_data(
|
||||
zha_device_joined_restored, zigpy_device, file_not_found=True
|
||||
)
|
||||
|
||||
entity_id = find_entity_id(Platform.UPDATE, zha_device, hass)
|
||||
assert entity_id is not None
|
||||
|
||||
# allow traffic to flow through the gateway and device
|
||||
await async_enable_traffic(hass, [zha_device])
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_OFF
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == f"0x{installed_fw_version:08x}"
|
||||
assert not attrs[ATTR_IN_PROGRESS]
|
||||
assert attrs[ATTR_LATEST_VERSION] == f"0x{installed_fw_version:08x}"
|
||||
|
||||
|
||||
async def test_firmware_update_restore_version_from_state_machine(
|
||||
hass: HomeAssistant, zha_device_joined_restored, zigpy_device
|
||||
) -> None:
|
||||
"""Test ZHA update platform - restore data - file not found."""
|
||||
fw_version = 0x12345678
|
||||
installed_fw_version = fw_version - 10
|
||||
mock_restore_cache_with_extra_data(
|
||||
hass,
|
||||
[
|
||||
(
|
||||
State(
|
||||
"update.fakemanufacturer_fakemodel_firmware",
|
||||
STATE_ON,
|
||||
{
|
||||
ATTR_INSTALLED_VERSION: f"0x{installed_fw_version:08x}",
|
||||
ATTR_LATEST_VERSION: f"0x{fw_version:08x}",
|
||||
ATTR_SKIPPED_VERSION: None,
|
||||
},
|
||||
),
|
||||
{"image_type": 0x90},
|
||||
)
|
||||
],
|
||||
)
|
||||
zha_device, cluster, fw_image, installed_fw_version = await setup_test_data(
|
||||
zha_device_joined_restored,
|
||||
zigpy_device,
|
||||
skip_attribute_plugs=True,
|
||||
file_not_found=True,
|
||||
)
|
||||
|
||||
entity_id = find_entity_id(Platform.UPDATE, zha_device, hass)
|
||||
assert entity_id is not None
|
||||
|
||||
# allow traffic to flow through the gateway and device
|
||||
await async_enable_traffic(hass, [zha_device])
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_OFF
|
||||
attrs = state.attributes
|
||||
assert attrs[ATTR_INSTALLED_VERSION] == f"0x{installed_fw_version:08x}"
|
||||
assert not attrs[ATTR_IN_PROGRESS]
|
||||
assert attrs[ATTR_LATEST_VERSION] == f"0x{installed_fw_version:08x}"
|
|
@ -127,6 +127,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.bosch_isw_zpr1_wp13_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-5-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.bosch_isw_zpr1_wp13_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -165,6 +170,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.centralite_3130_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.centralite_3130_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -248,6 +258,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.centralite_3210_l_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.centralite_3210_l_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -296,6 +311,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Humidity",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.centralite_3310_s_humidity",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.centralite_3310_s_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -351,6 +371,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.centralite_3315_s_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.centralite_3315_s_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -406,6 +431,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.centralite_3320_l_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.centralite_3320_l_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -461,6 +491,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.centralite_3326_l_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.centralite_3326_l_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -523,6 +558,11 @@ DEVICES = [
|
|||
"binary_sensor.centralite_motion_sensor_a_occupancy"
|
||||
),
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.centralite_motion_sensor_a_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -593,6 +633,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.climaxtechnology_psmp5_00_00_02_02tc_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-4-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.climaxtechnology_psmp5_00_00_02_02tc_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -798,6 +843,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.heiman_smokesensor_em_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.heiman_smokesensor_em_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -836,6 +886,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.heiman_co_v16_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.heiman_co_v16_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -899,6 +954,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.heiman_warningdevice_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.heiman_warningdevice_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -952,6 +1012,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.hivehome_com_mot003_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-6-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.hivehome_com_mot003_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1005,6 +1070,11 @@ DEVICES = [
|
|||
"sensor.ikea_of_sweden_tradfri_bulb_e12_ws_opal_600lm_lqi"
|
||||
),
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_bulb_e12_ws_opal_600lm_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1051,6 +1121,11 @@ DEVICES = [
|
|||
"sensor.ikea_of_sweden_tradfri_bulb_e26_cws_opal_600lm_lqi"
|
||||
),
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_bulb_e26_cws_opal_600lm_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1097,6 +1172,11 @@ DEVICES = [
|
|||
"sensor.ikea_of_sweden_tradfri_bulb_e26_w_opal_1000lm_lqi"
|
||||
),
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_bulb_e26_w_opal_1000lm_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1143,6 +1223,11 @@ DEVICES = [
|
|||
"sensor.ikea_of_sweden_tradfri_bulb_e26_ws_opal_980lm_lqi"
|
||||
),
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_bulb_e26_ws_opal_980lm_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1189,6 +1274,11 @@ DEVICES = [
|
|||
"sensor.ikea_of_sweden_tradfri_bulb_e26_opal_1000lm_lqi"
|
||||
),
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_bulb_e26_opal_1000lm_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1231,6 +1321,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.ikea_of_sweden_tradfri_control_outlet_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_control_outlet_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1280,6 +1375,11 @@ DEVICES = [
|
|||
"binary_sensor.ikea_of_sweden_tradfri_motion_sensor_motion"
|
||||
),
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_motion_sensor_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1322,6 +1422,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.ikea_of_sweden_tradfri_on_off_switch_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_on_off_switch_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1364,6 +1469,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.ikea_of_sweden_tradfri_remote_control_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_remote_control_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1408,6 +1518,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.ikea_of_sweden_tradfri_signal_repeater_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_signal_repeater_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1452,6 +1567,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.ikea_of_sweden_tradfri_wireless_dimmer_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ikea_of_sweden_tradfri_wireless_dimmer_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1512,6 +1632,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.jasco_products_45852_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.jasco_products_45852_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1572,6 +1697,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.jasco_products_45856_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.jasco_products_45856_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1632,6 +1762,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.jasco_products_45857_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.jasco_products_45857_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1685,6 +1820,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.keen_home_inc_sv02_610_mp_1_3_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.keen_home_inc_sv02_610_mp_1_3_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1738,6 +1878,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.keen_home_inc_sv02_612_mp_1_2_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.keen_home_inc_sv02_612_mp_1_2_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1791,6 +1936,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.keen_home_inc_sv02_612_mp_1_3_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.keen_home_inc_sv02_612_mp_1_3_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1836,6 +1986,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "KofFan",
|
||||
DEV_SIG_ENT_MAP_ID: "fan.king_of_fans_inc_hbuniversalcfremote_fan",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.king_of_fans_inc_hbuniversalcfremote_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1874,6 +2029,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lds_zbt_cctswitch_d0001_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lds_zbt_cctswitch_d0001_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1912,6 +2072,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.ledvance_a19_rgbw_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ledvance_a19_rgbw_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1950,6 +2115,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.ledvance_flex_rgbw_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ledvance_flex_rgbw_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1988,6 +2158,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.ledvance_plug_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ledvance_plug_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2026,6 +2201,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.ledvance_rt_rgbw_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.ledvance_rt_rgbw_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2110,6 +2290,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_plug_maus01_summation_delivered",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_plug_maus01_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2210,6 +2395,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Light",
|
||||
DEV_SIG_ENT_MAP_ID: "light.lumi_lumi_relay_c2acn01_light_2",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_relay_c2acn01_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2262,6 +2452,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_remote_b186acn01_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_remote_b186acn01_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2314,6 +2509,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_remote_b286acn01_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_remote_b286acn01_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2780,6 +2980,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_sensor_86sw1_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_sensor_86sw1_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2832,6 +3037,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_sensor_cube_aqgl01_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_sensor_cube_aqgl01_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2894,6 +3104,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Humidity",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_sensor_ht_humidity",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_sensor_ht_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2937,6 +3152,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Opening",
|
||||
DEV_SIG_ENT_MAP_ID: "binary_sensor.lumi_lumi_sensor_magnet_opening",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_sensor_magnet_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3042,6 +3262,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_sensor_motion_aq2_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_sensor_motion_aq2_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3092,6 +3317,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_sensor_smoke_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_sensor_smoke_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3130,6 +3360,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_sensor_switch_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_sensor_switch_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3246,6 +3481,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_sensor_wleak_aq1_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_sensor_wleak_aq1_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3316,6 +3556,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "DeviceTemperature",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_vibration_aq1_device_temperature",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.lumi_lumi_vibration_aq1_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3534,6 +3779,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.osram_lightify_a19_rgbw_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-3-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.osram_lightify_a19_rgbw_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3572,6 +3822,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.osram_lightify_dimming_switch_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.osram_lightify_dimming_switch_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3610,6 +3865,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.osram_lightify_flex_rgbw_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-3-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.osram_lightify_flex_rgbw_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3684,6 +3944,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.osram_lightify_rt_tunable_white_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-3-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.osram_lightify_rt_tunable_white_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3722,6 +3987,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.osram_plug_01_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-3-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.osram_plug_01_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3816,6 +4086,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.osram_switch_4x_lightify_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.osram_switch_4x_lightify_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3866,6 +4141,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Battery",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.philips_rwl020_battery",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-2-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.philips_rwl020_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3914,6 +4194,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.samjin_button_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.samjin_button_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3967,6 +4252,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.samjin_multi_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.samjin_multi_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4015,6 +4305,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.samjin_water_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.samjin_water_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4083,6 +4378,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Switch",
|
||||
DEV_SIG_ENT_MAP_ID: "switch.securifi_ltd_unk_model_switch",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.securifi_ltd_unk_model_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4131,6 +4431,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.sercomm_corp_sz_dws04n_sf_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.sercomm_corp_sz_dws04n_sf_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4221,6 +4526,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.sercomm_corp_sz_esw01_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.sercomm_corp_sz_esw01_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4274,6 +4584,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.sercomm_corp_sz_pir04_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.sercomm_corp_sz_pir04_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4344,6 +4659,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Switch",
|
||||
DEV_SIG_ENT_MAP_ID: "switch.sinope_technologies_rm3250zb_switch",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.sinope_technologies_rm3250zb_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4444,6 +4764,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "SetpointChangeSource",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.sinope_technologies_th1123zb_setpoint_change_source",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.sinope_technologies_th1123zb_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4544,6 +4869,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "SetpointChangeSource",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.sinope_technologies_th1124zb_setpoint_change_source",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.sinope_technologies_th1124zb_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4617,6 +4947,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Switch",
|
||||
DEV_SIG_ENT_MAP_ID: "switch.smartthings_outletv4_switch",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.smartthings_outletv4_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4660,6 +4995,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.smartthings_tagv4_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.smartthings_tagv4_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4698,6 +5038,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Switch",
|
||||
DEV_SIG_ENT_MAP_ID: "switch.third_reality_inc_3rss007z_switch",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.third_reality_inc_3rss007z_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4741,6 +5086,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Switch",
|
||||
DEV_SIG_ENT_MAP_ID: "switch.third_reality_inc_3rss008z_switch",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.third_reality_inc_3rss008z_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4789,6 +5139,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.visonic_mct_340_e_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.visonic_mct_340_e_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4847,6 +5202,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "SetpointChangeSource",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.zen_within_zen_01_setpoint_change_source",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.zen_within_zen_01_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -4916,6 +5276,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "Light",
|
||||
DEV_SIG_ENT_MAP_ID: "light.tyzb01_ns1ndbww_ts0004_light_4",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.tyzb01_ns1ndbww_ts0004_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -5012,6 +5377,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.sengled_e11_g13_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.sengled_e11_g13_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -5065,6 +5435,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.sengled_e12_n14_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.sengled_e12_n14_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -5118,6 +5493,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "LQISensor",
|
||||
DEV_SIG_ENT_MAP_ID: "sensor.sengled_z01_a19nae26_lqi",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-1-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.sengled_z01_a19nae26_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -5584,6 +5964,11 @@ DEVICES = [
|
|||
DEV_SIG_ENT_MAP_CLASS: "HueV1MotionSensitivity",
|
||||
DEV_SIG_ENT_MAP_ID: "select.philips_sml001_motion_sensitivity",
|
||||
},
|
||||
("update", "00:11:22:33:44:55:66:77-2-25-firmware_update"): {
|
||||
DEV_SIG_CLUSTER_HANDLERS: ["ota"],
|
||||
DEV_SIG_ENT_MAP_CLASS: "ZHAFirmwareUpdateEntity",
|
||||
DEV_SIG_ENT_MAP_ID: "update.philips_sml001_firmware",
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
|
Loading…
Add table
Reference in a new issue