diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f14dcb8db0c54c..cc55aa550b070c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -55,10 +55,12 @@ env: # and some queries that work on MariaDB do not work on MySQL MARIADB_VERSIONS: "['mariadb:10.3.32','mariadb:10.6.10','mariadb:10.10.3','mariadb:10.11.2','mariadb:11.4.9','mysql:8.0.32']" # 12 is the oldest supported version - # - 12.14 is the latest (as of 9 Feb 2023) - # 15 is the latest version - # - 15.2 is the latest (as of 9 Feb 2023) - POSTGRESQL_VERSIONS: "['postgres:12.14','postgres:15.2']" + # - 12.22 is the latest (as of 19 Aug 2026) + # 15 is a supported version + # - 15.19 is the latest (as of 19 Aug 2026) + # 18 is the latest version + # - 18.6 is the latest (as of 19 Aug 2026) + POSTGRESQL_VERSIONS: "['postgres:12.22','postgres:15.19', 'postgres:18.6']" UV_CACHE_DIR: /tmp/uv-cache APT_CACHE_VERSION: 1 SQLALCHEMY_WARN_20: 1 @@ -1064,6 +1066,9 @@ jobs: - 5432:5432 env: POSTGRES_PASSWORD: password + # 18+ images default PGDATA to /var/lib/postgresql//docker, + # which is not covered by the tmpfs below + PGDATA: /var/lib/postgresql/data options: >- --health-cmd="pg_isready -hlocalhost -Upostgres" --health-interval=5s --health-timeout=2s --health-retries=3 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index afc6f0245eb1f0..995fbd4b2d7d7c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -28,11 +28,11 @@ jobs: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: languages: python - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: category: "/language:python" diff --git a/homeassistant/components/actron_air/__init__.py b/homeassistant/components/actron_air/__init__.py index ee362231efce7a..0a28550741cc0d 100644 --- a/homeassistant/components/actron_air/__init__.py +++ b/homeassistant/components/actron_air/__init__.py @@ -7,6 +7,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.helpers import device_registry as dr +from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import DOMAIN, LOGGER from .coordinator import ( @@ -27,7 +28,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ActronAirConfigEntry) -> bool: """Set up Actron Air integration from a config entry.""" - api = ActronAirAPI(refresh_token=entry.data[CONF_API_TOKEN]) + api = ActronAirAPI( + refresh_token=entry.data[CONF_API_TOKEN], + session=async_get_clientsession(hass), + ) systems: list[ActronAirSystemInfo] = [] try: diff --git a/homeassistant/components/actron_air/config_flow.py b/homeassistant/components/actron_air/config_flow.py index d0c91ba017d57f..c3616a09370bd8 100644 --- a/homeassistant/components/actron_air/config_flow.py +++ b/homeassistant/components/actron_air/config_flow.py @@ -14,6 +14,7 @@ ) from homeassistant.const import CONF_API_TOKEN from homeassistant.exceptions import HomeAssistantError +from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import DOMAIN, LOGGER @@ -37,7 +38,7 @@ async def async_step_user( """Handle the initial step.""" if self._api is None: LOGGER.debug("Initiating device authorization") - self._api = ActronAirAPI() + self._api = ActronAirAPI(session=async_get_clientsession(self.hass)) try: device_code_response = await self._api.request_device_code() except ActronAirAuthError as err: diff --git a/homeassistant/components/actron_air/quality_scale.yaml b/homeassistant/components/actron_air/quality_scale.yaml index cb8dbad465e095..b3ca9c7f02bb59 100644 --- a/homeassistant/components/actron_air/quality_scale.yaml +++ b/homeassistant/components/actron_air/quality_scale.yaml @@ -74,5 +74,5 @@ rules: # Platinum async-dependency: done - inject-websession: todo + inject-websession: done strict-typing: done diff --git a/homeassistant/components/androidtv_remote/remote.py b/homeassistant/components/androidtv_remote/remote.py index 7ecf4b3edf665d..8a22a3fbccfc23 100644 --- a/homeassistant/components/androidtv_remote/remote.py +++ b/homeassistant/components/androidtv_remote/remote.py @@ -2,7 +2,7 @@ import asyncio from collections.abc import Iterable -from typing import Any, override +from typing import Any, Final, override from homeassistant.components.remote import ( ATTR_ACTIVITY, @@ -16,14 +16,35 @@ RemoteEntityFeature, ) from homeassistant.core import HomeAssistant, callback +from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import CONF_APP_NAME +from .const import CONF_APP_NAME, DOMAIN from .entity import AndroidTVRemoteBaseEntity from .helpers import AndroidTVRemoteConfigEntry PARALLEL_UPDATES = 0 +PREFIX_SEPARATOR: Final[str] = ":" +# Only direction prefixes are stripped; other colon conventions (e.g. text:) pass through to the library unchanged. +VALID_PREFIXES: Final[frozenset[str]] = frozenset( + { + "SHORT", + "START_LONG", + "END_LONG", + } +) + + +def _parse_command(single_command: str) -> tuple[str, str | None]: + """Split an optional prefix from the key code.""" + prefix, separator, rest = single_command.partition(PREFIX_SEPARATOR) + if separator: + normalized = prefix.upper() + if normalized in VALID_PREFIXES: + return rest, normalized + return single_command, None + async def async_setup_entry( hass: HomeAssistant, @@ -105,10 +126,24 @@ async def async_send_command(self, command: Iterable[str], **kwargs: Any) -> Non for _ in range(num_repeats): for single_command in command: + key_code, direction = _parse_command(single_command) + if direction is not None: + if not key_code: + raise ServiceValidationError( + translation_domain=DOMAIN, + translation_key="empty_key_code", + translation_placeholders={"command": single_command}, + ) + if hold_secs: + raise ServiceValidationError( + translation_domain=DOMAIN, + translation_key="direction_prefix_with_hold_secs", + translation_placeholders={"command": single_command}, + ) if hold_secs: - self._send_key_command(single_command, "START_LONG") + self._send_key_command(key_code, "START_LONG") await asyncio.sleep(hold_secs) - self._send_key_command(single_command, "END_LONG") + self._send_key_command(key_code, "END_LONG") else: - self._send_key_command(single_command, "SHORT") + self._send_key_command(key_code, direction or "SHORT") await asyncio.sleep(delay_secs) diff --git a/homeassistant/components/androidtv_remote/strings.json b/homeassistant/components/androidtv_remote/strings.json index e1d768f0adc49e..e71f0ed7644b75 100644 --- a/homeassistant/components/androidtv_remote/strings.json +++ b/homeassistant/components/androidtv_remote/strings.json @@ -56,6 +56,12 @@ "connection_closed": { "message": "Connection to the Android TV device is closed" }, + "direction_prefix_with_hold_secs": { + "message": "Command \"{command}\" combines a direction prefix with hold_secs; specify only one" + }, + "empty_key_code": { + "message": "Command \"{command}\" is missing a key code after the direction prefix" + }, "invalid_channel": { "message": "Channel must be numeric: {media_id}" }, diff --git a/homeassistant/components/deconz/logbook.py b/homeassistant/components/deconz/logbook.py index 2ce0f45af98cae..77690bf337238a 100644 --- a/homeassistant/components/deconz/logbook.py +++ b/homeassistant/components/deconz/logbook.py @@ -137,7 +137,9 @@ def async_describe_events( @callback def async_describe_deconz_alarm_event(event: Event) -> dict[str, str]: """Describe deCONZ logbook alarm event.""" - if device := device_registry.devices.get(event.data[ATTR_DEVICE_ID]): + if device := device_registry.async_get( + event.data[ATTR_DEVICE_ID], include_child_devices=False + ): deconz_alarm_event = _get_deconz_event_from_device(hass, device) name = deconz_alarm_event.device.name else: @@ -153,7 +155,9 @@ def async_describe_deconz_alarm_event(event: Event) -> dict[str, str]: @callback def async_describe_deconz_event(event: Event) -> dict[str, str]: """Describe deCONZ logbook event.""" - if device := device_registry.devices.get(event.data[ATTR_DEVICE_ID]): + if device := device_registry.async_get( + event.data[ATTR_DEVICE_ID], include_child_devices=False + ): deconz_event = _get_deconz_event_from_device(hass, device) name = deconz_event.device.name else: diff --git a/homeassistant/components/hassio/coordinator.py b/homeassistant/components/hassio/coordinator.py index f5115c7f7e3aed..aa5c99dc9d0560 100644 --- a/homeassistant/components/hassio/coordinator.py +++ b/homeassistant/components/hassio/coordinator.py @@ -40,7 +40,7 @@ callback, is_callback_check_partial, ) -from homeassistant.helpers import device_registry as dr +from homeassistant.helpers import device_registry as dr, issue_registry as ir from homeassistant.helpers.debounce import Debouncer from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -399,16 +399,28 @@ def _process_issue_deltas( current_data: SupervisorIssuesData, ) -> None: """Create/delete issue repairs and notify subscribers based on issue deltas.""" + issue_registry = ir.async_get(self.hass) for issue in current_data.issues.values(): previous_issue = previous_data.issues.get(issue.uuid) - if previous_issue is not None and self._issue_equal(previous_issue, issue): - continue - - self._create_or_update_issue_repair(issue) - self._process_issue_change( - IssueSubscriptionEvent(event="changed", issue=issue) + changed = previous_issue is None or not self._issue_equal( + previous_issue, issue ) + # Update the repair on changes, and re-create it if the registry + # entry went missing: a finished repair flow deletes the entry + # even when applying the suggestion failed in Supervisor and the + # issue is unchanged. + if changed or ( + issue.key in ISSUE_KEYS_FOR_REPAIRS + and not issue_registry.async_get_issue(DOMAIN, issue.uuid.hex) + ): + self._create_or_update_issue_repair(issue) + + if changed: + self._process_issue_change( + IssueSubscriptionEvent(event="changed", issue=issue) + ) + for issue_uuid, issue in previous_data.issues.items(): if issue_uuid not in current_data.issues: self._delete_issue_repair(issue) diff --git a/homeassistant/components/hassio/repairs.py b/homeassistant/components/hassio/repairs.py index 55b43f3fa08d9e..f76ee362de42a7 100644 --- a/homeassistant/components/hassio/repairs.py +++ b/homeassistant/components/hassio/repairs.py @@ -41,6 +41,7 @@ SUGGESTION_CONFIRMATION_REQUIRED = { "addon_execute_remove", + "mount_move_local_data", "system_adopt_data_disk", "system_execute_reboot", } diff --git a/homeassistant/components/hassio/strings.json b/homeassistant/components/hassio/strings.json index 213215822b660c..9c05ad0a6e30b5 100644 --- a/homeassistant/components/hassio/strings.json +++ b/homeassistant/components/hassio/strings.json @@ -152,11 +152,15 @@ }, "step": { "fix_menu": { - "description": "Could not connect to `{reference}`. Check host logs for errors from the mount service for more details.\n\nUse reload to try to connect again. If you need to update `{reference}`, go to [storage]({storage_url}).", + "description": "Could not set up `{reference}`. This can happen when the storage device is unreachable, or when local data is blocking the mount location. Check host logs for errors from the mount service for more details.\n\nUse reload to try again. If you need to update `{reference}`, go to [storage]({storage_url}).", "menu_options": { "mount_execute_reload": "[%key:common::action::reload%]", - "mount_execute_remove": "Remove" + "mount_execute_remove": "Remove", + "mount_move_local_data": "Move blocking local data away" } + }, + "mount_move_local_data": { + "description": "Select **Submit** to move the local data blocking `{reference}` to a `{reference}_local_recovery` folder and set up the mount again.\n\nNo files are deleted. For media and share mounts the recovery folder is created next to the mount, where you can review and remove it. For backup mounts it is placed in local backup storage." } } }, diff --git a/homeassistant/components/homeassistant/triggers/event.py b/homeassistant/components/homeassistant/triggers/event.py index 7f45f19862b557..010f20a0c5a46c 100644 --- a/homeassistant/components/homeassistant/triggers/event.py +++ b/homeassistant/components/homeassistant/triggers/event.py @@ -1,16 +1,29 @@ """Offer event listening automation rules.""" from collections.abc import ItemsView, Mapping +import logging from typing import Any import voluptuous as vol -from homeassistant.const import CONF_EVENT_DATA, CONF_PLATFORM, EVENT_STATE_REPORTED +from homeassistant.const import ( + CONF_DEVICE_ID, + CONF_EVENT_DATA, + CONF_PLATFORM, + EVENT_STATE_REPORTED, +) from homeassistant.core import CALLBACK_TYPE, Event, HassJob, HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers import config_validation as cv, template +from homeassistant.helpers import ( + config_validation as cv, + device_registry as dr, + template, +) from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo from homeassistant.helpers.typing import ConfigType +from homeassistant.util import yaml as yaml_util + +_LOGGER = logging.getLogger(__name__) CONF_EVENT_TYPE = "event_type" CONF_EVENT_CONTEXT = "context" @@ -39,6 +52,58 @@ def _validate_event_types(value: Any) -> Any: ) +async def async_validate_trigger_config( + hass: HomeAssistant, config: ConfigType +) -> ConfigType: + """Validate trigger config. + + Warn if the trigger filters event_data.device_id on a pre-migration composite device + id - a device that was split into one device per config entry. + A templated device id is a Template (not a plain string) and is left alone. + """ + validated_config: ConfigType = TRIGGER_SCHEMA(config) + if ( + CONF_EVENT_DATA in validated_config + and isinstance( + device_id := validated_config[CONF_EVENT_DATA].get(CONF_DEVICE_ID), str + ) + and ( + split_devices := dr.async_get( + hass + ).async_get_devices_for_composite_device_id(device_id) + ) + ): + _log_composite_device_id_warning(hass, config, device_id, split_devices) + return validated_config + + +@callback +def _log_composite_device_id_warning( + hass: HomeAssistant, + config: ConfigType, + device_id: str, + split_devices: list[dr.DeviceEntry], +) -> None: + """Warn that an event trigger filters on a split (pre-migration) device id.""" + + device_summaries: list[str] = [] + for device in split_devices: + entry = hass.config_entries.async_get_entry(device.config_entry_id) + domain = entry.domain if entry else "unknown" + name = device.name_by_user or device.name or device.id + device_summaries.append(f"{name} ({device.id}) from the {domain} integration") + + _LOGGER.warning( + "Event trigger filters on device '%s', which was split into one device per " + "integration and no longer exists, so the trigger can no longer fire. Update the " + "automation, script or template entity to filter on one of these devices instead: " + "%s.\nThe affected trigger is configured as:\n%s", + device_id, + ", ".join(device_summaries), + yaml_util.dump(config), + ) + + def _schema_value(value: Any) -> Any: if isinstance(value, list): return vol.In(value) diff --git a/homeassistant/components/homekit/__init__.py b/homeassistant/components/homekit/__init__.py index cbf0fb0e9a515f..38f206d3641263 100644 --- a/homeassistant/components/homekit/__init__.py +++ b/homeassistant/components/homekit/__init__.py @@ -1231,7 +1231,9 @@ async def _async_set_device_info_attributes( dev_reg_ent = dev_reg.async_get(ent_reg_ent.device_id) if isinstance(dev_reg_ent, dr.ChildDeviceEntry): # A child device has no hardware info of its own; use the parent's - dev_reg_ent = dev_reg.devices.get(dev_reg_ent.parent_device_id) + dev_reg_ent = dev_reg.async_get( + dev_reg_ent.parent_device_id, include_child_devices=False + ) if dev_reg_ent is not None: self._fill_config_from_device_registry_entry(dev_reg_ent, ent_cfg) if ATTR_MANUFACTURER not in ent_cfg: diff --git a/homeassistant/components/http/ban.py b/homeassistant/components/http/ban.py index a21499f613ae81..d85ded19b016e3 100644 --- a/homeassistant/components/http/ban.py +++ b/homeassistant/components/http/ban.py @@ -46,7 +46,7 @@ ATTR_BANNED_AT: Final = "banned_at" SCHEMA_IP_BAN_ENTRY: Final = vol.Schema( - {vol.Optional("banned_at"): vol.Any(None, cv.datetime)} + {vol.Optional(ATTR_BANNED_AT, default=None): vol.Any(None, cv.datetime)} ) diff --git a/homeassistant/components/lunatone/__init__.py b/homeassistant/components/lunatone/__init__.py index dde1f64bb4e382..e6d8d6bde5e202 100644 --- a/homeassistant/components/lunatone/__init__.py +++ b/homeassistant/components/lunatone/__init__.py @@ -81,21 +81,18 @@ async def _update_unique_id( async def async_setup_entry(hass: HomeAssistant, entry: LunatoneConfigEntry) -> bool: """Set up Lunatone from a config entry.""" auth_api = Auth(async_get_clientsession(hass), entry.data[CONF_URL]) - info_api = Info(auth_api) - dali_scan_api = DALIScan(auth_api) - devices_api = Devices(info_api) - sensors_api = Sensors(auth_api) + info_api = Info(auth_api) coordinator_info = LunatoneInfoDataUpdateCoordinator(hass, entry, info_api) await coordinator_info.async_config_entry_first_refresh() - if info_api.data is None or info_api.serial_number is None: + if info_api.data is None: raise ConfigEntryError( translation_domain=DOMAIN, translation_key="missing_device_info" ) - if info_api.uid is not None: - new_unique_id = info_api.uid.replace("-", "") + if info_api.data.uid is not None: + new_unique_id = info_api.data.uid.replace("-", "") if new_unique_id != entry.unique_id: await _update_unique_id(hass, entry, new_unique_id) @@ -105,24 +102,27 @@ async def async_setup_entry(hass: HomeAssistant, entry: LunatoneConfigEntry) -> device_registry.async_get_or_create( config_entry_id=entry.entry_id, identifiers={(DOMAIN, entry.unique_id)}, - name=info_api.name, + name=info_api.data.name, manufacturer=MANUFACTURER, - sw_version=info_api.version, + sw_version=info_api.data.version, hw_version=coordinator_info.data.device.pcb, configuration_url=entry.data[CONF_URL], - serial_number=str(info_api.serial_number), - model=info_api.product_name, + serial_number=str(info_api.data.device.serial), + model=info_api.data.product_name, model_id=( - f"{coordinator_info.data.device.article_number}{coordinator_info.data.device.article_info}" + f"{coordinator_info.data.device.article_number}{coordinator_info.data.article_suffix}" ), ) + devices_api = Devices(auth_api, info_api.data.version) coordinator_devices = LunatoneDevicesDataUpdateCoordinator(hass, entry, devices_api) await coordinator_devices.async_config_entry_first_refresh() + sensors_api = Sensors(auth_api) coordinator_sensors = LunatoneSensorsDataUpdateCoordinator(hass, entry, sensors_api) await coordinator_sensors.async_config_entry_first_refresh() + dali_scan_api = DALIScan(auth_api) coordinator_scan = LunatoneScanDataUpdateCoordinator(hass, entry, dali_scan_api) await coordinator_scan.async_config_entry_first_refresh() diff --git a/homeassistant/components/lunatone/binary_sensor.py b/homeassistant/components/lunatone/binary_sensor.py index c05ef6cc616274..5b9d51bd4415de 100644 --- a/homeassistant/components/lunatone/binary_sensor.py +++ b/homeassistant/components/lunatone/binary_sensor.py @@ -62,4 +62,4 @@ def __init__( @override def is_on(self) -> bool: """Return true if the DALI scan is on.""" - return self.coordinator.dali_scan_api.is_busy + return self.coordinator.data.busy diff --git a/homeassistant/components/lunatone/config_flow.py b/homeassistant/components/lunatone/config_flow.py index 8f74ed828d3e07..88f54701e4efd5 100644 --- a/homeassistant/components/lunatone/config_flow.py +++ b/homeassistant/components/lunatone/config_flow.py @@ -56,12 +56,12 @@ async def async_step_user( except aiohttp.ClientConnectionError: errors["base"] = "cannot_connect" else: - if info_api.serial_number is None: + if info_api.data is None: errors["base"] = "missing_device_info" else: - unique_id = str(info_api.serial_number) - if info_api.uid is not None: - unique_id = info_api.uid.replace("-", "") + unique_id = str(info_api.data.device.serial) + if info_api.data.uid is not None: + unique_id = info_api.data.uid.replace("-", "") await self.async_set_unique_id(unique_id) if self.source == SOURCE_RECONFIGURE: self._abort_if_unique_id_mismatch() diff --git a/homeassistant/components/lunatone/coordinator.py b/homeassistant/components/lunatone/coordinator.py index 6170309d09110e..0583e3511a410d 100644 --- a/homeassistant/components/lunatone/coordinator.py +++ b/homeassistant/components/lunatone/coordinator.py @@ -113,7 +113,7 @@ async def _async_update_data(self) -> dict[int, Device]: if self.devices_api.data is None: raise UpdateFailed("Did not receive devices data from Lunatone REST API") - return {device.id: device for device in self.devices_api.devices} + return {device.data.id: device for device in self.devices_api.devices} class LunatoneSensorsDataUpdateCoordinator(DataUpdateCoordinator[dict[int, Sensor]]): @@ -151,7 +151,7 @@ async def _async_update_data(self) -> dict[int, Sensor]: if self.sensors_api.data is None: raise UpdateFailed("Did not receive sensors data from Lunatone REST API") - return {sensor.id: sensor for sensor in self.sensors_api.sensors} + return {sensor.data.id: sensor for sensor in self.sensors_api.sensors} class LunatoneScanDataUpdateCoordinator(DataUpdateCoordinator[ScanData]): @@ -190,7 +190,7 @@ async def _async_update_data(self) -> ScanData: raise UpdateFailed("Did not receive scan data from Lunatone REST API") update_interval = DEFAULT_SCAN_UPDATE_INTERVAL - if self.dali_scan_api.is_busy: + if self.dali_scan_api.data.busy: update_interval = timedelta(seconds=1) self.update_interval = update_interval diff --git a/homeassistant/components/lunatone/light.py b/homeassistant/components/lunatone/light.py index 80f7fedd311ed0..fefa30226646c4 100644 --- a/homeassistant/components/lunatone/light.py +++ b/homeassistant/components/lunatone/light.py @@ -97,7 +97,7 @@ def device_info(self) -> DeviceInfo: assert self.unique_id return DeviceInfo( identifiers={(DOMAIN, self.unique_id)}, - name=self._device.name, + name=self._device.data.name, via_device_id=dr.async_get_device_id_by_identifier( self.hass, ( diff --git a/homeassistant/components/lunatone/manifest.json b/homeassistant/components/lunatone/manifest.json index 3fee384abde538..46fe5cac31051a 100644 --- a/homeassistant/components/lunatone/manifest.json +++ b/homeassistant/components/lunatone/manifest.json @@ -7,7 +7,7 @@ "integration_type": "hub", "iot_class": "local_polling", "quality_scale": "silver", - "requirements": ["lunatone-rest-api-client==0.9.2"], + "requirements": ["lunatone-rest-api-client==0.10.0"], "zeroconf": [ { "properties": { diff --git a/homeassistant/components/lunatone/sensor.py b/homeassistant/components/lunatone/sensor.py index 0335a848c1e30a..7ec5903e52af57 100644 --- a/homeassistant/components/lunatone/sensor.py +++ b/homeassistant/components/lunatone/sensor.py @@ -112,7 +112,7 @@ def __init__( self._config_entry_unique_id = config_entry_unique_id self._sensor_id = sensor_id - self._attr_name = self.sensor.name + self._attr_name = self.sensor.data.name self._attr_unique_id = ( f"{config_entry_unique_id}-sensor{sensor_id}-{description.key}" ) diff --git a/homeassistant/components/lyngdorf/diagnostics.py b/homeassistant/components/lyngdorf/diagnostics.py index b46987114525ad..701bdfa9c6ef65 100644 --- a/homeassistant/components/lyngdorf/diagnostics.py +++ b/homeassistant/components/lyngdorf/diagnostics.py @@ -59,7 +59,7 @@ async def async_get_config_entry_diagnostics( state: dict[str, Any] = { "connected": receiver.connected, - "model": receiver.model.name if receiver.model else None, + "model": receiver.model.name, "power_on": receiver.power_on, "volume": receiver.volume, "max_volume": receiver.max_volume, diff --git a/homeassistant/components/lyngdorf/media_player.py b/homeassistant/components/lyngdorf/media_player.py index fa0315329d4702..1c3fa481660013 100644 --- a/homeassistant/components/lyngdorf/media_player.py +++ b/homeassistant/components/lyngdorf/media_player.py @@ -1,8 +1,9 @@ """Media player platform for Lyngdorf integration.""" -from typing import override +from typing import TYPE_CHECKING, override from lyngdorf.device import Receiver +from lyngdorf.models.base import NumericRange from homeassistant.components.media_player import ( MediaPlayerDeviceClass, @@ -19,10 +20,6 @@ PARALLEL_UPDATES = 1 -MAX_VOLUME_DB = 18.0 -MIN_VOLUME_DB = -80.0 -VOLUME_RANGE = MAX_VOLUME_DB - MIN_VOLUME_DB - FEATURES_ZONE_B = ( MediaPlayerEntityFeature.VOLUME_STEP | MediaPlayerEntityFeature.VOLUME_SET @@ -66,16 +63,17 @@ async def async_setup_entry( async_add_entities(entities) -def _to_ha_volume(volume_db: float) -> float: +def _to_ha_volume(volume_db: float, volume_range: NumericRange) -> float: """Convert Lyngdorf dB volume to HA 0..1 scale, clamped to 0..1.""" - volume = (volume_db - MIN_VOLUME_DB) / VOLUME_RANGE - return max(0.0, min(volume, 1.0)) + span = volume_range.max - volume_range.min + return max(0.0, min((volume_db - volume_range.min) / span, 1.0)) -def _to_lyngdorf_volume(volume: float) -> float: +def _to_lyngdorf_volume(volume: float, volume_range: NumericRange) -> float: """Convert HA 0..1 volume to Lyngdorf dB scale, clamped to min and max.""" - volume_db = volume * VOLUME_RANGE + MIN_VOLUME_DB - return max(MIN_VOLUME_DB, min(volume_db, MAX_VOLUME_DB)) + span = volume_range.max - volume_range.min + volume_db = volume * span + volume_range.min + return max(volume_range.min, min(volume_db, volume_range.max)) class LyngdorfDevice(LyngdorfEntity, MediaPlayerEntity): @@ -133,13 +131,22 @@ def is_volume_muted(self) -> bool | None: """Return boolean if volume is currently muted.""" return self._receiver.zone_b_mute_enabled + @property + def _volume_range(self) -> NumericRange: + """Return the model's documented Zone B volume range.""" + volume_range = self._receiver.zone_b_volume_range + # This entity is only created for models that have a Zone B. + if TYPE_CHECKING: + assert volume_range is not None + return volume_range + @override @property def volume_level(self) -> float | None: """Volume level of the media player (0..1).""" - if not isinstance(self._receiver.zone_b_volume, float): + if (volume := self._receiver.zone_b_volume) is None: return None - return _to_ha_volume(self._receiver.zone_b_volume) + return _to_ha_volume(volume, self._volume_range) @override async def async_turn_on(self) -> None: @@ -164,7 +171,9 @@ async def async_volume_down(self) -> None: @override async def async_set_volume_level(self, volume: float) -> None: """Set volume level, range 0..1.""" - self._receiver.zone_b_volume = _to_lyngdorf_volume(volume) + self._receiver.set_zone_b_volume( + _to_lyngdorf_volume(volume, self._volume_range) + ) @override async def async_mute_volume(self, mute: bool) -> None: @@ -234,13 +243,22 @@ def is_volume_muted(self) -> bool | None: """Return boolean if volume is currently muted.""" return self._receiver.mute_enabled + @property + def _volume_range(self) -> NumericRange: + """Return the model's documented main-zone volume range.""" + volume_range = self._receiver.volume_range + # Every supported model documents a main-zone volume range. + if TYPE_CHECKING: + assert volume_range is not None + return volume_range + @override @property def volume_level(self) -> float | None: """Volume level of the media player (0..1).""" - if not isinstance(self._receiver.volume, float): + if (volume := self._receiver.volume) is None: return None - return _to_ha_volume(self._receiver.volume) + return _to_ha_volume(volume, self._volume_range) @override @property @@ -277,7 +295,7 @@ async def async_volume_down(self) -> None: @override async def async_set_volume_level(self, volume: float) -> None: """Set volume level, range 0..1.""" - self._receiver.volume = _to_lyngdorf_volume(volume) + self._receiver.set_volume(_to_lyngdorf_volume(volume, self._volume_range)) @override async def async_mute_volume(self, mute: bool) -> None: diff --git a/homeassistant/components/monzo/sensor.py b/homeassistant/components/monzo/sensor.py index 9f9290157b2a31..dbf785f412d30b 100644 --- a/homeassistant/components/monzo/sensor.py +++ b/homeassistant/components/monzo/sensor.py @@ -41,6 +41,13 @@ class MonzoSensorEntityDescription(SensorEntityDescription): device_class=SensorDeviceClass.MONETARY, suggested_display_precision=2, ), + MonzoSensorEntityDescription( + key="spend_today", + translation_key="spend_today", + value_fn=lambda data: abs(data["balance"]["spend_today"]) / 100, + device_class=SensorDeviceClass.MONETARY, + suggested_display_precision=2, + ), ) POT_SENSORS = ( diff --git a/homeassistant/components/monzo/strings.json b/homeassistant/components/monzo/strings.json index 9aecc53fa2dae5..99616320ce0068 100644 --- a/homeassistant/components/monzo/strings.json +++ b/homeassistant/components/monzo/strings.json @@ -57,6 +57,9 @@ "pot_balance": { "name": "[%key:component::monzo::entity::sensor::balance::name%]" }, + "spend_today": { + "name": "Spent today" + }, "total_balance": { "name": "Total balance" } diff --git a/homeassistant/components/netatmo/light.py b/homeassistant/components/netatmo/light.py index 2e84133e17074e..1c977cbfaf888e 100644 --- a/homeassistant/components/netatmo/light.py +++ b/homeassistant/components/netatmo/light.py @@ -183,6 +183,7 @@ async def async_turn_on(self, **kwargs: Any) -> None: await self.device.async_set_brightness( round(kwargs[ATTR_BRIGHTNESS] / 2.55) ) + self._attr_brightness = kwargs[ATTR_BRIGHTNESS] else: await self.device.async_on() diff --git a/homeassistant/components/nfandroidtv/notify.py b/homeassistant/components/nfandroidtv/notify.py index b250df4549290d..21672e6b9ae6eb 100644 --- a/homeassistant/components/nfandroidtv/notify.py +++ b/homeassistant/components/nfandroidtv/notify.py @@ -154,11 +154,14 @@ def send_message(self, message: str, **kwargs: Any) -> None: duration = int( data.get(ATTR_DURATION, Notifications.DEFAULT_DURATION) ) - # pylint: disable-next=home-assistant-action-swallowed-exception - except ValueError: - _LOGGER.warning( - "Invalid duration-value: %s", data.get(ATTR_DURATION) - ) + except (OverflowError, TypeError, ValueError) as err: + raise ServiceValidationError( + translation_domain=DOMAIN, + translation_key="invalid_duration", + translation_placeholders={ + "duration": str(data.get(ATTR_DURATION)) + }, + ) from err if ATTR_FONTSIZE in data: if data.get(ATTR_FONTSIZE) in Notifications.FONTSIZES: fontsize = data.get(ATTR_FONTSIZE) @@ -189,10 +192,14 @@ def send_message(self, message: str, **kwargs: Any) -> None: if ATTR_INTERRUPT in data: try: interrupt = cv.boolean(data.get(ATTR_INTERRUPT)) - except vol.Invalid: - _LOGGER.warning( - "Invalid interrupt-value: %s", data.get(ATTR_INTERRUPT) - ) + except vol.Invalid as err: + raise ServiceValidationError( + translation_domain=DOMAIN, + translation_key="invalid_interrupt", + translation_placeholders={ + "interrupt": str(data.get(ATTR_INTERRUPT)) + }, + ) from err if imagedata := data.get(ATTR_IMAGE): if isinstance(imagedata, str): image_file = ( diff --git a/homeassistant/components/nfandroidtv/strings.json b/homeassistant/components/nfandroidtv/strings.json index 61a1620dfa2eaf..ebc75419a9fc2b 100644 --- a/homeassistant/components/nfandroidtv/strings.json +++ b/homeassistant/components/nfandroidtv/strings.json @@ -34,6 +34,12 @@ "connection_failed": { "message": "Failed to connect to host: {host}" }, + "invalid_duration": { + "message": "Invalid duration value: {duration}" + }, + "invalid_interrupt": { + "message": "Invalid interrupt value: {interrupt}" + }, "invalid_notification_icon": { "message": "Invalid icon data provided. Got {type}" }, diff --git a/homeassistant/components/python_script/__init__.py b/homeassistant/components/python_script/__init__.py index afed00363c9e19..dfe8947411aab2 100644 --- a/homeassistant/components/python_script/__init__.py +++ b/homeassistant/components/python_script/__init__.py @@ -9,7 +9,7 @@ import os import time import types -from typing import Any +from typing import TYPE_CHECKING, Any from RestrictedPython import ( compile_restricted_exec, @@ -230,6 +230,9 @@ def execute( "Warning loading script %s: %s", filename, ", ".join(compiled.warnings) ) + if TYPE_CHECKING: + assert compiled.code is not None + def protected_getattr(obj: object, name: str, default: Any = None) -> Any: """Restricted method to get attributes.""" if name.startswith("async_"): diff --git a/homeassistant/components/python_script/manifest.json b/homeassistant/components/python_script/manifest.json index f026e3fa220a62..3dafd6bf9ed459 100644 --- a/homeassistant/components/python_script/manifest.json +++ b/homeassistant/components/python_script/manifest.json @@ -5,5 +5,5 @@ "documentation": "https://www.home-assistant.io/integrations/python_script", "loggers": ["RestrictedPython"], "quality_scale": "internal", - "requirements": ["RestrictedPython==8.1"] + "requirements": ["RestrictedPython==8.5"] } diff --git a/homeassistant/components/rachio/icons.json b/homeassistant/components/rachio/icons.json index 71c634a6cb9adc..84328f5e6548c9 100644 --- a/homeassistant/components/rachio/icons.json +++ b/homeassistant/components/rachio/icons.json @@ -2,10 +2,10 @@ "entity": { "switch": { "rain_delay": { - "default": "mdi:camera-timer" + "default": "mdi:hours-24" }, "standby": { - "default": "mdi:power" + "default": "mdi:power-sleep" } } }, diff --git a/homeassistant/components/repairs/__init__.py b/homeassistant/components/repairs/__init__.py index 99bd11597f8e58..73aea989555938 100644 --- a/homeassistant/components/repairs/__init__.py +++ b/homeassistant/components/repairs/__init__.py @@ -5,13 +5,14 @@ from homeassistant.helpers.typing import ConfigType from . import issue_handler, websocket_api -from .const import DOMAIN +from .const import DOMAIN, FlowType from .issue_handler import ConfirmRepairFlow, RepairsFlowManager from .models import RepairsFlow, RepairsFlowResult __all__ = [ "DOMAIN", "ConfirmRepairFlow", + "FlowType", "RepairsFlow", "RepairsFlowManager", "RepairsFlowResult", diff --git a/homeassistant/components/repairs/const.py b/homeassistant/components/repairs/const.py index cddc5edcffd793..49de0db186ad34 100644 --- a/homeassistant/components/repairs/const.py +++ b/homeassistant/components/repairs/const.py @@ -1,3 +1,13 @@ """Constants for the Repairs integration.""" +from enum import StrEnum + DOMAIN = "repairs" + + +class FlowType(StrEnum): + """Flow types supported in `next_flow` of RepairsFlowResult.""" + + CONFIG_FLOW = "config_flow" + OPTIONS_FLOW = "options_flow" + CONFIG_SUBENTRIES_FLOW = "config_subentries_flow" diff --git a/homeassistant/components/repairs/issue_handler.py b/homeassistant/components/repairs/issue_handler.py index f816d0c3f2110d..45da9615b3bbca 100644 --- a/homeassistant/components/repairs/issue_handler.py +++ b/homeassistant/components/repairs/issue_handler.py @@ -62,7 +62,9 @@ async def async_create_flow( issue_registry = ir.async_get(self.hass) issue = issue_registry.async_get_issue(handler_key, issue_id) if issue is None or not issue.is_fixable: - raise data_entry_flow.UnknownStep + raise data_entry_flow.UnknownStep( + f"issue id {issue_id} is {'not found' if issue is None else 'not fixable'}" + ) platforms: LazyIntegrationPlatforms[RepairsProtocol] = self.hass.data[DOMAIN][ "platforms" diff --git a/homeassistant/components/repairs/models.py b/homeassistant/components/repairs/models.py index bdaee67fe1f845..12d0ca48f7b8a9 100644 --- a/homeassistant/components/repairs/models.py +++ b/homeassistant/components/repairs/models.py @@ -1,12 +1,26 @@ """Models for Repairs.""" -from typing import Protocol +from collections.abc import Mapping +from typing import Any, Protocol, override from homeassistant import data_entry_flow -from homeassistant.core import HomeAssistant +from homeassistant.config_entries import ( + ConfigEntry, + ConfigFlowResult, + SubentryFlowResult, +) +from homeassistant.core import HomeAssistant, callback -# Placeholder TypeAlias for future TypedDict to handle next_flow. -RepairsFlowResult = data_entry_flow.FlowResult[data_entry_flow.FlowContext, str] +from .const import FlowType + + +class RepairsFlowResult( + data_entry_flow.FlowResult[data_entry_flow.FlowContext, str], total=False +): + """Typed result dict for repair flow.""" + + next_flow: tuple[FlowType, str] + result: ConfigEntry | None class RepairsFlow( @@ -17,6 +31,81 @@ class RepairsFlow( issue_id: str data: dict[str, str | int | float | None] | None + @override + @callback + def async_create_entry( + self, + *, + title: str | None = None, + data: Mapping[str, Any], + description: str | None = None, + description_placeholders: Mapping[str, str] | None = None, + next_flow: tuple[FlowType, str] | None = None, + ) -> RepairsFlowResult: + """Create an entry (fix a flow).""" + result: RepairsFlowResult = super().async_create_entry( + title=title, + data=data, + description=description, + description_placeholders=description_placeholders, + ) + + self._async_set_next_flow_if_valid(result, next_flow) + + return result + + @override + @callback + def async_abort( + self, + *, + reason: str, + description_placeholders: Mapping[str, str] | None = None, + next_flow: tuple[FlowType, str] | None = None, + ) -> RepairsFlowResult: + """Abort the flow (leave the issue unrepaired).""" + result: RepairsFlowResult = super().async_abort( + reason=reason, description_placeholders=description_placeholders + ) + + self._async_set_next_flow_if_valid(result, next_flow) + + return result + + @callback + def _async_set_next_flow_if_valid( + self, + result: RepairsFlowResult, + next_flow: tuple[FlowType, str] | None, + ) -> None: + """Validate and set next_flow in result if provided.""" + if next_flow is None: + return + flow_type, flow_id = next_flow + if flow_type not in FlowType: + raise data_entry_flow.UnknownFlow("Invalid next_flow FlowType") + entry_id: str | None = None + if flow_type == FlowType.CONFIG_FLOW: + config_flow: ConfigFlowResult = self.hass.config_entries.flow.async_get( + flow_id + ) + entry_id = config_flow["context"].get("entry_id") + elif flow_type == FlowType.CONFIG_SUBENTRIES_FLOW: + subentry_flow: SubentryFlowResult = ( + self.hass.config_entries.subentries.async_get(flow_id) + ) + entry_id, _ = subentry_flow["handler"] + else: # FlowType.OPTIONS_FLOW + config_flow = self.hass.config_entries.options.async_get(flow_id) + entry_id = config_flow["handler"] + # entry_id can be None for config flows creating a new config entry + result["result"] = ( + self.hass.config_entries.async_get_known_entry(entry_id) + if entry_id is not None + else None + ) + result["next_flow"] = next_flow + class RepairsProtocol(Protocol): """Define the format of repairs platforms.""" diff --git a/homeassistant/components/repairs/websocket_api.py b/homeassistant/components/repairs/websocket_api.py index 5f926e23095e4e..5519a270dfc98b 100644 --- a/homeassistant/components/repairs/websocket_api.py +++ b/homeassistant/components/repairs/websocket_api.py @@ -1,5 +1,6 @@ """The repairs websocket API.""" +from collections.abc import Callable from http import HTTPStatus from typing import Any, override @@ -11,6 +12,7 @@ from homeassistant.components import websocket_api from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.components.http.decorators import require_admin +from homeassistant.config_entries import ConfigEntry, UnknownEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import issue_registry as ir from homeassistant.helpers.data_entry_flow import ( @@ -19,6 +21,7 @@ ) from .const import DOMAIN +from .issue_handler import RepairsFlowManager @callback @@ -105,7 +108,20 @@ def ws_list_issues( connection.send_result(msg["id"], {"issues": issues}) -class RepairsFlowIndexView(FlowManagerIndexView): +def _prepare_repairs_flow_result_json( + result: data_entry_flow.FlowResult, + prepare_result_json: Callable[[data_entry_flow.FlowResult], dict[str, Any]], +) -> dict[str, Any]: + """Convert result to serializable JSON dict.""" + entry: ConfigEntry | None = result.pop("result", None) # type: ignore[typeddict-item] + data = prepare_result_json(result) + if entry is not None: + # Overwrite the ConfigEntry object with its json representation for frontend. + data["result"] = entry.as_json_fragment + return data + + +class RepairsFlowIndexView(FlowManagerIndexView[RepairsFlowManager]): """View to create issue fix flows.""" url = "/api/repairs/issues/fix" @@ -129,19 +145,28 @@ async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response data["handler"], data={"issue_id": data["issue_id"]}, ) - except data_entry_flow.UnknownHandler: - return self.json_message("Invalid handler specified", HTTPStatus.NOT_FOUND) - except data_entry_flow.UnknownStep: + except data_entry_flow.UnknownFlow as ex: + return self.json_message( + f"Unknown flow{f': {ex!s}' if str(ex) else ''}", + HTTPStatus.NOT_FOUND, + ) + except data_entry_flow.UnknownStep as ex: + return self.json_message(str(ex), HTTPStatus.BAD_REQUEST) + except UnknownEntry as ex: return self.json_message( - "Handler does not support user", HTTPStatus.BAD_REQUEST + f"Config entry {ex!s} not found in next_flow", HTTPStatus.BAD_REQUEST ) + return self.json(self._prepare_result_json(result)) - return self.json( - self._prepare_result_json(result), - ) + @override + def _prepare_result_json( + self, result: data_entry_flow.FlowResult + ) -> dict[str, Any]: + """Convert result to JSON serializable dict.""" + return _prepare_repairs_flow_result_json(result, super()._prepare_result_json) -class RepairsFlowResourceView(FlowManagerResourceView): +class RepairsFlowResourceView(FlowManagerResourceView[RepairsFlowManager]): """View to interact with the option flow manager.""" url = "/api/repairs/issues/fix/{flow_id}" @@ -157,4 +182,18 @@ async def get(self, request: web.Request, /, flow_id: str) -> web.Response: @override async def post(self, request: web.Request, flow_id: str) -> web.Response: """Handle a POST request.""" - return await super().post(request, flow_id) + try: + result = await super().post(request, flow_id) + except UnknownEntry as ex: + # Raised by _async_set_next_flow_if_valid in a RepairsFlow + return self.json_message( + f"Config entry {ex!s} not found in next_flow", HTTPStatus.BAD_REQUEST + ) + return result + + @override + def _prepare_result_json( + self, result: data_entry_flow.FlowResult + ) -> dict[str, Any]: + """Convert result to JSON serializable dict.""" + return _prepare_repairs_flow_result_json(result, super()._prepare_result_json) diff --git a/homeassistant/components/sonos/__init__.py b/homeassistant/components/sonos/__init__.py index e17f7c8abf2e2e..e953b4110f4347 100644 --- a/homeassistant/components/sonos/__init__.py +++ b/homeassistant/components/sonos/__init__.py @@ -73,6 +73,12 @@ ZGS_SUBSCRIPTION_TIMEOUT = 2 SHUTDOWN_TIMEOUT = 10 + +def _get_soco_uid(soco: SoCo) -> str: + """Get SoCo uid as a typed helper for executor jobs.""" + return soco.uid + + CONFIG_SCHEMA = vol.Schema( { DOMAIN: vol.Schema( @@ -531,9 +537,11 @@ async def async_poll_manual_hosts( ), None, ) - if not known_speaker: + if known_speaker: + uid = known_speaker.uid + else: try: - uid = await self.hass.async_add_executor_job(getattr, soco, "uid") + uid = await self.hass.async_add_executor_job(_get_soco_uid, soco) except HTTPError as err: await self._process_http_connection_error(err, ip_addr) continue @@ -545,6 +553,14 @@ async def async_poll_manual_hosts( ) as ex: _LOGGER.warning("Could not get Sonos uid from %s: %s", ip_addr, ex) continue + + if self.is_device_disabled(uid): + _LOGGER.debug( + "Skipping manual poll for disabled Sonos device: %s", + uid, + ) + continue + if not known_speaker: try: await self._async_handle_discovery_message( uid, diff --git a/homeassistant/components/thread/__init__.py b/homeassistant/components/thread/__init__.py index ffbe32e389a14c..1f9bef81d7634d 100644 --- a/homeassistant/components/thread/__init__.py +++ b/homeassistant/components/thread/__init__.py @@ -7,6 +7,7 @@ from .const import DOMAIN from .dataset_store import ( + DatasetAddResult, DatasetEntry, async_add_dataset, async_get_dataset, @@ -16,6 +17,7 @@ __all__ = [ "DOMAIN", + "DatasetAddResult", "DatasetEntry", "async_add_dataset", "async_get_dataset", diff --git a/homeassistant/components/thread/dataset_store.py b/homeassistant/components/thread/dataset_store.py index 9f9f132fc8ba73..784c17303ca6a4 100644 --- a/homeassistant/components/thread/dataset_store.py +++ b/homeassistant/components/thread/dataset_store.py @@ -3,6 +3,7 @@ from asyncio import Event, Task, wait import dataclasses from datetime import datetime +from enum import StrEnum import logging from pprint import pformat from typing import Any, cast, override @@ -89,6 +90,24 @@ class DatasetPreferredError(HomeAssistantError): """Raised when attempting to delete the preferred dataset.""" +class DatasetAddResult(StrEnum): + """The outcome of adding a dataset to the store. + + A caller that has already handed the dataset to a border router needs to + know when Home Assistant's copy disagrees with what the mesh will run. + """ + + # The store's dataset for this extended PAN ID is the one that was passed: + # it was written, or an equivalent one was already stored, so the stored + # TLV may differ byte for byte. The preferred border agent is refreshed. + STORED = "stored" + + # The dataset was not stored, because the store holds a different dataset + # with the same or a newer active timestamp for this extended PAN ID. + # Nothing about the entry was changed. + DISCARDED = "discarded" + + @dataclasses.dataclass(frozen=True) class DatasetEntry: """Dataset store entry.""" @@ -264,8 +283,13 @@ def async_add( tlv: str, preferred_border_agent_id: str | None, preferred_extended_address: str | None, - ) -> None: - """Add dataset, does nothing if it already exists.""" + ) -> DatasetAddResult: + """Add a dataset, report whether the store holds it afterwards. + + Datasets are keyed by extended PAN ID and ordered by active timestamp, + the way a Thread mesh orders them itself, so a dataset that is not newer + than the stored one for its network is discarded rather than stored. + """ # Make sure the tlv is valid dataset = tlv_parser.parse_tlv(tlv) @@ -291,7 +315,7 @@ def async_add( self._async_maybe_update_preferred_border_agent( entry, preferred_border_agent_id, preferred_extended_address ) - return + return DatasetAddResult.STORED # Update if dataset with same extended pan id exists and the timestamp # is newer @@ -326,7 +350,7 @@ def async_add( pformat(_format_dataset(entry.dataset)), pformat(_format_dataset(dataset)), ) - return + return DatasetAddResult.DISCARDED elif _LOGGER.isEnabledFor(logging.DEBUG): _LOGGER.debug( "Updating dataset with same extended PAN ID and newer" @@ -341,7 +365,7 @@ def async_add( self._async_maybe_update_preferred_border_agent( entry, preferred_border_agent_id, preferred_extended_address ) - return + return DatasetAddResult.STORED entry = DatasetEntry( preferred_border_agent_id=preferred_border_agent_id, @@ -365,6 +389,8 @@ def async_add( ) ) + return DatasetAddResult.STORED + @callback def async_delete(self, dataset_id: str) -> None: """Delete dataset.""" @@ -551,10 +577,17 @@ async def async_add_dataset( *, preferred_border_agent_id: str | None = None, preferred_extended_address: str | None = None, -) -> None: - """Add a dataset.""" +) -> DatasetAddResult: + """Add a dataset, report whether the store holds it afterwards. + + Returns STORED when the store's dataset for the network is the one that + was passed, DISCARDED when the store kept a same-or-newer dataset for it + and changed nothing. + """ store = await async_get_store(hass) - store.async_add(source, tlv, preferred_border_agent_id, preferred_extended_address) + return store.async_add( + source, tlv, preferred_border_agent_id, preferred_extended_address + ) async def async_get_dataset(hass: HomeAssistant, dataset_id: str) -> str | None: diff --git a/homeassistant/components/thread/websocket_api.py b/homeassistant/components/thread/websocket_api.py index 6e813ba1bbcc48..c725bc5d2e68d3 100644 --- a/homeassistant/components/thread/websocket_api.py +++ b/homeassistant/components/thread/websocket_api.py @@ -40,12 +40,16 @@ async def ws_add_dataset( tlv = msg["tlv"] try: - await dataset_store.async_add_dataset(hass, source, tlv) + result = await dataset_store.async_add_dataset(hass, source, tlv) except TLVError as exc: connection.send_error(msg["id"], websocket_api.ERR_INVALID_FORMAT, str(exc)) return - connection.send_result(msg["id"]) + # The outcome rides in the result payload rather than an error: existing + # callers treat any error as a failed transfer, while a discarded dataset + # means the store already holds this network's dataset in a same-or-newer + # revision. + connection.send_result(msg["id"], {"result": str(result)}) @websocket_api.require_admin diff --git a/homeassistant/components/tuya/const.py b/homeassistant/components/tuya/const.py index 78d03c625261a3..1b2793c024206e 100644 --- a/homeassistant/components/tuya/const.py +++ b/homeassistant/components/tuya/const.py @@ -491,6 +491,8 @@ class DeviceCategory(StrEnum): """ FSKG = "fskg" """Fan wall switch (undocumented)""" + HCDD = "hcdd" + """Chasing tape light (undocumented)""" HJJCY = "hjjcy" """Air Quality Monitor diff --git a/homeassistant/components/tuya/light.py b/homeassistant/components/tuya/light.py index 6aeb1b530dea06..4ccc1b7164ae4c 100644 --- a/homeassistant/components/tuya/light.py +++ b/homeassistant/components/tuya/light.py @@ -164,6 +164,16 @@ class TuyaLightEntityDescription(LightEntityDescription): color_data=DPCode.COLOUR_DATA, ), ), + DeviceCategory.HCDD: ( + TuyaLightEntityDescription( + key=DPCode.SWITCH_LED, + name=None, + color_mode=DPCode.WORK_MODE, + brightness=DPCode.BRIGHT_VALUE, + color_temp=DPCode.TEMP_VALUE, + color_data=DPCode.COLOUR_DATA, + ), + ), DeviceCategory.HXD: ( TuyaLightEntityDescription( key=DPCode.SWITCH_LED, diff --git a/homeassistant/components/unifi/sensor.py b/homeassistant/components/unifi/sensor.py index 96d5cfb332a00b..cf10b61d05787b 100644 --- a/homeassistant/components/unifi/sensor.py +++ b/homeassistant/components/unifi/sensor.py @@ -191,9 +191,7 @@ def async_uptime_value_changed_fn( @callback def async_device_outlet_power_supported_fn(hub: UnifiHub, obj_id: str) -> bool: """Determine if an outlet has the power property.""" - # At this time, an outlet_caps value of 3 is expected to indicate that the outlet - # supports metering - return hub.api.outlets[obj_id].caps == 3 + return hub.api.outlets[obj_id].has_metering is True @callback diff --git a/homeassistant/components/unifi/switch.py b/homeassistant/components/unifi/switch.py index 0173a396fd1529..e2cb5f6141da6a 100644 --- a/homeassistant/components/unifi/switch.py +++ b/homeassistant/components/unifi/switch.py @@ -186,8 +186,7 @@ def async_object_oriented_network_config_supported_fn( @callback def async_outlet_switching_supported_fn(hub: UnifiHub, obj_id: str) -> bool: """Determine if an outlet supports switching.""" - outlet = hub.api.outlets[obj_id] - return outlet.has_relay or outlet.caps in (1, 3) + return hub.api.outlets[obj_id].has_relay is True @callback diff --git a/homeassistant/components/zwave_js/config_flow.py b/homeassistant/components/zwave_js/config_flow.py index 203cfe7d4c4f0f..4beebfe448c92f 100644 --- a/homeassistant/components/zwave_js/config_flow.py +++ b/homeassistant/components/zwave_js/config_flow.py @@ -766,6 +766,16 @@ async def async_step_on_supervisor( self.use_addon = True + if any( + entry.data.get(CONF_USE_ADDON) and entry.unique_id != self.unique_id + for entry in self._async_current_entries(include_ignore=False) + ): + # The add-on can only connect to a single adapter, so abort before + # the flow changes the add-on config of the existing entry. + # A discovery of the existing entry's own adapter passes, so the + # entry can be updated, e.g. from a USB path to a socket. + return self.async_abort(reason="addon_already_configured") + addon_info = await self._async_get_addon_info() if addon_info.state is AddonState.RUNNING: @@ -1339,6 +1349,14 @@ async def async_step_on_supervisor_reconfigure( raise AbortFlow("addon_stop_failed") from err return await self.async_step_manual_reconfigure() + if any( + entry.data.get(CONF_USE_ADDON) and entry.entry_id != config_entry.entry_id + for entry in self._async_current_entries(include_ignore=False) + ): + # The add-on can only connect to a single adapter, so abort before + # the flow changes the add-on config of the other entry. + return self.async_abort(reason="addon_already_configured") + addon_info = await self._async_get_addon_info() if addon_info.state is AddonState.NOT_INSTALLED: diff --git a/homeassistant/components/zwave_js/discovery.py b/homeassistant/components/zwave_js/discovery.py index 3e2fa301aaf455..98039ecfe854b9 100644 --- a/homeassistant/components/zwave_js/discovery.py +++ b/homeassistant/components/zwave_js/discovery.py @@ -258,6 +258,18 @@ class ZWaveDiscoverySchema: FanValueMapping(speeds=[(1, 25), (26, 50), (51, 75), (76, 99)]), ), ), + # Leviton VRF01 fan controllers using switch multilevel CC + ZWaveDiscoverySchema( + platform=Platform.FAN, + hint="has_fan_value_mapping", + manufacturer_id={0x001D}, + product_id={0x0209, 0x0334}, + product_type={0x1001}, + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, + data_template=FixedFanValueMappingDataTemplate( + FanValueMapping(speeds=[(1, 32), (33, 66), (67, 99)]), + ), + ), # Inovelli LZW36 light / fan controller combo using switch multilevel CC # The fan is endpoint 2, the light is endpoint 1. ZWaveDiscoverySchema( diff --git a/homeassistant/components/zwave_js/strings.json b/homeassistant/components/zwave_js/strings.json index 49a602d051a465..0f6c78f2ae49f8 100644 --- a/homeassistant/components/zwave_js/strings.json +++ b/homeassistant/components/zwave_js/strings.json @@ -1,6 +1,7 @@ { "config": { "abort": { + "addon_already_configured": "A configuration entry using the Z-Wave JS app already exists. Reconfigure or migrate that entry instead.", "addon_get_discovery_info_failed": "Failed to get Z-Wave JS app discovery info.", "addon_info_failed": "Failed to get Z-Wave JS app info.", "addon_install_failed": "Failed to install the Z-Wave JS app.", diff --git a/requirements_all.txt b/requirements_all.txt index a9c9eef3e76492..f15f25be3eea81 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -108,7 +108,7 @@ PyXiaomiGateway==0.14.3 RachioPy==1.1.0 # homeassistant.components.python_script -RestrictedPython==8.1 +RestrictedPython==8.5 # homeassistant.components.remember_the_milk RtmAPI==0.7.2 @@ -1525,7 +1525,7 @@ loqedAPI==2.1.11 luftdaten==0.7.4 # homeassistant.components.lunatone -lunatone-rest-api-client==0.9.2 +lunatone-rest-api-client==0.10.0 # homeassistant.components.lupusec lupupy==0.3.2 diff --git a/tests/components/actron_air/conftest.py b/tests/components/actron_air/conftest.py index 9eca84ab07b951..7b6ef48d90374b 100644 --- a/tests/components/actron_air/conftest.py +++ b/tests/components/actron_air/conftest.py @@ -21,7 +21,7 @@ @pytest.fixture -def mock_actron_api() -> Generator[AsyncMock]: +def mock_actron_api_class() -> Generator[MagicMock]: """Mock the Actron Air API class.""" with ( patch( @@ -32,6 +32,14 @@ def mock_actron_api() -> Generator[AsyncMock]: "homeassistant.components.actron_air.config_flow.ActronAirAPI", new=mock_api, ), + ): + yield mock_api + + +@pytest.fixture +def mock_actron_api(mock_actron_api_class: MagicMock) -> Generator[AsyncMock]: + """Mock the Actron Air API instance.""" + with ( patch.object(ActronAirACSystem, "set_system_mode", new_callable=AsyncMock), patch.object( ActronAirUserAirconSettings, "set_away_mode", new_callable=AsyncMock @@ -54,7 +62,7 @@ def mock_actron_api() -> Generator[AsyncMock]: ActronAirUserAirconSettings, "set_fan_mode", new_callable=AsyncMock ), ): - api = mock_api.return_value + api = mock_actron_api_class.return_value # Mock device code request api.request_device_code.return_value = ActronAirDeviceCode( diff --git a/tests/components/actron_air/test_config_flow.py b/tests/components/actron_air/test_config_flow.py index 701f6627491153..c4554ed845786b 100644 --- a/tests/components/actron_air/test_config_flow.py +++ b/tests/components/actron_air/test_config_flow.py @@ -1,7 +1,7 @@ """Config flow tests for the Actron Air Integration.""" import asyncio -from unittest.mock import AsyncMock +from unittest.mock import AsyncMock, MagicMock from actron_neo_api import ActronAirAuthError from actron_neo_api.models.auth import ActronAirUserInfo @@ -12,10 +12,28 @@ from homeassistant.const import CONF_API_TOKEN from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType +from homeassistant.helpers.aiohttp_client import async_get_clientsession from tests.common import MockConfigEntry +@pytest.mark.usefixtures("mock_setup_entry", "mock_actron_api") +async def test_user_flow_uses_shared_session( + hass: HomeAssistant, mock_actron_api_class: MagicMock +) -> None: + """Test the API is created with Home Assistant's shared client session.""" + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + + assert mock_actron_api_class.call_args.kwargs["session"] is async_get_clientsession( + hass + ) + + await hass.async_block_till_done() + await hass.config_entries.flow.async_configure(result["flow_id"]) + + @pytest.mark.usefixtures("mock_setup_entry") async def test_user_flow_oauth2_success( hass: HomeAssistant, mock_actron_api: AsyncMock diff --git a/tests/components/actron_air/test_init.py b/tests/components/actron_air/test_init.py index 65ca2d90d1b500..792cec36bf71a5 100644 --- a/tests/components/actron_air/test_init.py +++ b/tests/components/actron_air/test_init.py @@ -10,12 +10,28 @@ from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr +from homeassistant.helpers.aiohttp_client import async_get_clientsession from . import setup_integration from tests.common import MockConfigEntry +@pytest.mark.usefixtures("mock_actron_api") +async def test_setup_entry_uses_shared_session( + hass: HomeAssistant, + mock_actron_api_class: MagicMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test the API is created with Home Assistant's shared client session.""" + await setup_integration(hass, mock_config_entry) + + assert mock_config_entry.state is ConfigEntryState.LOADED + assert mock_actron_api_class.call_args.kwargs["session"] is async_get_clientsession( + hass + ) + + async def test_setup_entry_auth_error( hass: HomeAssistant, mock_actron_api: AsyncMock, diff --git a/tests/components/androidtv_remote/test_remote.py b/tests/components/androidtv_remote/test_remote.py index 9bd86bb3d8567d..2e006c4514aa3d 100644 --- a/tests/components/androidtv_remote/test_remote.py +++ b/tests/components/androidtv_remote/test_remote.py @@ -8,7 +8,7 @@ from homeassistant.config_entries import ConfigEntryState from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE from homeassistant.core import HomeAssistant -from homeassistant.exceptions import HomeAssistantError +from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from tests.common import MockConfigEntry @@ -174,6 +174,171 @@ async def test_remote_send_command_with_hold_secs( ] +@pytest.mark.parametrize( + ("command", "expected_call"), + [ + ("start_long:DPAD_DOWN", call("DPAD_DOWN", "START_LONG")), + ("end_long:DPAD_DOWN", call("DPAD_DOWN", "END_LONG")), + ("short:DPAD_DOWN", call("DPAD_DOWN", "SHORT")), + ("START_LONG:DPAD_DOWN", call("DPAD_DOWN", "START_LONG")), + ], + ids=["start", "end", "short", "uppercase_prefix"], +) +async def test_remote_send_command_with_direction_prefix( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_api: MagicMock, + command: str, + expected_call: object, +) -> None: + """Test remote.send_command emits a single directional event for prefixed commands.""" + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + assert mock_config_entry.state is ConfigEntryState.LOADED + + await hass.services.async_call( + "remote", + "send_command", + { + "entity_id": REMOTE_ENTITY, + "command": command, + "delay_secs": 0.01, + }, + blocking=True, + ) + assert mock_api.send_key_command.mock_calls == [expected_call] + + +@pytest.mark.parametrize( + "command", + [ + "text:hello world", + "voice:something", + "DPAD_DOWN:WITH_COLON", + ":leading_colon", + ], + ids=["text_prefix", "unknown_prefix", "embedded_colon", "leading_colon"], +) +async def test_remote_send_command_unknown_prefix_passes_through( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_api: MagicMock, + command: str, +) -> None: + """Test that commands with non-direction colon prefixes are forwarded verbatim. + + The integration only strips prefixes that match the allowlist; + other colon-using conventions (notably the lib's own ``text:`` prefix for + keyboard text) must reach the underlying library unchanged so it can apply + its own routing. + """ + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + assert mock_config_entry.state is ConfigEntryState.LOADED + + await hass.services.async_call( + "remote", + "send_command", + { + "entity_id": REMOTE_ENTITY, + "command": command, + "delay_secs": 0.01, + }, + blocking=True, + ) + assert mock_api.send_key_command.mock_calls == [call(command, "SHORT")] + + +async def test_remote_send_command_direction_prefix_pair( + hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock +) -> None: + """Test that a press-down/release-up pair produces exactly two events. + + This is the live-press scenario: a UI sends START_LONG on pointerdown and + END_LONG on pointerup as separate service calls. Together they must produce + no extra SHORT or sleep-driven events. + """ + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + assert mock_config_entry.state is ConfigEntryState.LOADED + + await hass.services.async_call( + "remote", + "send_command", + { + "entity_id": REMOTE_ENTITY, + "command": "start_long:DPAD_CENTER", + "delay_secs": 0.01, + }, + blocking=True, + ) + await hass.services.async_call( + "remote", + "send_command", + { + "entity_id": REMOTE_ENTITY, + "command": "end_long:DPAD_CENTER", + "delay_secs": 0.01, + }, + blocking=True, + ) + assert mock_api.send_key_command.mock_calls == [ + call("DPAD_CENTER", "START_LONG"), + call("DPAD_CENTER", "END_LONG"), + ] + + +async def test_remote_send_command_direction_prefix_with_hold_secs_raises( + hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock +) -> None: + """Test that combining a direction prefix with hold_secs raises.""" + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + assert mock_config_entry.state is ConfigEntryState.LOADED + + with pytest.raises( + ServiceValidationError, + match='Command "start_long:DPAD_RIGHT" combines a direction prefix with hold_secs', + ): + await hass.services.async_call( + "remote", + "send_command", + { + "entity_id": REMOTE_ENTITY, + "command": "start_long:DPAD_RIGHT", + "delay_secs": 0.01, + "hold_secs": 0.01, + }, + blocking=True, + ) + assert mock_api.send_key_command.mock_calls == [] + + +async def test_remote_send_command_empty_key_code_raises( + hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock +) -> None: + """Test that a direction prefix without a key code raises.""" + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + assert mock_config_entry.state is ConfigEntryState.LOADED + + with pytest.raises( + ServiceValidationError, + match='Command "SHORT:" is missing a key code after the direction prefix', + ): + await hass.services.async_call( + "remote", + "send_command", + { + "entity_id": REMOTE_ENTITY, + "command": "SHORT:", + "delay_secs": 0.01, + }, + blocking=True, + ) + assert mock_api.send_key_command.mock_calls == [] + + async def test_remote_connection_closed( hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock ) -> None: diff --git a/tests/components/brother/test_config_flow.py b/tests/components/brother/test_config_flow.py index 41d2743263a4b5..475321176fb26e 100644 --- a/tests/components/brother/test_config_flow.py +++ b/tests/components/brother/test_config_flow.py @@ -149,7 +149,15 @@ async def test_unsupported_model_error( """Test unsupported printer model error.""" mock_brother.create.side_effect = UnsupportedModelError("error") result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": SOURCE_USER}, data=CONFIG + DOMAIN, context={"source": SOURCE_USER} + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + CONFIG, ) assert result["type"] is FlowResultType.ABORT @@ -165,7 +173,15 @@ async def test_device_exists_abort( await init_integration(hass, mock_config_entry) result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": SOURCE_USER}, data=CONFIG + DOMAIN, context={"source": SOURCE_USER} + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + CONFIG, ) assert result["type"] is FlowResultType.ABORT diff --git a/tests/components/hassio/test_issues.py b/tests/components/hassio/test_issues.py index a241e700cf5c55..f4a1f0b50c7dce 100644 --- a/tests/components/hassio/test_issues.py +++ b/tests/components/hassio/test_issues.py @@ -33,6 +33,7 @@ ) from homeassistant.components.repairs import DOMAIN as REPAIRS_DOMAIN from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers import issue_registry as ir from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util @@ -1436,6 +1437,59 @@ async def test_supervisor_issues_periodic_refresh_backstop( supervisor_client.resolution.info.assert_called_once() +@pytest.mark.usefixtures("all_setup_requests") +async def test_issue_repair_recreated_when_registry_entry_missing( + hass: HomeAssistant, + supervisor_client: AsyncMock, + issue_registry: ir.IssueRegistry, +) -> None: + """Test a repair deleted from the registry is re-created for an unchanged issue. + + A finished repair flow deletes the issue registry entry even when applying + the suggestion failed in Supervisor. The issue then comes back unchanged on + the next refresh and must be re-created instead of skipped as known. + """ + mock_resolution_info( + supervisor_client, + issues=[ + Issue( + type=IssueType.MOUNT_FAILED, + context=ContextType.MOUNT, + reference="m1", + uuid=(issue_uuid := uuid4()), + reference_extra=None, + ) + ], + suggestions_by_issue={ + issue_uuid: [ + Suggestion( + SuggestionType.EXECUTE_RELOAD, + context=ContextType.MOUNT, + reference="m1", + uuid=uuid4(), + auto=False, + reference_extra=None, + ) + ] + }, + ) + + result = await async_setup_component(hass, DOMAIN, {}) + assert result + + assert issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_uuid.hex) + + # Simulate a finished repair flow whose suggestion failed to apply in + # Supervisor: the registry entry is gone, the supervisor issue unchanged + ir.async_delete_issue(hass, DOMAIN, issue_uuid.hex) + assert not issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_uuid.hex) + + async_fire_time_changed(hass, dt_util.utcnow() + HASSIO_ISSUES_UPDATE_INTERVAL) + await hass.async_block_till_done() + + assert issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_uuid.hex) + + @pytest.mark.usefixtures("all_setup_requests") async def test_supervisor_issues_suggestions_change_updates_fixable_state( hass: HomeAssistant, diff --git a/tests/components/hassio/test_repairs.py b/tests/components/hassio/test_repairs.py index 93caa5a5e0286c..52c8e4c9b7b6dd 100644 --- a/tests/components/hassio/test_repairs.py +++ b/tests/components/hassio/test_repairs.py @@ -749,6 +749,106 @@ async def test_mount_failed_repair_flow( supervisor_client.resolution.apply_suggestion.assert_called_once_with(sugg_uuid) +@pytest.mark.usefixtures("all_setup_requests") +async def test_mount_failed_move_local_data_repair_flow( + hass: HomeAssistant, + supervisor_client: AsyncMock, + hass_client: ClientSessionGenerator, + issue_registry: ir.IssueRegistry, +) -> None: + """Test moving blocking local data from the mount_failed repair.""" + mock_resolution_info( + supervisor_client, + issues=[ + Issue( + type=IssueType.MOUNT_FAILED, + context=ContextType.MOUNT, + reference="media_share", + uuid=(issue_uuid := uuid4()), + reference_extra=None, + ), + ], + suggestions_by_issue={ + issue_uuid: [ + Suggestion( + # Not in aiohasupervisor's SuggestionType enum yet, arrives + # as a plain string like any newer supervisor suggestion + type="move_local_data", + context=ContextType.MOUNT, + reference="media_share", + uuid=(sugg_uuid := uuid4()), + auto=False, + reference_extra=None, + ), + Suggestion( + type=SuggestionType.EXECUTE_RELOAD, + context=ContextType.MOUNT, + reference="media_share", + uuid=uuid4(), + auto=False, + reference_extra=None, + ), + Suggestion( + type=SuggestionType.EXECUTE_REMOVE, + context=ContextType.MOUNT, + reference="media_share", + uuid=uuid4(), + auto=False, + reference_extra=None, + ), + ] + }, + ) + + assert await async_setup_component(hass, DOMAIN, {}) + + repair_issue = issue_registry.async_get_issue( + domain="hassio", issue_id=issue_uuid.hex + ) + assert repair_issue + + client = await hass_client() + + resp = await client.post( + "/api/repairs/issues/fix", + json={"handler": "hassio", "issue_id": repair_issue.issue_id}, + ) + + assert resp.status == HTTPStatus.OK + data = await resp.json() + + flow_id = data["flow_id"] + assert data["type"] == "menu" + assert data["menu_options"] == [ + "mount_move_local_data", + "mount_execute_reload", + "mount_execute_remove", + ] + + # Moving data aside requires a confirmation step + resp = await client.post( + f"/api/repairs/issues/fix/{flow_id}", + json={"next_step_id": "mount_move_local_data"}, + ) + + assert resp.status == HTTPStatus.OK + data = await resp.json() + + flow_id = data["flow_id"] + assert data["type"] == "form" + assert data["step_id"] == "mount_move_local_data" + supervisor_client.resolution.apply_suggestion.assert_not_called() + + resp = await client.post(f"/api/repairs/issues/fix/{flow_id}", json={}) + + assert resp.status == HTTPStatus.OK + data = await resp.json() + + assert data["type"] == "create_entry" + assert not issue_registry.async_get_issue(domain="hassio", issue_id=issue_uuid.hex) + supervisor_client.resolution.apply_suggestion.assert_called_once_with(sugg_uuid) + + @pytest.mark.parametrize( "all_setup_requests", [{"include_addons": True}], indirect=True ) diff --git a/tests/components/homeassistant/triggers/test_event.py b/tests/components/homeassistant/triggers/test_event.py index 5536db1eb5e9ba..316d2eba42d8fb 100644 --- a/tests/components/homeassistant/triggers/test_event.py +++ b/tests/components/homeassistant/triggers/test_event.py @@ -1,13 +1,17 @@ """The tests for the Event automation.""" +import logging + +import attr import pytest from homeassistant.components import automation from homeassistant.const import ATTR_ENTITY_ID, ENTITY_MATCH_ALL, SERVICE_TURN_OFF from homeassistant.core import Context, HomeAssistant, ServiceCall +from homeassistant.helpers import device_registry as dr, script, trigger from homeassistant.setup import async_setup_component -from tests.common import mock_component +from tests.common import MockConfigEntry, mock_component @pytest.fixture @@ -629,3 +633,109 @@ async def test_templated_state_reported_event( "Got error 'Can't listen to state_reported in event trigger' " "when setting up triggers for automation 0" in caplog.text ) + + +COMPOSITE_ID = "composite00000000000000000000ab" + + +@pytest.fixture +def split_devices( + hass: HomeAssistant, device_registry: dr.DeviceRegistry +) -> tuple[dr.DeviceEntry, dr.DeviceEntry]: + """Create two devices which are splits of a pre-migration composite device.""" + entry_1 = MockConfigEntry(domain="itg1") + entry_1.add_to_hass(hass) + entry_2 = MockConfigEntry(domain="itg2") + entry_2.add_to_hass(hass) + device_1 = device_registry.async_get_or_create( + config_entry_id=entry_1.entry_id, + identifiers={("itg1", "1")}, + name="Split device 1", + ) + device_2 = device_registry.async_get_or_create( + config_entry_id=entry_2.entry_id, + identifiers={("itg2", "1")}, + name="Split device 2", + ) + device_registry.devices[device_1.id] = attr.evolve( + device_1, composite_device_id=COMPOSITE_ID + ) + device_registry.devices[device_2.id] = attr.evolve( + device_2, composite_device_id=COMPOSITE_ID + ) + return device_registry.devices[device_1.id], device_registry.devices[device_2.id] + + +_EVENT_TRIGGER = { + "platform": "event", + "event_type": "my_event", + "event_data": {"device_id": COMPOSITE_ID}, +} + + +def _expected_composite_warning( + device_1: dr.DeviceEntry, device_2: dr.DeviceEntry +) -> str: + """Return the exact warning the event validator logs for a composite device id.""" + return ( + f"Event trigger filters on device '{COMPOSITE_ID}', which was split into one " + "device per integration and no longer exists, so the trigger can no longer fire. " + "Update the automation, script or template entity to filter on one of these " + "devices instead: " + f"Split device 1 ({device_1.id}) from the itg1 integration, " + f"Split device 2 ({device_2.id}) from the itg2 integration.\n" + "The affected trigger is configured as:\n" + "platform: event\n" + "event_type: my_event\n" + "event_data:\n" + f" device_id: {COMPOSITE_ID}\n" + ) + + +async def test_composite_device_id_logs_warning( + hass: HomeAssistant, + split_devices: tuple[dr.DeviceEntry, dr.DeviceEntry], + caplog: pytest.LogCaptureFixture, +) -> None: + """Test a composite event_data.device_id filter logs the full warning.""" + with caplog.at_level(logging.WARNING): + await trigger.async_validate_trigger_config(hass, [_EVENT_TRIGGER]) + assert caplog.messages == [_expected_composite_warning(*split_devices)] + + +async def test_live_device_id_no_warning( + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, + caplog: pytest.LogCaptureFixture, +) -> None: + """Test a live event_data.device_id filter does not warn.""" + entry = MockConfigEntry(domain="itg") + entry.add_to_hass(hass) + live_device = device_registry.async_get_or_create( + config_entry_id=entry.entry_id, identifiers={("itg", "1")} + ) + with caplog.at_level(logging.WARNING): + await trigger.async_validate_trigger_config( + hass, + [ + { + "platform": "event", + "event_type": "my_event", + "event_data": {"device_id": live_device.id}, + } + ], + ) + assert caplog.messages == [] + + +async def test_wait_for_trigger_composite_device_id_logs_warning( + hass: HomeAssistant, + split_devices: tuple[dr.DeviceEntry, dr.DeviceEntry], + caplog: pytest.LogCaptureFixture, +) -> None: + """Test a composite device_id in a wait_for_trigger event trigger warns too.""" + with caplog.at_level(logging.WARNING): + await script.async_validate_actions_config( + hass, [{"wait_for_trigger": [_EVENT_TRIGGER]}] + ) + assert caplog.messages == [_expected_composite_warning(*split_devices)] diff --git a/tests/components/http/test_ban.py b/tests/components/http/test_ban.py index 5f5fd1660f4f16..ff6465e91f87bc 100644 --- a/tests/components/http/test_ban.py +++ b/tests/components/http/test_ban.py @@ -83,18 +83,19 @@ async def test_access_from_banned_ip_with_partially_broken_yaml_file( aiohttp_client: ClientSessionGenerator, caplog: pytest.LogCaptureFixture, ) -> None: - """Test accessing to server from banned IP. Both trusted and not. - - We inject some garbage into the yaml file to make sure it can - still load the bans. - """ + """Test loading IP bans from a partially broken YAML file.""" app = web.Application() app[KEY_HASS] = hass setup_bans(hass, app, 5) set_real_ip = mock_real_ip(app) - data = {banned_ip: {"banned_at": "2016-11-16T19:20:03"} for banned_ip in BANNED_IPS} - data["5.3.3.3"] = {"banned_at": "garbage"} + data = { + BANNED_IPS[0]: {"banned_at": "2016-11-16T19:20:03"}, + "5.3.3.3": {"banned_at": "garbage"}, + "5.3.3.4": {}, + "5.3.3.5": None, + BANNED_IPS[1]: {"banned_at": "2016-11-16T19:20:03"}, + } with patch( "homeassistant.components.http.ban.load_yaml_config_file", @@ -102,17 +103,18 @@ async def test_access_from_banned_ip_with_partially_broken_yaml_file( ): client = await aiohttp_client(app) - for remote_addr in BANNED_IPS: + for remote_addr in (*BANNED_IPS, "5.3.3.4"): set_real_ip(remote_addr) resp = await client.get("/") assert resp.status == HTTPStatus.FORBIDDEN - # Ensure garbage data is ignored - set_real_ip("5.3.3.3") - resp = await client.get("/") - assert resp.status == HTTPStatus.NOT_FOUND + # Ensure malformed data is ignored + for remote_addr in ("5.3.3.3", "5.3.3.5"): + set_real_ip(remote_addr) + resp = await client.get("/") + assert resp.status == HTTPStatus.NOT_FOUND - assert "Failed to load IP ban" in caplog.text + assert caplog.text.count("Failed to load IP ban") == 2 async def test_access_from_banned_ip_with_invalid_ip_entry( diff --git a/tests/components/lunatone/__init__.py b/tests/components/lunatone/__init__.py index e88b23f7cefeef..98d0d302dde998 100644 --- a/tests/components/lunatone/__init__.py +++ b/tests/components/lunatone/__init__.py @@ -26,7 +26,7 @@ BASE_IP: Final = "10.0.0.131" BASE_URL: Final = URL.build(scheme="http", host=BASE_IP).human_repr()[:-1] MANUFACTURER: Final = "Lunatone Industrielle Elektronik GmbH" -PRODUCT_NAME: Final = "Test Product" +PRODUCT_NAME: Final = "DALI-2 Display 7''" SERIAL_NUMBER: Final = 12345 UUID: Final = "be37ca9c-47c2-4498-a38b-c62c7c711840" VERSION: Final = "v1.14.1/1.4.3" @@ -36,7 +36,7 @@ serial=12345, gtin=192837465, pcb="2a", - articleNumber=87654321, + articleNumber=86456840, productionYear=20, productionWeek=1, ) diff --git a/tests/components/lunatone/conftest.py b/tests/components/lunatone/conftest.py index 82813f857cc68f..a039a8116a5938 100644 --- a/tests/components/lunatone/conftest.py +++ b/tests/components/lunatone/conftest.py @@ -1,17 +1,18 @@ """Fixtures for Lunatone tests.""" from collections.abc import Generator +from copy import deepcopy from unittest.mock import AsyncMock, PropertyMock, patch from lunatone_rest_api_client import Device, Devices, Info, Sensor, Sensors -from lunatone_rest_api_client.models import InfoData, ScanData, ScanState, SensorsData +from lunatone_rest_api_client.models import InfoData, ScanData, SensorsData import pytest from homeassistant.components.lunatone.config_flow import LunatoneConfigFlow from homeassistant.components.lunatone.const import DOMAIN from homeassistant.const import CONF_URL -from . import BASE_URL, INFO_DATA, PRODUCT_NAME, SENSORS_DATA, UUID, build_devices_data +from . import BASE_URL, INFO_DATA, SENSORS_DATA, UUID, build_devices_data from tests.common import MockConfigEntry @@ -104,15 +105,10 @@ def mock_lunatone_info() -> Generator[AsyncMock]: def _set_data(data: InfoData) -> Info: info.data = data - info.name = info.data.name - info.product_name = PRODUCT_NAME - info.serial_number = info.data.device.serial - info.uid = info.data.uid - info.version = info.data.version return info info.set_data = _set_data - info.set_data(INFO_DATA) + info.set_data(deepcopy(INFO_DATA)) yield info @@ -139,8 +135,6 @@ def build_sensors_mock(sensors: Sensors): for sensor_data in sensors.data.sensors: sensor = AsyncMock(spec=Sensor) sensor.data = sensor_data - sensor.id = sensor.data.id - sensor.name = sensor.data.name sensor_list.append(sensor) return sensor_list @@ -176,11 +170,6 @@ def mock_lunatone_scan() -> Generator[AsyncMock]: ): scan = mock_dali_scan.return_value scan.data = ScanData() - type(scan).is_busy = PropertyMock( - side_effect=lambda: ( - scan.data.status in {ScanState.ADDRESSING, ScanState.IN_PROGRESS} - ) - ) yield scan diff --git a/tests/components/lunatone/snapshots/test_diagnostics.ambr b/tests/components/lunatone/snapshots/test_diagnostics.ambr index d5f6d613639131..4ffe5e96c82061 100644 --- a/tests/components/lunatone/snapshots/test_diagnostics.ambr +++ b/tests/components/lunatone/snapshots/test_diagnostics.ambr @@ -321,7 +321,7 @@ }), 'device': dict({ 'article_info': '', - 'article_number': 87654321, + 'article_number': 86456840, 'gtin': 192837465, 'pcb': '2a', 'production_week': 1, @@ -335,7 +335,7 @@ '0': dict({ 'device': dict({ 'article_info': '', - 'article_number': 87654321, + 'article_number': 86456840, 'gtin': 192837465, 'pcb': '2a', 'production_week': 1, diff --git a/tests/components/lunatone/test_config_flow.py b/tests/components/lunatone/test_config_flow.py index 16fc432f531f4f..58bb2cb6578b5a 100644 --- a/tests/components/lunatone/test_config_flow.py +++ b/tests/components/lunatone/test_config_flow.py @@ -72,7 +72,7 @@ async def test_full_flow_fail_because_of_missing_device_infos( hass: HomeAssistant, mock_lunatone_info: AsyncMock ) -> None: """Test full flow.""" - mock_lunatone_info.serial_number = None + mock_lunatone_info.data = None result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} diff --git a/tests/components/lunatone/test_init.py b/tests/components/lunatone/test_init.py index 9c0b5275b3fc89..6a9c30c78f22b4 100644 --- a/tests/components/lunatone/test_init.py +++ b/tests/components/lunatone/test_init.py @@ -1,6 +1,6 @@ """Tests for the Lunatone integration.""" -from unittest.mock import AsyncMock +from unittest.mock import AsyncMock, PropertyMock import aiohttp @@ -10,7 +10,15 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr, entity_registry as er -from . import BASE_URL, PRODUCT_NAME, SERIAL_NUMBER, UUID, VERSION, setup_integration +from . import ( + BASE_URL, + INFO_DATA, + PRODUCT_NAME, + SERIAL_NUMBER, + UUID, + VERSION, + setup_integration, +) from tests.common import MockConfigEntry @@ -173,6 +181,23 @@ async def test_config_entry_not_ready_no_info_data( assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY +async def test_config_entry_setup_error_no_info_data( + hass: HomeAssistant, + mock_lunatone_info: AsyncMock, + mock_lunatone_devices: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test the Lunatone config entry setup error due to missing info data.""" + type(mock_lunatone_info).data = PropertyMock( + side_effect=[INFO_DATA, INFO_DATA, None] + ) + + await setup_integration(hass, mock_config_entry) + + mock_lunatone_info.async_update.assert_called_once() + assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR + + async def test_config_entry_not_ready_no_devices_data( hass: HomeAssistant, mock_lunatone_info: AsyncMock, @@ -227,21 +252,6 @@ async def test_config_entry_not_ready_no_dali_scan_data( assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY -async def test_config_entry_not_ready_no_serial_number( - hass: HomeAssistant, - mock_lunatone_info: AsyncMock, - mock_lunatone_devices: AsyncMock, - mock_config_entry: MockConfigEntry, -) -> None: - """Test config entry not ready due to missing serial number.""" - mock_lunatone_info.serial_number = None - - await setup_integration(hass, mock_config_entry) - - mock_lunatone_info.async_update.assert_called_once() - assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR - - async def test_config_entry_unique_id_update( hass: HomeAssistant, mock_lunatone_info: AsyncMock, @@ -261,7 +271,7 @@ async def test_config_entry_unique_id_update( ) expected_unique_id = str(SERIAL_NUMBER) - mock_lunatone_info.uid = None + mock_lunatone_info.data.uid = None await setup_integration(hass, config_entry) @@ -278,7 +288,7 @@ async def test_config_entry_unique_id_update( assert entity.unique_id.startswith(expected_unique_id) expected_unique_id = UUID.replace("-", "") - mock_lunatone_info.uid = UUID + mock_lunatone_info.data.uid = UUID await hass.config_entries.async_reload(config_entry.entry_id) await hass.async_block_till_done() diff --git a/tests/components/lyngdorf/conftest.py b/tests/components/lyngdorf/conftest.py index fabe3f63134bd4..86a685abaeccd4 100644 --- a/tests/components/lyngdorf/conftest.py +++ b/tests/components/lyngdorf/conftest.py @@ -81,6 +81,9 @@ def mock_receiver() -> Generator[MagicMock]: setattr(receiver, f"trim_{_t}", None) setattr(receiver, f"trim_{_t}_range", NumericRange(-10.0, 10.0, 0.1)) + receiver.volume_range = NumericRange(-99.9, 24.0, 0.1) + receiver.zone_b_volume_range = NumericRange(-99.9, 24.0, 0.1) + receiver.power_on = False receiver.volume = -40.0 receiver.mute_enabled = False diff --git a/tests/components/lyngdorf/test_media_player.py b/tests/components/lyngdorf/test_media_player.py index 658db3733ca6a3..89edb45dc92cbe 100644 --- a/tests/components/lyngdorf/test_media_player.py +++ b/tests/components/lyngdorf/test_media_player.py @@ -131,11 +131,11 @@ async def test_volume_step( @pytest.mark.parametrize( - ("entity_id", "level", "attr", "expected_db"), + ("entity_id", "level", "method", "expected_db"), [ - (MAIN_ZONE, 0.5, "volume", -31.0), - (MAIN_ZONE, 1.0, "volume", 18.0), - (ZONE_B, 0.3, "zone_b_volume", -50.6), + (MAIN_ZONE, 0.5, "set_volume", -37.95), + (MAIN_ZONE, 1.0, "set_volume", 24.0), + (ZONE_B, 0.3, "set_zone_b_volume", -62.73), ], ) async def test_volume_set( @@ -144,7 +144,7 @@ async def test_volume_set( mock_receiver: MagicMock, entity_id: str, level: float, - attr: str, + method: str, expected_db: float, ) -> None: """Test setting and clamping volume on both zones.""" @@ -154,7 +154,7 @@ async def test_volume_set( {ATTR_ENTITY_ID: entity_id, ATTR_MEDIA_VOLUME_LEVEL: level}, blocking=True, ) - assert getattr(mock_receiver, attr) == pytest.approx(expected_db) + getattr(mock_receiver, method).assert_called_once_with(pytest.approx(expected_db)) @pytest.mark.parametrize( @@ -273,7 +273,7 @@ async def test_main_zone_state_properties( state = hass.states.get(MAIN_ZONE) assert state.state == MediaPlayerState.ON - assert state.attributes[ATTR_MEDIA_VOLUME_LEVEL] == pytest.approx(0.408, abs=0.01) + assert state.attributes[ATTR_MEDIA_VOLUME_LEVEL] == pytest.approx(0.484, abs=0.01) assert state.attributes[ATTR_MEDIA_VOLUME_MUTED] is False assert state.attributes[ATTR_INPUT_SOURCE] == "HDMI" assert state.attributes[ATTR_SOUND_MODE] == "Movie" @@ -317,14 +317,7 @@ async def test_zone_b_state_properties( state = hass.states.get(ZONE_B) assert state.state == MediaPlayerState.ON - assert state.attributes[ATTR_MEDIA_VOLUME_LEVEL] == pytest.approx(0.510, abs=0.01) + assert state.attributes[ATTR_MEDIA_VOLUME_LEVEL] == pytest.approx(0.564, abs=0.01) assert state.attributes[ATTR_MEDIA_VOLUME_MUTED] is True assert state.attributes[ATTR_INPUT_SOURCE] == "Optical" assert state.attributes[ATTR_INPUT_SOURCE_LIST] == ["HDMI", "Optical"] - - mock_receiver.zone_b_volume = "invalid" - for cb in callbacks: - cb() - await hass.async_block_till_done() - state = hass.states.get(ZONE_B) - assert state.attributes.get(ATTR_MEDIA_VOLUME_LEVEL) is None diff --git a/tests/components/monzo/conftest.py b/tests/components/monzo/conftest.py index 1d23206f58c46e..db12e5d392d524 100644 --- a/tests/components/monzo/conftest.py +++ b/tests/components/monzo/conftest.py @@ -27,13 +27,23 @@ "id": "acc_curr", "name": "Current Account", "type": "uk_retail", - "balance": {"balance": 123, "total_balance": 321, "currency": "GBP"}, + "balance": { + "balance": 123, + "total_balance": 321, + "spend_today": -45, + "currency": "GBP", + }, }, { "id": "acc_flex", "name": "Flex", "type": "uk_monzo_flex", - "balance": {"balance": 123, "total_balance": 321, "currency": "EUR"}, + "balance": { + "balance": 123, + "total_balance": 321, + "spend_today": -67, + "currency": "EUR", + }, }, ] TEST_POTS = [ diff --git a/tests/components/monzo/snapshots/test_sensor.ambr b/tests/components/monzo/snapshots/test_sensor.ambr index c7e686ec158640..25aab02720f10b 100644 --- a/tests/components/monzo/snapshots/test_sensor.ambr +++ b/tests/components/monzo/snapshots/test_sensor.ambr @@ -55,6 +55,62 @@ 'state': '1.23', }) # --- +# name: test_all_entities[sensor.current_account_spent_today-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.current_account_spent_today', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Spent today', + 'options': dict({ + 'sensor': dict({ + 'suggested_display_precision': 2, + }), + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Spent today', + 'platform': 'monzo', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'spend_today', + 'unique_id': 'acc_curr_spend_today', + 'unit_of_measurement': 'GBP', + }) +# --- +# name: test_all_entities[sensor.current_account_spent_today-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Data provided by Monzo', + : 'monetary', + : 'Current Account Spent today', + : 'GBP', + }), + 'context': , + 'entity_id': 'sensor.current_account_spent_today', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '0.45', + }) +# --- # name: test_all_entities[sensor.current_account_total_balance-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ @@ -167,6 +223,62 @@ 'state': '1.23', }) # --- +# name: test_all_entities[sensor.flex_spent_today-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.flex_spent_today', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Spent today', + 'options': dict({ + 'sensor': dict({ + 'suggested_display_precision': 2, + }), + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Spent today', + 'platform': 'monzo', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'spend_today', + 'unique_id': 'acc_flex_spend_today', + 'unit_of_measurement': 'EUR', + }) +# --- +# name: test_all_entities[sensor.flex_spent_today-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Data provided by Monzo', + : 'monetary', + : 'Flex Spent today', + : 'EUR', + }), + 'context': , + 'entity_id': 'sensor.flex_spent_today', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '0.67', + }) +# --- # name: test_all_entities[sensor.flex_total_balance-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ diff --git a/tests/components/monzo/test_sensor.py b/tests/components/monzo/test_sensor.py index 2699685bba7d4c..d1204f011d5773 100644 --- a/tests/components/monzo/test_sensor.py +++ b/tests/components/monzo/test_sensor.py @@ -29,6 +29,7 @@ EXPECTED_VALUE_GETTERS = { "balance": lambda x: x["balance"]["balance"] / 100, "total_balance": lambda x: x["balance"]["total_balance"] / 100, + "spend_today": lambda x: abs(x["balance"]["spend_today"]) / 100, "pot_balance": lambda x: x["balance"] / 100, } diff --git a/tests/components/nam/test_config_flow.py b/tests/components/nam/test_config_flow.py index 7c44f6c9bdecda..323d08b353ee0a 100644 --- a/tests/components/nam/test_config_flow.py +++ b/tests/components/nam/test_config_flow.py @@ -168,14 +168,19 @@ async def test_reauth_unsuccessful(hass: HomeAssistant) -> None: async def test_form_with_auth_errors(hass: HomeAssistant, error) -> None: """Test we handle errors when auth is required.""" exc, base_error = error + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + with patch( "homeassistant.components.nam.NettigoAirMonitor.async_get_mac_address", side_effect=AuthFailedError("Authorization has failed"), ): - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_USER}, - data=VALID_CONFIG, + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input=VALID_CONFIG, ) assert result["type"] is FlowResultType.FORM @@ -204,14 +209,19 @@ async def test_form_with_auth_errors(hass: HomeAssistant, error) -> None: async def test_form_errors(hass: HomeAssistant, error) -> None: """Test we handle errors.""" exc, base_error = error + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + with patch( "homeassistant.components.nam.NettigoAirMonitor.initialize", side_effect=exc, ): - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_USER}, - data=VALID_CONFIG, + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input=VALID_CONFIG, ) assert result["errors"] == {"base": base_error} @@ -219,16 +229,19 @@ async def test_form_errors(hass: HomeAssistant, error) -> None: async def test_form_abort(hass: HomeAssistant) -> None: """Test we handle abort after error.""" - with ( - patch( - "homeassistant.components.nam.NettigoAirMonitor.async_get_mac_address", - side_effect=CannotGetMacError("Cannot get MAC address from device"), - ), + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + with patch( + "homeassistant.components.nam.NettigoAirMonitor.async_get_mac_address", + side_effect=CannotGetMacError("Cannot get MAC address from device"), ): - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_USER}, - data=VALID_CONFIG, + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input=VALID_CONFIG, ) assert result["type"] is FlowResultType.ABORT diff --git a/tests/components/netatmo/test_light.py b/tests/components/netatmo/test_light.py index 83fe5a54607ac6..db8ebea1b936ac 100644 --- a/tests/components/netatmo/test_light.py +++ b/tests/components/netatmo/test_light.py @@ -211,3 +211,44 @@ async def test_light_setup_and_services( ] } ) + + +async def test_dimmable_light_turn_on_updates_brightness_optimistically( + hass: HomeAssistant, config_entry: MockConfigEntry, netatmo_auth: AsyncMock +) -> None: + """Test that turning on a dimmable light with a brightness updates state immediately. + + The Netatmo API doesn't push brightness changes back until the next poll, + which can be several minutes away, so the new brightness must be reflected + optimistically instead of waiting for that poll. + """ + with selected_platforms(["light"]): + assert await hass.config_entries.async_setup(config_entry.entry_id) + + await hass.async_block_till_done() + + light_entity = "light.unknown_00_11_22_33_00_11_45_fe" + + with patch("pyatmo.home.Home.async_set_state") as mock_set_state: + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: light_entity, "brightness": 128}, + blocking=True, + ) + await hass.async_block_till_done() + mock_set_state.assert_called_once_with( + { + "modules": [ + { + "id": "00:11:22:33:00:11:45:fe", + "brightness": round(128 / 2.55), + "bridge": "12:34:56:80:60:40", + } + ] + } + ) + + state = hass.states.get(light_entity) + assert state.state == "on" + assert state.attributes["brightness"] == 128 diff --git a/tests/components/nfandroidtv/test_notify.py b/tests/components/nfandroidtv/test_notify.py index fd0d82b7e1b3a9..8b30a24c6e21fc 100644 --- a/tests/components/nfandroidtv/test_notify.py +++ b/tests/components/nfandroidtv/test_notify.py @@ -1,7 +1,7 @@ """Tests for the Notifications for Android TV / Fire TV notify platform.""" -from collections.abc import AsyncGenerator -from unittest.mock import patch +from collections.abc import AsyncGenerator, Generator +from unittest.mock import MagicMock, patch from notifications_android_tv.notifications import ConnectError import pytest @@ -16,13 +16,15 @@ from homeassistant.config_entries import ConfigEntryState from homeassistant.const import ATTR_ENTITY_ID, CONF_NAME, STATE_UNKNOWN, Platform from homeassistant.core import HomeAssistant -from homeassistant.exceptions import HomeAssistantError +from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers import entity_registry as er from . import NAME from tests.common import AsyncMock, MockConfigEntry, snapshot_platform +LEGACY_SERVICE_NAME = "android_tv_fire_tv_1_2_3_4" + @pytest.fixture(autouse=True) async def notify_only() -> AsyncGenerator[None]: @@ -123,3 +125,48 @@ async def test_send_message_exception( mock_notifications_android_tv.send.assert_called_once_with( message="Hello", title="World" ) + + +@pytest.fixture +def mock_legacy_notifications() -> Generator[MagicMock]: + """Mock the client used by the legacy notify service.""" + with patch( + "homeassistant.components.nfandroidtv.notify.Notifications", + autospec=True, + ) as mock_client: + yield mock_client.return_value + + +@pytest.mark.usefixtures("mock_notifications_android_tv") +@pytest.mark.parametrize( + ("service_data", "translation_key"), + [ + pytest.param({"duration": "invalid"}, "invalid_duration", id="duration"), + pytest.param({"duration": None}, "invalid_duration", id="duration_none"), + pytest.param({"interrupt": "invalid"}, "invalid_interrupt", id="interrupt"), + ], +) +async def test_legacy_send_message_invalid_data( + hass: HomeAssistant, + config_entry: MockConfigEntry, + mock_legacy_notifications: MagicMock, + service_data: dict[str, str | None], + translation_key: str, +) -> None: + """Test that invalid service data raises and sends nothing.""" + config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert hass.services.has_service(NOTIFY_DOMAIN, LEGACY_SERVICE_NAME) + + with pytest.raises(ServiceValidationError) as err: + await hass.services.async_call( + NOTIFY_DOMAIN, + LEGACY_SERVICE_NAME, + {"message": "Hello", "data": service_data}, + blocking=True, + ) + + assert err.value.translation_key == translation_key + mock_legacy_notifications.send.assert_not_called() diff --git a/tests/components/recorder/auto_repairs/statistics/test_duplicates.py b/tests/components/recorder/auto_repairs/statistics/test_duplicates.py index e51129b643dee9..90f21e575c46b1 100644 --- a/tests/components/recorder/auto_repairs/statistics/test_duplicates.py +++ b/tests/components/recorder/auto_repairs/statistics/test_duplicates.py @@ -183,7 +183,11 @@ def add_statistics_meta(hass: HomeAssistant) -> None: def get_statistics_meta(hass: HomeAssistant) -> list: with session_scope(hass=hass, read_only=True) as session: - return list(session.query(recorder.db_schema.StatisticsMeta).all()) + return list( + session.query(recorder.db_schema.StatisticsMeta) + .order_by(recorder.db_schema.StatisticsMeta.id) + .all() + ) # Create some duplicated statistics_meta with schema version 28 with ( @@ -308,7 +312,11 @@ def add_statistics_meta(hass: HomeAssistant) -> None: def get_statistics_meta(hass: HomeAssistant) -> list: with session_scope(hass=hass, read_only=True) as session: - return list(session.query(recorder.db_schema.StatisticsMeta).all()) + return list( + session.query(recorder.db_schema.StatisticsMeta) + .order_by(recorder.db_schema.StatisticsMeta.id) + .all() + ) # Create some duplicated statistics with schema version 28 with ( diff --git a/tests/components/repairs/test_models.py b/tests/components/repairs/test_models.py new file mode 100644 index 00000000000000..4e4346d903a2ec --- /dev/null +++ b/tests/components/repairs/test_models.py @@ -0,0 +1,177 @@ +"""Tests for repairs model.py.""" + +from collections.abc import Iterator +from contextlib import contextmanager + +import pytest + +from homeassistant.components.repairs import ( + DOMAIN, + FlowType, + RepairsFlow, + RepairsFlowResult, + repairs_flow_manager, +) +from homeassistant.config_entries import ( + SOURCE_RECONFIGURE, + ConfigFlow, + ConfigSubentryFlow, + OptionsFlow, + SubentryFlowResult, +) +from homeassistant.core import HomeAssistant, callback +import homeassistant.helpers.issue_registry as ir + +from tests.common import ( + AsyncMock, + Mock, + MockConfigEntry, + MockModule, + async_setup_component, + mock_config_flow, + mock_integration, + mock_platform, +) + + +@pytest.fixture(autouse=True) +async def mock_repairs_integration(hass: HomeAssistant) -> None: + """Mock a repairs integration.""" + hass.config.components.add("fake_integration") + + def async_create_fix_flow( + hass: HomeAssistant, + issue_id: str, + data: dict[str, str | int | float | None] | None, + ) -> RepairsFlow: + return MockFixFlowNextFlow() + + mock_platform( + hass, + "fake_integration.repairs", + Mock(async_create_fix_flow=AsyncMock(wraps=async_create_fix_flow)), + ) + + +@contextmanager +def mock_core_config_flow() -> Iterator[None]: + """Mock a config flow.""" + + class CompConfigSubentryFlowHandler(ConfigSubentryFlow): + """Config subentry flow.""" + + async def async_step_reconfigure(self, user_input=None) -> SubentryFlowResult: + return self.async_show_form(step_id="reconfigure") + + class CompOptionsFlowHandler(OptionsFlow): + """Options flow.""" + + async def async_step_init(self, user_input=None): + return self.async_show_form(step_id="init") + + class CompConfigFlow(ConfigFlow): + """Config flow with options and subentries flow.""" + + async def async_step_user(self, user_input=None): + return self.async_show_form(step_id="user") + + async def async_step_reconfigure(self, user_input=None): + return self.async_show_form(step_id="reconfigure") + + @classmethod + @callback + def async_get_supported_subentry_types( + cls, config_entry + ) -> dict[str, type[ConfigSubentryFlow]]: + return {"fake_subentry": CompConfigSubentryFlowHandler} + + @staticmethod + @callback + def async_get_options_flow(config_entry) -> CompOptionsFlowHandler: + return CompOptionsFlowHandler() + + with mock_config_flow("comp", CompConfigFlow): + yield + + +class MockFixFlowNextFlow(RepairsFlow): + """Mock flow fix supporting `next_flow`.""" + + async def async_step_init( + self, user_input: dict[str, str] | None = None + ) -> RepairsFlowResult: + """Handle the first step of a fix flow.""" + + mock_integration(self.hass, MockModule("comp")) + mock_platform(self.hass, "comp.config_flow", None) + + entries = self.hass.config_entries.async_entries("comp") + assert len(entries) == 1 + mock_entry: MockConfigEntry = entries[0] + + with mock_core_config_flow(): + if self.issue_id == FlowType.OPTIONS_FLOW: + next_flow = await self.hass.config_entries.options.async_init( + mock_entry.entry_id + ) + return self.async_create_entry( + next_flow=(FlowType.OPTIONS_FLOW, next_flow["flow_id"]), data={} + ) + # self.issue_id == "subentry_config_issue" + assert len(mock_entry.subentries) == 1 + next_flow = await self.hass.config_entries.subentries.async_init( + (mock_entry.entry_id, "fake_subentry"), + context={ + "entry_id": mock_entry.entry_id, + "subentry_id": list(mock_entry.subentries.keys())[0], + "source": SOURCE_RECONFIGURE, + }, + ) + return self.async_create_entry( + next_flow=(FlowType.CONFIG_SUBENTRIES_FLOW, next_flow["flow_id"]), + data={}, + ) + + +@pytest.mark.parametrize( + ("flow_type", "ignore_translations_for_mock_domains"), + [ + (FlowType.OPTIONS_FLOW, ["fake_integration"]), + (FlowType.CONFIG_SUBENTRIES_FLOW, ["fake_integration"]), + ], +) +async def test_fix_issue_next_flow(hass: HomeAssistant, flow_type: FlowType) -> None: + """Test that that a repair flow can refer to an options flow.""" + assert await async_setup_component(hass, DOMAIN, {}) + + mock_entry = MockConfigEntry( + domain="comp", + data={}, + subentries_data=[ + { + "unique_id": "test_1", + "title": "test 1", + "subentry_type": "fake_subentry", + "data": {}, + } + ], + ) + mock_entry.add_to_hass(hass) + + ir.async_create_issue( + hass, + issue_id=flow_type, + domain="fake_integration", + is_fixable=True, + severity="error", + translation_key="fake_key", + ) + + assert (repairs := repairs_flow_manager(hass)) + + flow = await repairs.async_init("fake_integration", data={"issue_id": flow_type}) + + next_flow_type, _ = flow["next_flow"] + + assert next_flow_type is flow_type + assert mock_entry == flow["result"] diff --git a/tests/components/repairs/test_websocket_api.py b/tests/components/repairs/test_websocket_api.py index 1343a5683bd50d..b3d60ec576775b 100644 --- a/tests/components/repairs/test_websocket_api.py +++ b/tests/components/repairs/test_websocket_api.py @@ -1,21 +1,32 @@ """Test the repairs websocket API.""" +from collections.abc import Iterator +from contextlib import contextmanager from http import HTTPStatus from typing import Any from unittest.mock import ANY, AsyncMock, Mock +import orjson import pytest import voluptuous as vol from homeassistant import data_entry_flow -from homeassistant.components.repairs import RepairsFlow +from homeassistant.components.repairs import FlowType, RepairsFlow, RepairsFlowResult from homeassistant.components.repairs.const import DOMAIN +from homeassistant.config_entries import ConfigFlow from homeassistant.const import __version__ as ha_version from homeassistant.core import HomeAssistant from homeassistant.helpers import issue_registry as ir from homeassistant.setup import async_setup_component -from tests.common import MockUser, mock_platform +from tests.common import ( + MockConfigEntry, + MockModule, + MockUser, + mock_config_flow, + mock_integration, + mock_platform, +) from tests.typing import ( ClientSessionGenerator, MockHAClientWebSocket, @@ -84,6 +95,10 @@ def api_issue(issue): "issue_1": None, "issue_2": {"blah": "bleh"}, "abort_issue1": None, + "issue_3": None, + "invalid_flow": None, + "unknown_entry": None, + "unknown_entry_via_form": None, } @@ -135,6 +150,13 @@ def async_create_fix_flow( if issue_id == "abort_issue1": return MockFixFlowAbort() + if issue_id in [ + "issue_3", + "invalid_flow", + "unknown_entry", + "unknown_entry_via_form", + ]: + return MockFixFlowNextFlow() return MockFixFlow() mock_platform( @@ -371,6 +393,199 @@ async def test_fix_issue( assert msg["result"] == {"issues": []} +@contextmanager +def mock_core_config_flow() -> Iterator[None]: + """Mock a config flow.""" + + class CompConfigFlow(ConfigFlow): + """Config flow with options and subentries flow.""" + + async def async_step_user(self, user_input=None): + return self.async_show_form(step_id="user") + + async def async_step_reconfigure(self, user_input=None): + return self.async_show_form(step_id="reconfigure") + + with mock_config_flow("comp", CompConfigFlow): + yield + + +class MockFixFlowNextFlow(RepairsFlow): + """Mock flow fix supporting `next_flow`.""" + + async def async_step_init( + self, user_input: dict[str, str] | None = None + ) -> RepairsFlowResult: + """Handle the first step of a fix flow.""" + + assert self.issue_id in EXPECTED_DATA + + mock_integration(self.hass, MockModule("comp")) + mock_platform(self.hass, "comp.config_flow", None) + + entries = self.hass.config_entries.async_entries("comp") + assert len(entries) == 1 + mock_entry: MockConfigEntry = entries[0] + if self.issue_id == "unknown_entry_via_form": + return await self.async_step_user() + + with mock_core_config_flow(): + flow_type: str = FlowType.CONFIG_FLOW + match self.issue_id: + case "issue_3": + next_flow = await mock_entry.start_reconfigure_flow(self.hass) + case "invalid_flow": + flow_type = "fake_flow_type" + next_flow = {"flow_id": "fake_flow_id"} + case "unknown_entry": + next_flow = await mock_entry.start_reconfigure_flow(self.hass) + # Remove the entry to trigger UnknownEntry error. + await self.hass.config_entries.async_remove(mock_entry.entry_id) + return self.async_create_entry( + data={}, + next_flow=( + flow_type, + next_flow["flow_id"], + ), + ) + + async def async_step_user( + self, user_input: dict[str, str] | None = None + ) -> RepairsFlowResult: + """Handle an UnknownEntry error via a form. + + Test RepairsFlowResourceView.post error handling. + """ + if user_input: + entries = self.hass.config_entries.async_entries("comp") + mock_entry: MockConfigEntry = entries[0] + next_flow = await mock_entry.start_reconfigure_flow(self.hass) + await self.hass.config_entries.async_remove(mock_entry.entry_id) + return self.async_create_entry( + data={}, next_flow=(FlowType.CONFIG_FLOW, next_flow["flow_id"]) + ) + return self.async_show_form(step_id="user") + + +@pytest.mark.parametrize("ignore_translations_for_mock_domains", ["fake_integration"]) +async def test_fix_issue_next_flow( + hass: HomeAssistant, + hass_client: ClientSessionGenerator, + hass_ws_client: WebSocketGenerator, +) -> None: + """Test next_flow RepairFlows.""" + assert await async_setup_component(hass, "http", {}) + assert await async_setup_component(hass, DOMAIN, {}) + + ws_client = await hass_ws_client(hass) + client = await hass_client() + + issues = [{**DEFAULT_ISSUES[0], "issue_id": "issue_3"}] + await create_issues(hass, ws_client, issues=issues) + + mock_entry = MockConfigEntry( + domain="comp", + data={}, + ) + mock_entry.add_to_hass(hass) + + url = "/api/repairs/issues/fix" + + resp = await client.post( + url, json={"handler": "fake_integration", "issue_id": "issue_3"} + ) + + assert resp.status == HTTPStatus.OK, ( + f"Error: {resp.status} cause {await resp.text()}" + ) + + data = await resp.json() + + _, next_flow_id = data["next_flow"] + + assert data == { + "description_placeholders": None, + "flow_id": ANY, + "handler": "fake_integration", + "description": None, + "type": data_entry_flow.FlowResultType.CREATE_ENTRY, + "next_flow": [ + FlowType.CONFIG_FLOW, + next_flow_id, + ], + "result": orjson.loads(orjson.dumps(mock_entry.as_json_fragment)), + } + + +@pytest.mark.parametrize("ignore_translations_for_mock_domains", ["fake_integration"]) +async def test_fix_issue_next_flow_errors( + hass: HomeAssistant, + hass_client: ClientSessionGenerator, + hass_ws_client: WebSocketGenerator, +) -> None: + """Test next_flow RepairFlows.""" + assert await async_setup_component(hass, "http", {}) + assert await async_setup_component(hass, DOMAIN, {}) + + ws_client = await hass_ws_client(hass) + client = await hass_client() + + issues = [ + { + **DEFAULT_ISSUES[0], + "issue_id": "invalid_flow", + }, + { + **DEFAULT_ISSUES[0], + "issue_id": "unknown_entry", + }, + { + **DEFAULT_ISSUES[0], + "issue_id": "unknown_entry_via_form", + }, + ] + await create_issues(hass, ws_client, issues=issues) + mock_entry = MockConfigEntry( + domain="comp", + data={}, + ) + mock_entry.add_to_hass(hass) + + url = "/api/repairs/issues/fix" + + resp = await client.post( + url, json={"handler": "fake_integration", "issue_id": "invalid_flow"} + ) + + assert resp.status == HTTPStatus.NOT_FOUND + data = await resp.json() + assert "Invalid next_flow FlowType" in data["message"] + + resp = await client.post( + url, json={"handler": "fake_integration", "issue_id": "unknown_entry"} + ) + assert resp.status == HTTPStatus.BAD_REQUEST + data = await resp.json() + assert "not found in next_flow" in data["message"] + + # Re add removed mock entry + mock_entry = MockConfigEntry( + domain="comp", + data={}, + ) + mock_entry.add_to_hass(hass) + resp = await client.post( + url, json={"handler": "fake_integration", "issue_id": "unknown_entry_via_form"} + ) + assert resp.status == HTTPStatus.OK + data = await resp.json() + assert data["type"] == "form" + resp = await client.post(f"{url}/{data['flow_id']}", json={"submit": "True"}) + assert resp.status == HTTPStatus.BAD_REQUEST + data = await resp.json() + assert "not found in next_flow" in data["message"] + + async def test_fix_issue_unauth( hass: HomeAssistant, hass_client: ClientSessionGenerator, hass_admin_user: MockUser ) -> None: diff --git a/tests/components/sonos/test_init.py b/tests/components/sonos/test_init.py index dde22673d85a9f..cf9e44771470a9 100644 --- a/tests/components/sonos/test_init.py +++ b/tests/components/sonos/test_init.py @@ -8,6 +8,7 @@ from typing import Any from unittest.mock import MagicMock, Mock, PropertyMock, patch +from freezegun import freeze_time from freezegun.api import FrozenDateTimeFactory import pytest from requests import Response @@ -605,6 +606,70 @@ async def test_async_poll_manual_hosts_6( await hass.async_block_till_done(wait_background_tasks=True) +async def test_async_poll_manual_hosts_skips_ping_for_disabled_device( + hass: HomeAssistant, + soco_factory: SoCoMockFactory, + device_registry: dr.DeviceRegistry, + entity_registry: er.EntityRegistry, +) -> None: + """Test disabled manual-host speakers are not pinged on heartbeat.""" + soco = soco_factory.cache_mock(MockSoCo(), "10.10.10.1", "Living Room") + soco.renderingControl = Mock() + soco.renderingControl.GetVolume = Mock() + + await _setup_hass(hass) + + assert "media_player.living_room" in entity_registry.entities + + # Mark the speaker unavailable via ZGS event with VanishedDevices. + async def fire_vanish_event(): + subscription = soco.zoneGroupTopology.subscribe.return_value + sub_callback = await subscription.wait_for_callback_to_be_set() + zgs_with_vanished = f""" + + + + + + + + + """ + event = SonosMockEvent( + soco, soco.zoneGroupTopology, {"ZoneGroupState": zgs_with_vanished} + ) + sub_callback(event) + await hass.async_block_till_done(wait_background_tasks=True) + + await fire_vanish_event() + + # Verify the speaker is marked unavailable. + state = hass.states.get("media_player.living_room") + assert state is not None + assert state.state == "unavailable" + + # Now disable the device. + entry = hass.config_entries.async_entries(sonos.DOMAIN)[0] + device = device_registry.async_get_device_by_identifier( + (sonos.DOMAIN, soco.uid), entry.entry_id + ) + assert device is not None + device_registry.async_update_device( + device.id, + disabled_by=dr.DeviceEntryDisabler.USER, + ) + + # SonosSpeaker.ping uses RenderingControl.GetVolume under the hood. + soco.renderingControl.GetVolume.reset_mock() + with freeze_time(dt_util.utcnow()) as freezer: + freezer.tick(DISCOVERY_INTERVAL) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + # The disabled speaker should not have been pinged. + soco.renderingControl.GetVolume.assert_not_called() + + async def test_async_poll_manual_hosts_7( hass: HomeAssistant, soco_factory: SoCoMockFactory, diff --git a/tests/components/thread/__init__.py b/tests/components/thread/__init__.py index 0b53c879c37d67..5d4baa1d313a77 100644 --- a/tests/components/thread/__init__.py +++ b/tests/components/thread/__init__.py @@ -6,6 +6,12 @@ "0212340410445F2B5CA6F2A93A55CE570A70EFEECB0C0402A0F7F8" ) +DATASET_1_LARGER_TIMESTAMP = ( + "0E080000000000020000000300000F35060004001FFFE0020811111111222222220708FDAD70BF" + "E5AA15DD051000112233445566778899AABBCCDDEEFF030E4F70656E54687265616444656D6F01" + "0212340410445F2B5CA6F2A93A55CE570A70EFEECB0C0402A0F7F8" +) + DATASET_2 = ( "0E080000000000010000000300000F35060004001FFFE0020811111111222222330708FDAD70BF" "E5AA15DD051000112233445566778899AABBCCDDEEFF030E486f6d65417373697374616e742101" diff --git a/tests/components/thread/test_dataset_store.py b/tests/components/thread/test_dataset_store.py index 468136a79bc2f8..305d5d6ad74064 100644 --- a/tests/components/thread/test_dataset_store.py +++ b/tests/components/thread/test_dataset_store.py @@ -14,6 +14,7 @@ from . import ( DATASET_1, + DATASET_1_LARGER_TIMESTAMP, DATASET_2, DATASET_3, ROUTER_DISCOVERY_GOOGLE_1, @@ -55,12 +56,6 @@ "0212340410445F2B5CA6F2A93A55CE570A70EFEECB0C0402A0F7F8" ) -DATASET_1_LARGER_TIMESTAMP = ( - "0E080000000000020000000300000F35060004001FFFE0020811111111222222220708FDAD70BF" - "E5AA15DD051000112233445566778899AABBCCDDEEFF030E4F70656E54687265616444656D6F01" - "0212340410445F2B5CA6F2A93A55CE570A70EFEECB0C0402A0F7F8" -) - # Same as DATASET_1 but with WAKEUP_CHANNEL (type 0x4A) appended, same timestamp DATASET_1_WITH_WAKEUP_CHANNEL = ( "0E080000000000010000000300000F35060004001FFFE0020811111111222222220708FDAD70BF" @@ -97,7 +92,10 @@ async def test_add_invalid_dataset(hass: HomeAssistant) -> None: async def test_add_dataset_twice(hass: HomeAssistant) -> None: """Test adding dataset twice does nothing.""" - await dataset_store.async_add_dataset(hass, "source", DATASET_1) + assert ( + await dataset_store.async_add_dataset(hass, "source", DATASET_1) + is dataset_store.DatasetAddResult.STORED + ) store = await dataset_store.async_get_store(hass) assert len(store.datasets) == 1 @@ -116,9 +114,14 @@ async def test_add_dataset_reordered(hass: HomeAssistant) -> None: assert len(store.datasets) == 1 created = list(store.datasets.values())[0].created - await dataset_store.async_add_dataset(hass, "new_source", DATASET_1_REORDERED) + assert ( + await dataset_store.async_add_dataset(hass, "new_source", DATASET_1_REORDERED) + is dataset_store.DatasetAddResult.STORED + ) assert len(store.datasets) == 1 assert list(store.datasets.values())[0].created == created + # STORED is about the dataset, not the bytes: the stored TLV is untouched. + assert list(store.datasets.values())[0].tlv == DATASET_1 async def test_delete_dataset_twice(hass: HomeAssistant) -> None: @@ -242,7 +245,10 @@ async def test_update_dataset_newer( ) -> None: """Test updating a dataset.""" await dataset_store.async_add_dataset(hass, "test", DATASET_1) - await dataset_store.async_add_dataset(hass, "test", DATASET_1_LARGER_TIMESTAMP) + assert ( + await dataset_store.async_add_dataset(hass, "test", DATASET_1_LARGER_TIMESTAMP) + is dataset_store.DatasetAddResult.STORED + ) store = await dataset_store.async_get_store(hass) assert len(store.datasets) == 1 @@ -263,7 +269,10 @@ async def test_update_dataset_older( ) -> None: """Test updating a dataset.""" await dataset_store.async_add_dataset(hass, "test", DATASET_1_LARGER_TIMESTAMP) - await dataset_store.async_add_dataset(hass, "test", DATASET_1) + assert ( + await dataset_store.async_add_dataset(hass, "test", DATASET_1) + is dataset_store.DatasetAddResult.DISCARDED + ) store = await dataset_store.async_get_store(hass) assert len(store.datasets) == 1 @@ -1107,3 +1116,79 @@ async def mock_remove_service_listener(listener: Any): == TEST_BORDER_AGENT_EXTENDED_ADDRESS.hex() ) assert await dataset_store.async_get_preferred_dataset(hass) is None + + +async def test_add_dataset_returns_stored(hass: HomeAssistant) -> None: + """Test adding a dataset for a new network reports it was stored.""" + store = await dataset_store.async_get_store(hass) + + assert ( + store.async_add("test", DATASET_1, None, None) + is dataset_store.DatasetAddResult.STORED + ) + assert ( + await dataset_store.async_add_dataset(hass, "test", DATASET_2) + is dataset_store.DatasetAddResult.STORED + ) + + +async def test_add_dataset_discarded_by_concurrent_write(hass: HomeAssistant) -> None: + """Test an add beaten to the store by a newer dataset is discarded.""" + await dataset_store.async_add_dataset(hass, "test", DATASET_1) + store = await dataset_store.async_get_store(hass) + + await dataset_store.async_add_dataset(hass, "other", DATASET_1_LARGER_TIMESTAMP) + + assert ( + await dataset_store.async_add_dataset(hass, "test", DATASET_1) + is dataset_store.DatasetAddResult.DISCARDED + ) + assert len(store.datasets) == 1 + assert list(store.datasets.values())[0].tlv == DATASET_1_LARGER_TIMESTAMP + + +async def test_add_dataset_stored_refreshes_border_agent(hass: HomeAssistant) -> None: + """Test STORED covers an identical dataset refreshing the border agent.""" + await dataset_store.async_add_dataset(hass, "test", DATASET_1) + store = await dataset_store.async_get_store(hass) + + assert ( + await dataset_store.async_add_dataset( + hass, + "test", + DATASET_1, + preferred_border_agent_id="230C6A1AC57F6F4BE262ACF32E5EF52C", + preferred_extended_address="AEEB2F594B570BBF", + ) + is dataset_store.DatasetAddResult.STORED + ) + entry = list(store.datasets.values())[0] + assert entry.preferred_border_agent_id == "230C6A1AC57F6F4BE262ACF32E5EF52C" + assert entry.preferred_extended_address == "AEEB2F594B570BBF" + + +async def test_add_dataset_discarded_keeps_border_agent(hass: HomeAssistant) -> None: + """Test DISCARDED means nothing about the entry changed.""" + await dataset_store.async_add_dataset( + hass, + "test", + DATASET_1_LARGER_TIMESTAMP, + preferred_border_agent_id="230C6A1AC57F6F4BE262ACF32E5EF52C", + preferred_extended_address="AEEB2F594B570BBF", + ) + store = await dataset_store.async_get_store(hass) + + assert ( + await dataset_store.async_add_dataset( + hass, + "test", + DATASET_1, + preferred_border_agent_id="230C6A1AC57F6F4BE262ACF32E5EF52D", + preferred_extended_address="AEEB2F594B570BB0", + ) + is dataset_store.DatasetAddResult.DISCARDED + ) + entry = list(store.datasets.values())[0] + assert entry.tlv == DATASET_1_LARGER_TIMESTAMP + assert entry.preferred_border_agent_id == "230C6A1AC57F6F4BE262ACF32E5EF52C" + assert entry.preferred_extended_address == "AEEB2F594B570BBF" diff --git a/tests/components/thread/test_websocket_api.py b/tests/components/thread/test_websocket_api.py index 1876cfa956d84b..6cd938eb0f83cb 100644 --- a/tests/components/thread/test_websocket_api.py +++ b/tests/components/thread/test_websocket_api.py @@ -11,6 +11,7 @@ from . import ( DATASET_1, + DATASET_1_LARGER_TIMESTAMP, DATASET_2, DATASET_3, ROUTER_DISCOVERY_GOOGLE_1, @@ -34,7 +35,7 @@ async def test_add_dataset( ) msg = await client.receive_json() assert msg["success"] - assert msg["result"] is None + assert msg["result"] == {"result": "stored"} store = await dataset_store.async_get_store(hass) assert len(store.datasets) == 1 @@ -43,6 +44,32 @@ async def test_add_dataset( assert dataset.tlv == DATASET_1 +async def test_add_dataset_discarded( + hass: HomeAssistant, hass_ws_client: WebSocketGenerator +) -> None: + """Test a dataset the store discards is reported as discarded, not stored. + + The command still succeeds -- existing callers treat any error as a + failed transfer -- but the payload says the dataset was discarded. + """ + assert await async_setup_component(hass, DOMAIN, {}) + await hass.async_block_till_done() + await dataset_store.async_add_dataset(hass, "test", DATASET_1_LARGER_TIMESTAMP) + + client = await hass_ws_client(hass) + + await client.send_json( + {"id": 1, "type": "thread/add_dataset_tlv", "source": "test", "tlv": DATASET_1} + ) + msg = await client.receive_json() + assert msg["success"] + assert msg["result"] == {"result": "discarded"} + + store = await dataset_store.async_get_store(hass) + assert len(store.datasets) == 1 + assert next(iter(store.datasets.values())).tlv == DATASET_1_LARGER_TIMESTAMP + + async def test_add_invalid_dataset( hass: HomeAssistant, hass_ws_client: WebSocketGenerator ) -> None: @@ -237,7 +264,7 @@ async def test_set_preferred_border_agent( ) msg = await client.receive_json() assert msg["success"] - assert msg["result"] is None + assert msg["result"] == {"result": "stored"} await client.send_json_auto_id({"type": "thread/list_datasets"}) msg = await client.receive_json() diff --git a/tests/components/tuya/snapshots/test_init.ambr b/tests/components/tuya/snapshots/test_init.ambr index 145718c8fbfd9e..43f740196fe052 100644 --- a/tests/components/tuya/snapshots/test_init.ambr +++ b/tests/components/tuya/snapshots/test_init.ambr @@ -2450,7 +2450,7 @@ 'labels': set({ }), 'manufacturer': 'Tuya', - 'model': 'Chasing Tape Light (unsupported)', + 'model': 'Chasing Tape Light', 'model_id': 'expmpw4xxd0kkifb', 'name': 'Chasing Tape Light', 'name_by_user': None, diff --git a/tests/components/tuya/snapshots/test_light.ambr b/tests/components/tuya/snapshots/test_light.ambr index a0aef98c4c163d..a4c70cd5c273d6 100644 --- a/tests/components/tuya/snapshots/test_light.ambr +++ b/tests/components/tuya/snapshots/test_light.ambr @@ -808,6 +808,84 @@ 'state': 'off', }) # --- +# name: test_platform_setup_and_discovery[light.chasing_tape_light-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': dict({ + : 6500, + : 2000, + : list([ + , + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'light', + 'entity_category': None, + 'entity_id': 'light.chasing_tape_light', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': None, + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'tuya.bfikk0dxx4wpmpxeddchswitch_led', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[light.chasing_tape_light-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 255, + : , + : 2000, + : 'Chasing Tape Light', + : tuple( + 30.601, + 94.547, + ), + : 6500, + : 2000, + : tuple( + 255, + 137, + 14, + ), + : list([ + , + ]), + : , + : tuple( + 0.598, + 0.383, + ), + }), + 'context': , + 'entity_id': 'light.chasing_tape_light', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- # name: test_platform_setup_and_discovery[light.cleverio_pf100_light-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ diff --git a/tests/components/unifi/test_sensor.py b/tests/components/unifi/test_sensor.py index f610b515ebc24e..bf346b4b12d35e 100644 --- a/tests/components/unifi/test_sensor.py +++ b/tests/components/unifi/test_sensor.py @@ -362,6 +362,49 @@ }, ] +UPS_DEVICE_1 = deepcopy(PDU_DEVICE_1) +UPS_DEVICE_1.update( + { + "device_id": "mock-ups", + "mac": "02:00:00:00:00:01", + "model": "USPDA2B", + "name": "Dummy UPS 2U Pro", + "type": "usp", + "outlet_table": [ + { + "index": 1, + "relay_state": True, + "cycle_enabled": False, + "name": "Outlet 1", + "outlet_caps": 65539, + "outlet_voltage": 121.7, + "outlet_current": 0.35, + "outlet_power": 42.5, + "outlet_power_factor": 0.98, + }, + { + "index": 2, + "relay_state": True, + "cycle_enabled": False, + "has_metering": True, + "name": "Outlet 2", + "outlet_voltage": 121.7, + "outlet_current": 0.1, + "outlet_power": 12.5, + "outlet_power_factor": 0.95, + }, + ], + "outlet_overrides": [ + { + "cycle_enabled": False, + "name": "Outlet 1", + "relay_state": True, + "index": 1, + } + ], + } +) + @pytest.mark.parametrize( "config_entry_options", @@ -956,6 +999,27 @@ async def test_outlet_power_readings( assert hass.states.get(f"sensor.{entity_id}").state == expected_update_value +@pytest.mark.parametrize("device_payload", [[UPS_DEVICE_1]]) +@pytest.mark.usefixtures("config_entry_setup") +async def test_outlet_power_reading_extended_caps( + hass: HomeAssistant, + mock_websocket_message: WebsocketMessageMock, +) -> None: + """Test outlet power reporting with extended capability bits and numeric values.""" + entity_id = "sensor.dummy_ups_2u_pro_outlet_1_outlet_power" + assert hass.states.get(entity_id).state == "42.5" + assert ( + hass.states.get("sensor.dummy_ups_2u_pro_outlet_2_outlet_power").state == "12.5" + ) + + updated_device_data = deepcopy(UPS_DEVICE_1) + updated_device_data["outlet_table"][0]["outlet_power"] = 43.5 + mock_websocket_message(message=MessageKey.DEVICE, data=updated_device_data) + await hass.async_block_till_done() + + assert hass.states.get(entity_id).state == "43.5" + + @pytest.mark.parametrize( "device_payload", [ diff --git a/tests/components/zwave_js/conftest.py b/tests/components/zwave_js/conftest.py index 4d4ce3e01b41e2..3863bac207bc71 100644 --- a/tests/components/zwave_js/conftest.py +++ b/tests/components/zwave_js/conftest.py @@ -256,6 +256,12 @@ def leviton_zw4sf_state_fixture() -> dict[str, Any]: return load_json_object_fixture("leviton_zw4sf_state.json", DOMAIN) +@pytest.fixture(name="leviton_vrf01_state", scope="package") +def leviton_vrf01_state_fixture() -> dict[str, Any]: + """Load the Leviton VRF01 node state fixture data.""" + return load_json_object_fixture("leviton_vrf01_state.json", DOMAIN) + + @pytest.fixture(name="fan_honeywell_39358_state", scope="package") def fan_honeywell_39358_state_fixture() -> dict[str, Any]: """Load the fan node state fixture data.""" @@ -1071,6 +1077,14 @@ def leviton_zw4sf_fixture(client, leviton_zw4sf_state) -> Node: return node +@pytest.fixture(name="leviton_vrf01") +def leviton_vrf01_fixture(client, leviton_vrf01_state) -> Node: + """Mock a fan node.""" + node = Node(client, copy.deepcopy(leviton_vrf01_state)) + client.driver.controller.nodes[node.node_id] = node + return node + + @pytest.fixture(name="fan_honeywell_39358") def fan_honeywell_39358_fixture(client, fan_honeywell_39358_state) -> Node: """Mock a fan node.""" diff --git a/tests/components/zwave_js/fixtures/leviton_vrf01_state.json b/tests/components/zwave_js/fixtures/leviton_vrf01_state.json new file mode 100644 index 00000000000000..bc500f58cdce63 --- /dev/null +++ b/tests/components/zwave_js/fixtures/leviton_vrf01_state.json @@ -0,0 +1,10439 @@ +{ + "nodeId": 35, + "index": 0, + "status": 4, + "ready": true, + "isListening": true, + "isRouting": true, + "isSecure": false, + "manufacturerId": 29, + "productId": 521, + "productType": 4097, + "firmwareVersion": "0.5", + "name": "Fan", + "location": "", + "deviceConfig": { + "filename": "/data/db/devices/0x001d/vrf01.json", + "isEmbedded": true, + "manufacturer": "Leviton", + "manufacturerId": 29, + "label": "VRF01", + "description": "Scene Capable Quiet Fan Speed Control", + "devices": [ + { + "productType": 4097, + "productId": 521 + }, + { + "productType": 4097, + "productId": 820 + } + ], + "firmwareVersion": { + "min": "0.0", + "max": "255.255" + }, + "preferred": false, + "associations": { + "1": { + "groupId": 1, + "label": "Lifeline", + "maxNodes": 5, + "isLifeline": true, + "multiChannel": "auto" + } + } + }, + "label": "VRF01", + "interviewAttempts": 1, + "isFrequentListening": false, + "maxDataRate": 40000, + "supportedDataRates": [40000], + "protocolVersion": 1, + "supportsBeaming": false, + "supportsSecurity": false, + "nodeType": 1, + "deviceClass": { + "basic": { + "key": 4, + "label": "Routing End Node" + }, + "generic": { + "key": 17, + "label": "Multilevel Switch" + }, + "specific": { + "key": 4, + "label": "Multilevel Scene Switch" + } + }, + "interviewStage": "Complete", + "deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x001d:0x1001:0x0209:0.5", + "statistics": { + "commandsTX": 55, + "commandsRX": 59, + "commandsDroppedRX": 2, + "commandsDroppedTX": 0, + "timeoutResponse": 23, + "lastSeen": "2026-07-04T16:21:27.053Z", + "rtt": 41.6, + "rssi": -84, + "lwr": { + "protocolDataRate": 2, + "repeaters": [11], + "rssi": -87, + "repeaterRSSI": [0] + }, + "nlwr": { + "protocolDataRate": 2, + "repeaters": [10], + "rssi": -72, + "repeaterRSSI": [0] + } + }, + "highestSecurityClass": -1, + "isControllerNode": false, + "keepAwake": false, + "lastSeen": "2026-07-04T16:21:27.053Z", + "protocol": 0, + "canSleep": false, + "hasSUCReturnRoute": true, + "manufacturer": "Leviton", + "values": [ + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "Down", + "propertyName": "Down", + "ccVersion": 1, + "metadata": { + "type": "boolean", + "readable": false, + "writeable": true, + "label": "Perform a level change (Down)", + "ccSpecific": { + "switchType": 2 + }, + "valueChangeOptions": ["transitionDuration"], + "states": { + "true": "Start", + "false": "Stop" + }, + "stateful": true, + "secret": false + }, + "value": false + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "currentValue", + "propertyName": "currentValue", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Current value", + "min": 0, + "max": 99, + "stateful": true, + "secret": false + }, + "value": 73 + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "targetValue", + "propertyName": "targetValue", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Target value", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 99, + "stateful": true, + "secret": false + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "Up", + "propertyName": "Up", + "ccVersion": 1, + "metadata": { + "type": "boolean", + "readable": false, + "writeable": true, + "label": "Perform a level change (Up)", + "ccSpecific": { + "switchType": 2 + }, + "valueChangeOptions": ["transitionDuration"], + "states": { + "true": "Start", + "false": "Stop" + }, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "duration", + "propertyName": "duration", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": false, + "label": "Remaining duration", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "restorePrevious", + "propertyName": "restorePrevious", + "ccVersion": 1, + "metadata": { + "type": "boolean", + "readable": false, + "writeable": true, + "label": "Restore previous value", + "states": { + "true": "Restore" + }, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 43, + "commandClassName": "Scene Activation", + "property": "sceneId", + "propertyName": "sceneId", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Scene ID", + "valueChangeOptions": ["transitionDuration"], + "min": 1, + "max": 255, + "stateful": false, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 43, + "commandClassName": "Scene Activation", + "property": "dimmingDuration", + "propertyName": "dimmingDuration", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 1, + "propertyName": "level", + "propertyKeyName": "1", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (1)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 1, + "propertyName": "dimmingDuration", + "propertyKeyName": "1", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (1)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 2, + "propertyName": "level", + "propertyKeyName": "2", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (2)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 2, + "propertyName": "dimmingDuration", + "propertyKeyName": "2", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (2)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 3, + "propertyName": "level", + "propertyKeyName": "3", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (3)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 3, + "propertyName": "dimmingDuration", + "propertyKeyName": "3", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (3)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 4, + "propertyName": "level", + "propertyKeyName": "4", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (4)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 4, + "propertyName": "dimmingDuration", + "propertyKeyName": "4", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (4)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 5, + "propertyName": "level", + "propertyKeyName": "5", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (5)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 5, + "propertyName": "dimmingDuration", + "propertyKeyName": "5", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (5)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 6, + "propertyName": "level", + "propertyKeyName": "6", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (6)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 6, + "propertyName": "dimmingDuration", + "propertyKeyName": "6", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (6)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 7, + "propertyName": "level", + "propertyKeyName": "7", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (7)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 7, + "propertyName": "dimmingDuration", + "propertyKeyName": "7", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (7)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 8, + "propertyName": "level", + "propertyKeyName": "8", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (8)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 8, + "propertyName": "dimmingDuration", + "propertyKeyName": "8", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (8)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 9, + "propertyName": "level", + "propertyKeyName": "9", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (9)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 9, + "propertyName": "dimmingDuration", + "propertyKeyName": "9", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (9)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 10, + "propertyName": "level", + "propertyKeyName": "10", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (10)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 10, + "propertyName": "dimmingDuration", + "propertyKeyName": "10", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (10)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 11, + "propertyName": "level", + "propertyKeyName": "11", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (11)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 11, + "propertyName": "dimmingDuration", + "propertyKeyName": "11", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (11)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 12, + "propertyName": "level", + "propertyKeyName": "12", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (12)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 12, + "propertyName": "dimmingDuration", + "propertyKeyName": "12", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (12)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 13, + "propertyName": "level", + "propertyKeyName": "13", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (13)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 13, + "propertyName": "dimmingDuration", + "propertyKeyName": "13", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (13)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 14, + "propertyName": "level", + "propertyKeyName": "14", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (14)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 14, + "propertyName": "dimmingDuration", + "propertyKeyName": "14", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (14)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 15, + "propertyName": "level", + "propertyKeyName": "15", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (15)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 15, + "propertyName": "dimmingDuration", + "propertyKeyName": "15", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (15)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 16, + "propertyName": "level", + "propertyKeyName": "16", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (16)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 16, + "propertyName": "dimmingDuration", + "propertyKeyName": "16", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (16)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 17, + "propertyName": "level", + "propertyKeyName": "17", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (17)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 17, + "propertyName": "dimmingDuration", + "propertyKeyName": "17", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (17)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 18, + "propertyName": "level", + "propertyKeyName": "18", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (18)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 18, + "propertyName": "dimmingDuration", + "propertyKeyName": "18", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (18)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 19, + "propertyName": "level", + "propertyKeyName": "19", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (19)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 19, + "propertyName": "dimmingDuration", + "propertyKeyName": "19", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (19)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 20, + "propertyName": "level", + "propertyKeyName": "20", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (20)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 20, + "propertyName": "dimmingDuration", + "propertyKeyName": "20", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (20)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 21, + "propertyName": "level", + "propertyKeyName": "21", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (21)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 21, + "propertyName": "dimmingDuration", + "propertyKeyName": "21", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (21)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 22, + "propertyName": "level", + "propertyKeyName": "22", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (22)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 22, + "propertyName": "dimmingDuration", + "propertyKeyName": "22", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (22)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 23, + "propertyName": "level", + "propertyKeyName": "23", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (23)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 23, + "propertyName": "dimmingDuration", + "propertyKeyName": "23", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (23)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 24, + "propertyName": "level", + "propertyKeyName": "24", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (24)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 24, + "propertyName": "dimmingDuration", + "propertyKeyName": "24", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (24)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 25, + "propertyName": "level", + "propertyKeyName": "25", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (25)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 25, + "propertyName": "dimmingDuration", + "propertyKeyName": "25", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (25)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 26, + "propertyName": "level", + "propertyKeyName": "26", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (26)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 26, + "propertyName": "dimmingDuration", + "propertyKeyName": "26", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (26)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 27, + "propertyName": "level", + "propertyKeyName": "27", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (27)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 27, + "propertyName": "dimmingDuration", + "propertyKeyName": "27", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (27)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 28, + "propertyName": "level", + "propertyKeyName": "28", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (28)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 28, + "propertyName": "dimmingDuration", + "propertyKeyName": "28", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (28)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 29, + "propertyName": "level", + "propertyKeyName": "29", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (29)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 29, + "propertyName": "dimmingDuration", + "propertyKeyName": "29", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (29)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 30, + "propertyName": "level", + "propertyKeyName": "30", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (30)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 30, + "propertyName": "dimmingDuration", + "propertyKeyName": "30", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (30)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 31, + "propertyName": "level", + "propertyKeyName": "31", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (31)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 31, + "propertyName": "dimmingDuration", + "propertyKeyName": "31", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (31)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 32, + "propertyName": "level", + "propertyKeyName": "32", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (32)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 32, + "propertyName": "dimmingDuration", + "propertyKeyName": "32", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (32)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 33, + "propertyName": "level", + "propertyKeyName": "33", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (33)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 33, + "propertyName": "dimmingDuration", + "propertyKeyName": "33", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (33)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 34, + "propertyName": "level", + "propertyKeyName": "34", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (34)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 34, + "propertyName": "dimmingDuration", + "propertyKeyName": "34", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (34)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 35, + "propertyName": "level", + "propertyKeyName": "35", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (35)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 35, + "propertyName": "dimmingDuration", + "propertyKeyName": "35", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (35)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 36, + "propertyName": "level", + "propertyKeyName": "36", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (36)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 36, + "propertyName": "dimmingDuration", + "propertyKeyName": "36", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (36)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 37, + "propertyName": "level", + "propertyKeyName": "37", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (37)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 37, + "propertyName": "dimmingDuration", + "propertyKeyName": "37", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (37)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 38, + "propertyName": "level", + "propertyKeyName": "38", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (38)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 38, + "propertyName": "dimmingDuration", + "propertyKeyName": "38", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (38)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 39, + "propertyName": "level", + "propertyKeyName": "39", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (39)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 39, + "propertyName": "dimmingDuration", + "propertyKeyName": "39", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (39)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 40, + "propertyName": "level", + "propertyKeyName": "40", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (40)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 40, + "propertyName": "dimmingDuration", + "propertyKeyName": "40", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (40)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 41, + "propertyName": "level", + "propertyKeyName": "41", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (41)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 41, + "propertyName": "dimmingDuration", + "propertyKeyName": "41", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (41)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 42, + "propertyName": "level", + "propertyKeyName": "42", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (42)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 42, + "propertyName": "dimmingDuration", + "propertyKeyName": "42", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (42)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 43, + "propertyName": "level", + "propertyKeyName": "43", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (43)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 43, + "propertyName": "dimmingDuration", + "propertyKeyName": "43", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (43)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 44, + "propertyName": "level", + "propertyKeyName": "44", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (44)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 44, + "propertyName": "dimmingDuration", + "propertyKeyName": "44", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (44)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 45, + "propertyName": "level", + "propertyKeyName": "45", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (45)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 45, + "propertyName": "dimmingDuration", + "propertyKeyName": "45", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (45)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 46, + "propertyName": "level", + "propertyKeyName": "46", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (46)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 46, + "propertyName": "dimmingDuration", + "propertyKeyName": "46", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (46)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 47, + "propertyName": "level", + "propertyKeyName": "47", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (47)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 47, + "propertyName": "dimmingDuration", + "propertyKeyName": "47", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (47)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 48, + "propertyName": "level", + "propertyKeyName": "48", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (48)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 48, + "propertyName": "dimmingDuration", + "propertyKeyName": "48", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (48)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 49, + "propertyName": "level", + "propertyKeyName": "49", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (49)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 49, + "propertyName": "dimmingDuration", + "propertyKeyName": "49", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (49)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 50, + "propertyName": "level", + "propertyKeyName": "50", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (50)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 50, + "propertyName": "dimmingDuration", + "propertyKeyName": "50", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (50)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 51, + "propertyName": "level", + "propertyKeyName": "51", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (51)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 51, + "propertyName": "dimmingDuration", + "propertyKeyName": "51", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (51)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 52, + "propertyName": "level", + "propertyKeyName": "52", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (52)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 52, + "propertyName": "dimmingDuration", + "propertyKeyName": "52", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (52)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 53, + "propertyName": "level", + "propertyKeyName": "53", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (53)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 53, + "propertyName": "dimmingDuration", + "propertyKeyName": "53", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (53)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 54, + "propertyName": "level", + "propertyKeyName": "54", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (54)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 54, + "propertyName": "dimmingDuration", + "propertyKeyName": "54", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (54)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 55, + "propertyName": "level", + "propertyKeyName": "55", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (55)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 55, + "propertyName": "dimmingDuration", + "propertyKeyName": "55", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (55)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 56, + "propertyName": "level", + "propertyKeyName": "56", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (56)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 56, + "propertyName": "dimmingDuration", + "propertyKeyName": "56", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (56)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 57, + "propertyName": "level", + "propertyKeyName": "57", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (57)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 57, + "propertyName": "dimmingDuration", + "propertyKeyName": "57", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (57)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 58, + "propertyName": "level", + "propertyKeyName": "58", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (58)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 58, + "propertyName": "dimmingDuration", + "propertyKeyName": "58", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (58)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 59, + "propertyName": "level", + "propertyKeyName": "59", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (59)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 59, + "propertyName": "dimmingDuration", + "propertyKeyName": "59", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (59)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 60, + "propertyName": "level", + "propertyKeyName": "60", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (60)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 60, + "propertyName": "dimmingDuration", + "propertyKeyName": "60", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (60)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 61, + "propertyName": "level", + "propertyKeyName": "61", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (61)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 61, + "propertyName": "dimmingDuration", + "propertyKeyName": "61", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (61)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 62, + "propertyName": "level", + "propertyKeyName": "62", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (62)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 62, + "propertyName": "dimmingDuration", + "propertyKeyName": "62", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (62)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 63, + "propertyName": "level", + "propertyKeyName": "63", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (63)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 63, + "propertyName": "dimmingDuration", + "propertyKeyName": "63", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (63)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 64, + "propertyName": "level", + "propertyKeyName": "64", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (64)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 64, + "propertyName": "dimmingDuration", + "propertyKeyName": "64", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (64)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 65, + "propertyName": "level", + "propertyKeyName": "65", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (65)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 65, + "propertyName": "dimmingDuration", + "propertyKeyName": "65", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (65)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 66, + "propertyName": "level", + "propertyKeyName": "66", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (66)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 66, + "propertyName": "dimmingDuration", + "propertyKeyName": "66", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (66)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 67, + "propertyName": "level", + "propertyKeyName": "67", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (67)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 67, + "propertyName": "dimmingDuration", + "propertyKeyName": "67", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (67)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 68, + "propertyName": "level", + "propertyKeyName": "68", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (68)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 68, + "propertyName": "dimmingDuration", + "propertyKeyName": "68", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (68)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 69, + "propertyName": "level", + "propertyKeyName": "69", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (69)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 69, + "propertyName": "dimmingDuration", + "propertyKeyName": "69", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (69)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 70, + "propertyName": "level", + "propertyKeyName": "70", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (70)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 70, + "propertyName": "dimmingDuration", + "propertyKeyName": "70", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (70)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 71, + "propertyName": "level", + "propertyKeyName": "71", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (71)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 71, + "propertyName": "dimmingDuration", + "propertyKeyName": "71", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (71)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 72, + "propertyName": "level", + "propertyKeyName": "72", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (72)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 72, + "propertyName": "dimmingDuration", + "propertyKeyName": "72", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (72)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 73, + "propertyName": "level", + "propertyKeyName": "73", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (73)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 73, + "propertyName": "dimmingDuration", + "propertyKeyName": "73", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (73)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 74, + "propertyName": "level", + "propertyKeyName": "74", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (74)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 74, + "propertyName": "dimmingDuration", + "propertyKeyName": "74", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (74)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 75, + "propertyName": "level", + "propertyKeyName": "75", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (75)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 75, + "propertyName": "dimmingDuration", + "propertyKeyName": "75", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (75)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 76, + "propertyName": "level", + "propertyKeyName": "76", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (76)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 76, + "propertyName": "dimmingDuration", + "propertyKeyName": "76", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (76)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 77, + "propertyName": "level", + "propertyKeyName": "77", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (77)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 77, + "propertyName": "dimmingDuration", + "propertyKeyName": "77", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (77)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 78, + "propertyName": "level", + "propertyKeyName": "78", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (78)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 78, + "propertyName": "dimmingDuration", + "propertyKeyName": "78", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (78)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 79, + "propertyName": "level", + "propertyKeyName": "79", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (79)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 79, + "propertyName": "dimmingDuration", + "propertyKeyName": "79", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (79)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 80, + "propertyName": "level", + "propertyKeyName": "80", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (80)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 80, + "propertyName": "dimmingDuration", + "propertyKeyName": "80", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (80)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 81, + "propertyName": "level", + "propertyKeyName": "81", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (81)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 81, + "propertyName": "dimmingDuration", + "propertyKeyName": "81", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (81)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 82, + "propertyName": "level", + "propertyKeyName": "82", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (82)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 82, + "propertyName": "dimmingDuration", + "propertyKeyName": "82", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (82)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 83, + "propertyName": "level", + "propertyKeyName": "83", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (83)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 83, + "propertyName": "dimmingDuration", + "propertyKeyName": "83", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (83)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 84, + "propertyName": "level", + "propertyKeyName": "84", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (84)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 84, + "propertyName": "dimmingDuration", + "propertyKeyName": "84", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (84)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 85, + "propertyName": "level", + "propertyKeyName": "85", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (85)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 85, + "propertyName": "dimmingDuration", + "propertyKeyName": "85", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (85)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 86, + "propertyName": "level", + "propertyKeyName": "86", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (86)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 86, + "propertyName": "dimmingDuration", + "propertyKeyName": "86", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (86)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 87, + "propertyName": "level", + "propertyKeyName": "87", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (87)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 87, + "propertyName": "dimmingDuration", + "propertyKeyName": "87", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (87)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 88, + "propertyName": "level", + "propertyKeyName": "88", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (88)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 88, + "propertyName": "dimmingDuration", + "propertyKeyName": "88", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (88)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 89, + "propertyName": "level", + "propertyKeyName": "89", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (89)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 89, + "propertyName": "dimmingDuration", + "propertyKeyName": "89", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (89)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 90, + "propertyName": "level", + "propertyKeyName": "90", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (90)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 90, + "propertyName": "dimmingDuration", + "propertyKeyName": "90", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (90)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 91, + "propertyName": "level", + "propertyKeyName": "91", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (91)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 91, + "propertyName": "dimmingDuration", + "propertyKeyName": "91", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (91)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 92, + "propertyName": "level", + "propertyKeyName": "92", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (92)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 92, + "propertyName": "dimmingDuration", + "propertyKeyName": "92", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (92)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 93, + "propertyName": "level", + "propertyKeyName": "93", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (93)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 93, + "propertyName": "dimmingDuration", + "propertyKeyName": "93", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (93)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 94, + "propertyName": "level", + "propertyKeyName": "94", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (94)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 94, + "propertyName": "dimmingDuration", + "propertyKeyName": "94", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (94)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 95, + "propertyName": "level", + "propertyKeyName": "95", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (95)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 95, + "propertyName": "dimmingDuration", + "propertyKeyName": "95", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (95)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 96, + "propertyName": "level", + "propertyKeyName": "96", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (96)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 96, + "propertyName": "dimmingDuration", + "propertyKeyName": "96", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (96)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 97, + "propertyName": "level", + "propertyKeyName": "97", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (97)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 97, + "propertyName": "dimmingDuration", + "propertyKeyName": "97", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (97)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 98, + "propertyName": "level", + "propertyKeyName": "98", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (98)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 98, + "propertyName": "dimmingDuration", + "propertyKeyName": "98", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (98)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 99, + "propertyName": "level", + "propertyKeyName": "99", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (99)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 99, + "propertyName": "dimmingDuration", + "propertyKeyName": "99", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (99)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 100, + "propertyName": "level", + "propertyKeyName": "100", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (100)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 100, + "propertyName": "dimmingDuration", + "propertyKeyName": "100", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (100)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 101, + "propertyName": "level", + "propertyKeyName": "101", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (101)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 101, + "propertyName": "dimmingDuration", + "propertyKeyName": "101", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (101)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 102, + "propertyName": "level", + "propertyKeyName": "102", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (102)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 102, + "propertyName": "dimmingDuration", + "propertyKeyName": "102", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (102)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 103, + "propertyName": "level", + "propertyKeyName": "103", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (103)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 103, + "propertyName": "dimmingDuration", + "propertyKeyName": "103", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (103)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 104, + "propertyName": "level", + "propertyKeyName": "104", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (104)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 104, + "propertyName": "dimmingDuration", + "propertyKeyName": "104", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (104)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 105, + "propertyName": "level", + "propertyKeyName": "105", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (105)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 105, + "propertyName": "dimmingDuration", + "propertyKeyName": "105", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (105)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 106, + "propertyName": "level", + "propertyKeyName": "106", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (106)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 106, + "propertyName": "dimmingDuration", + "propertyKeyName": "106", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (106)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 107, + "propertyName": "level", + "propertyKeyName": "107", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (107)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 107, + "propertyName": "dimmingDuration", + "propertyKeyName": "107", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (107)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 108, + "propertyName": "level", + "propertyKeyName": "108", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (108)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 108, + "propertyName": "dimmingDuration", + "propertyKeyName": "108", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (108)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 109, + "propertyName": "level", + "propertyKeyName": "109", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (109)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 109, + "propertyName": "dimmingDuration", + "propertyKeyName": "109", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (109)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 110, + "propertyName": "level", + "propertyKeyName": "110", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (110)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 110, + "propertyName": "dimmingDuration", + "propertyKeyName": "110", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (110)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 111, + "propertyName": "level", + "propertyKeyName": "111", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (111)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 111, + "propertyName": "dimmingDuration", + "propertyKeyName": "111", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (111)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 112, + "propertyName": "level", + "propertyKeyName": "112", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (112)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 112, + "propertyName": "dimmingDuration", + "propertyKeyName": "112", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (112)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 113, + "propertyName": "level", + "propertyKeyName": "113", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (113)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 113, + "propertyName": "dimmingDuration", + "propertyKeyName": "113", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (113)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 114, + "propertyName": "level", + "propertyKeyName": "114", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (114)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 114, + "propertyName": "dimmingDuration", + "propertyKeyName": "114", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (114)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 115, + "propertyName": "level", + "propertyKeyName": "115", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (115)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 115, + "propertyName": "dimmingDuration", + "propertyKeyName": "115", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (115)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 116, + "propertyName": "level", + "propertyKeyName": "116", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (116)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 116, + "propertyName": "dimmingDuration", + "propertyKeyName": "116", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (116)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 117, + "propertyName": "level", + "propertyKeyName": "117", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (117)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 117, + "propertyName": "dimmingDuration", + "propertyKeyName": "117", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (117)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 118, + "propertyName": "level", + "propertyKeyName": "118", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (118)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 118, + "propertyName": "dimmingDuration", + "propertyKeyName": "118", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (118)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 119, + "propertyName": "level", + "propertyKeyName": "119", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (119)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 119, + "propertyName": "dimmingDuration", + "propertyKeyName": "119", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (119)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 120, + "propertyName": "level", + "propertyKeyName": "120", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (120)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 120, + "propertyName": "dimmingDuration", + "propertyKeyName": "120", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (120)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 121, + "propertyName": "level", + "propertyKeyName": "121", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (121)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 121, + "propertyName": "dimmingDuration", + "propertyKeyName": "121", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (121)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 122, + "propertyName": "level", + "propertyKeyName": "122", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (122)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 122, + "propertyName": "dimmingDuration", + "propertyKeyName": "122", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (122)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 123, + "propertyName": "level", + "propertyKeyName": "123", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (123)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 123, + "propertyName": "dimmingDuration", + "propertyKeyName": "123", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (123)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 124, + "propertyName": "level", + "propertyKeyName": "124", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (124)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 124, + "propertyName": "dimmingDuration", + "propertyKeyName": "124", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (124)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 125, + "propertyName": "level", + "propertyKeyName": "125", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (125)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 125, + "propertyName": "dimmingDuration", + "propertyKeyName": "125", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (125)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 126, + "propertyName": "level", + "propertyKeyName": "126", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (126)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 126, + "propertyName": "dimmingDuration", + "propertyKeyName": "126", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (126)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 127, + "propertyName": "level", + "propertyKeyName": "127", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (127)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 127, + "propertyName": "dimmingDuration", + "propertyKeyName": "127", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (127)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 128, + "propertyName": "level", + "propertyKeyName": "128", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (128)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 128, + "propertyName": "dimmingDuration", + "propertyKeyName": "128", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (128)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 129, + "propertyName": "level", + "propertyKeyName": "129", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (129)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 129, + "propertyName": "dimmingDuration", + "propertyKeyName": "129", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (129)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 130, + "propertyName": "level", + "propertyKeyName": "130", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (130)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 130, + "propertyName": "dimmingDuration", + "propertyKeyName": "130", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (130)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 131, + "propertyName": "level", + "propertyKeyName": "131", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (131)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 131, + "propertyName": "dimmingDuration", + "propertyKeyName": "131", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (131)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 132, + "propertyName": "level", + "propertyKeyName": "132", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (132)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 132, + "propertyName": "dimmingDuration", + "propertyKeyName": "132", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (132)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 133, + "propertyName": "level", + "propertyKeyName": "133", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (133)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 133, + "propertyName": "dimmingDuration", + "propertyKeyName": "133", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (133)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 134, + "propertyName": "level", + "propertyKeyName": "134", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (134)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 134, + "propertyName": "dimmingDuration", + "propertyKeyName": "134", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (134)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 135, + "propertyName": "level", + "propertyKeyName": "135", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (135)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 135, + "propertyName": "dimmingDuration", + "propertyKeyName": "135", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (135)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 136, + "propertyName": "level", + "propertyKeyName": "136", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (136)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 136, + "propertyName": "dimmingDuration", + "propertyKeyName": "136", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (136)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 137, + "propertyName": "level", + "propertyKeyName": "137", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (137)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 137, + "propertyName": "dimmingDuration", + "propertyKeyName": "137", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (137)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 138, + "propertyName": "level", + "propertyKeyName": "138", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (138)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 138, + "propertyName": "dimmingDuration", + "propertyKeyName": "138", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (138)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 139, + "propertyName": "level", + "propertyKeyName": "139", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (139)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 139, + "propertyName": "dimmingDuration", + "propertyKeyName": "139", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (139)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 140, + "propertyName": "level", + "propertyKeyName": "140", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (140)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 140, + "propertyName": "dimmingDuration", + "propertyKeyName": "140", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (140)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 141, + "propertyName": "level", + "propertyKeyName": "141", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (141)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 141, + "propertyName": "dimmingDuration", + "propertyKeyName": "141", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (141)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 142, + "propertyName": "level", + "propertyKeyName": "142", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (142)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 142, + "propertyName": "dimmingDuration", + "propertyKeyName": "142", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (142)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 143, + "propertyName": "level", + "propertyKeyName": "143", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (143)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 143, + "propertyName": "dimmingDuration", + "propertyKeyName": "143", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (143)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 144, + "propertyName": "level", + "propertyKeyName": "144", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (144)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 144, + "propertyName": "dimmingDuration", + "propertyKeyName": "144", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (144)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 145, + "propertyName": "level", + "propertyKeyName": "145", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (145)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 145, + "propertyName": "dimmingDuration", + "propertyKeyName": "145", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (145)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 146, + "propertyName": "level", + "propertyKeyName": "146", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (146)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 146, + "propertyName": "dimmingDuration", + "propertyKeyName": "146", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (146)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 147, + "propertyName": "level", + "propertyKeyName": "147", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (147)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 147, + "propertyName": "dimmingDuration", + "propertyKeyName": "147", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (147)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 148, + "propertyName": "level", + "propertyKeyName": "148", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (148)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 148, + "propertyName": "dimmingDuration", + "propertyKeyName": "148", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (148)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 149, + "propertyName": "level", + "propertyKeyName": "149", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (149)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 149, + "propertyName": "dimmingDuration", + "propertyKeyName": "149", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (149)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 150, + "propertyName": "level", + "propertyKeyName": "150", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (150)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 150, + "propertyName": "dimmingDuration", + "propertyKeyName": "150", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (150)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 151, + "propertyName": "level", + "propertyKeyName": "151", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (151)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 151, + "propertyName": "dimmingDuration", + "propertyKeyName": "151", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (151)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 152, + "propertyName": "level", + "propertyKeyName": "152", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (152)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 152, + "propertyName": "dimmingDuration", + "propertyKeyName": "152", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (152)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 153, + "propertyName": "level", + "propertyKeyName": "153", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (153)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 153, + "propertyName": "dimmingDuration", + "propertyKeyName": "153", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (153)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 154, + "propertyName": "level", + "propertyKeyName": "154", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (154)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 154, + "propertyName": "dimmingDuration", + "propertyKeyName": "154", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (154)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 155, + "propertyName": "level", + "propertyKeyName": "155", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (155)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 155, + "propertyName": "dimmingDuration", + "propertyKeyName": "155", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (155)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 156, + "propertyName": "level", + "propertyKeyName": "156", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (156)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 156, + "propertyName": "dimmingDuration", + "propertyKeyName": "156", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (156)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 157, + "propertyName": "level", + "propertyKeyName": "157", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (157)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 157, + "propertyName": "dimmingDuration", + "propertyKeyName": "157", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (157)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 158, + "propertyName": "level", + "propertyKeyName": "158", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (158)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 158, + "propertyName": "dimmingDuration", + "propertyKeyName": "158", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (158)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 159, + "propertyName": "level", + "propertyKeyName": "159", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (159)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 159, + "propertyName": "dimmingDuration", + "propertyKeyName": "159", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (159)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 160, + "propertyName": "level", + "propertyKeyName": "160", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (160)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 160, + "propertyName": "dimmingDuration", + "propertyKeyName": "160", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (160)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 161, + "propertyName": "level", + "propertyKeyName": "161", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (161)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 161, + "propertyName": "dimmingDuration", + "propertyKeyName": "161", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (161)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 162, + "propertyName": "level", + "propertyKeyName": "162", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (162)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 162, + "propertyName": "dimmingDuration", + "propertyKeyName": "162", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (162)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 163, + "propertyName": "level", + "propertyKeyName": "163", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (163)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 163, + "propertyName": "dimmingDuration", + "propertyKeyName": "163", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (163)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 164, + "propertyName": "level", + "propertyKeyName": "164", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (164)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 164, + "propertyName": "dimmingDuration", + "propertyKeyName": "164", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (164)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 165, + "propertyName": "level", + "propertyKeyName": "165", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (165)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 165, + "propertyName": "dimmingDuration", + "propertyKeyName": "165", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (165)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 166, + "propertyName": "level", + "propertyKeyName": "166", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (166)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 166, + "propertyName": "dimmingDuration", + "propertyKeyName": "166", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (166)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 167, + "propertyName": "level", + "propertyKeyName": "167", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (167)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 167, + "propertyName": "dimmingDuration", + "propertyKeyName": "167", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (167)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 168, + "propertyName": "level", + "propertyKeyName": "168", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (168)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 168, + "propertyName": "dimmingDuration", + "propertyKeyName": "168", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (168)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 169, + "propertyName": "level", + "propertyKeyName": "169", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (169)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 169, + "propertyName": "dimmingDuration", + "propertyKeyName": "169", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (169)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 170, + "propertyName": "level", + "propertyKeyName": "170", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (170)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 170, + "propertyName": "dimmingDuration", + "propertyKeyName": "170", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (170)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 171, + "propertyName": "level", + "propertyKeyName": "171", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (171)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 171, + "propertyName": "dimmingDuration", + "propertyKeyName": "171", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (171)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 172, + "propertyName": "level", + "propertyKeyName": "172", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (172)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 172, + "propertyName": "dimmingDuration", + "propertyKeyName": "172", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (172)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 173, + "propertyName": "level", + "propertyKeyName": "173", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (173)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 173, + "propertyName": "dimmingDuration", + "propertyKeyName": "173", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (173)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 174, + "propertyName": "level", + "propertyKeyName": "174", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (174)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 174, + "propertyName": "dimmingDuration", + "propertyKeyName": "174", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (174)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 175, + "propertyName": "level", + "propertyKeyName": "175", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (175)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 175, + "propertyName": "dimmingDuration", + "propertyKeyName": "175", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (175)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 176, + "propertyName": "level", + "propertyKeyName": "176", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (176)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 176, + "propertyName": "dimmingDuration", + "propertyKeyName": "176", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (176)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 177, + "propertyName": "level", + "propertyKeyName": "177", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (177)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 177, + "propertyName": "dimmingDuration", + "propertyKeyName": "177", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (177)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 178, + "propertyName": "level", + "propertyKeyName": "178", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (178)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 178, + "propertyName": "dimmingDuration", + "propertyKeyName": "178", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (178)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 179, + "propertyName": "level", + "propertyKeyName": "179", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (179)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 179, + "propertyName": "dimmingDuration", + "propertyKeyName": "179", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (179)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 180, + "propertyName": "level", + "propertyKeyName": "180", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (180)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 180, + "propertyName": "dimmingDuration", + "propertyKeyName": "180", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (180)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 181, + "propertyName": "level", + "propertyKeyName": "181", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (181)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 181, + "propertyName": "dimmingDuration", + "propertyKeyName": "181", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (181)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 182, + "propertyName": "level", + "propertyKeyName": "182", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (182)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 182, + "propertyName": "dimmingDuration", + "propertyKeyName": "182", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (182)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 183, + "propertyName": "level", + "propertyKeyName": "183", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (183)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 183, + "propertyName": "dimmingDuration", + "propertyKeyName": "183", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (183)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 184, + "propertyName": "level", + "propertyKeyName": "184", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (184)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 184, + "propertyName": "dimmingDuration", + "propertyKeyName": "184", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (184)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 185, + "propertyName": "level", + "propertyKeyName": "185", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (185)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 185, + "propertyName": "dimmingDuration", + "propertyKeyName": "185", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (185)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 186, + "propertyName": "level", + "propertyKeyName": "186", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (186)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 186, + "propertyName": "dimmingDuration", + "propertyKeyName": "186", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (186)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 187, + "propertyName": "level", + "propertyKeyName": "187", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (187)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 187, + "propertyName": "dimmingDuration", + "propertyKeyName": "187", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (187)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 188, + "propertyName": "level", + "propertyKeyName": "188", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (188)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 188, + "propertyName": "dimmingDuration", + "propertyKeyName": "188", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (188)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 189, + "propertyName": "level", + "propertyKeyName": "189", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (189)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 189, + "propertyName": "dimmingDuration", + "propertyKeyName": "189", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (189)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 190, + "propertyName": "level", + "propertyKeyName": "190", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (190)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 190, + "propertyName": "dimmingDuration", + "propertyKeyName": "190", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (190)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 191, + "propertyName": "level", + "propertyKeyName": "191", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (191)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 191, + "propertyName": "dimmingDuration", + "propertyKeyName": "191", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (191)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 192, + "propertyName": "level", + "propertyKeyName": "192", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (192)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 192, + "propertyName": "dimmingDuration", + "propertyKeyName": "192", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (192)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 193, + "propertyName": "level", + "propertyKeyName": "193", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (193)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 193, + "propertyName": "dimmingDuration", + "propertyKeyName": "193", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (193)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 194, + "propertyName": "level", + "propertyKeyName": "194", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (194)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 194, + "propertyName": "dimmingDuration", + "propertyKeyName": "194", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (194)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 195, + "propertyName": "level", + "propertyKeyName": "195", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (195)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 195, + "propertyName": "dimmingDuration", + "propertyKeyName": "195", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (195)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 196, + "propertyName": "level", + "propertyKeyName": "196", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (196)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 196, + "propertyName": "dimmingDuration", + "propertyKeyName": "196", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (196)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 197, + "propertyName": "level", + "propertyKeyName": "197", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (197)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 197, + "propertyName": "dimmingDuration", + "propertyKeyName": "197", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (197)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 198, + "propertyName": "level", + "propertyKeyName": "198", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (198)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 198, + "propertyName": "dimmingDuration", + "propertyKeyName": "198", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (198)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 199, + "propertyName": "level", + "propertyKeyName": "199", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (199)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 199, + "propertyName": "dimmingDuration", + "propertyKeyName": "199", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (199)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 200, + "propertyName": "level", + "propertyKeyName": "200", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (200)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 200, + "propertyName": "dimmingDuration", + "propertyKeyName": "200", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (200)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 201, + "propertyName": "level", + "propertyKeyName": "201", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (201)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 201, + "propertyName": "dimmingDuration", + "propertyKeyName": "201", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (201)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 202, + "propertyName": "level", + "propertyKeyName": "202", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (202)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 202, + "propertyName": "dimmingDuration", + "propertyKeyName": "202", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (202)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 203, + "propertyName": "level", + "propertyKeyName": "203", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (203)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 203, + "propertyName": "dimmingDuration", + "propertyKeyName": "203", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (203)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 204, + "propertyName": "level", + "propertyKeyName": "204", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (204)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 204, + "propertyName": "dimmingDuration", + "propertyKeyName": "204", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (204)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 205, + "propertyName": "level", + "propertyKeyName": "205", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (205)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 205, + "propertyName": "dimmingDuration", + "propertyKeyName": "205", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (205)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 206, + "propertyName": "level", + "propertyKeyName": "206", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (206)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 206, + "propertyName": "dimmingDuration", + "propertyKeyName": "206", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (206)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 207, + "propertyName": "level", + "propertyKeyName": "207", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (207)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 207, + "propertyName": "dimmingDuration", + "propertyKeyName": "207", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (207)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 208, + "propertyName": "level", + "propertyKeyName": "208", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (208)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 208, + "propertyName": "dimmingDuration", + "propertyKeyName": "208", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (208)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 209, + "propertyName": "level", + "propertyKeyName": "209", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (209)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 209, + "propertyName": "dimmingDuration", + "propertyKeyName": "209", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (209)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 210, + "propertyName": "level", + "propertyKeyName": "210", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (210)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 210, + "propertyName": "dimmingDuration", + "propertyKeyName": "210", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (210)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 211, + "propertyName": "level", + "propertyKeyName": "211", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (211)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 211, + "propertyName": "dimmingDuration", + "propertyKeyName": "211", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (211)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 212, + "propertyName": "level", + "propertyKeyName": "212", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (212)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 212, + "propertyName": "dimmingDuration", + "propertyKeyName": "212", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (212)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 213, + "propertyName": "level", + "propertyKeyName": "213", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (213)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 213, + "propertyName": "dimmingDuration", + "propertyKeyName": "213", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (213)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 214, + "propertyName": "level", + "propertyKeyName": "214", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (214)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 214, + "propertyName": "dimmingDuration", + "propertyKeyName": "214", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (214)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 215, + "propertyName": "level", + "propertyKeyName": "215", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (215)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 215, + "propertyName": "dimmingDuration", + "propertyKeyName": "215", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (215)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 216, + "propertyName": "level", + "propertyKeyName": "216", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (216)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 216, + "propertyName": "dimmingDuration", + "propertyKeyName": "216", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (216)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 217, + "propertyName": "level", + "propertyKeyName": "217", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (217)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 217, + "propertyName": "dimmingDuration", + "propertyKeyName": "217", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (217)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 218, + "propertyName": "level", + "propertyKeyName": "218", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (218)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 218, + "propertyName": "dimmingDuration", + "propertyKeyName": "218", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (218)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 219, + "propertyName": "level", + "propertyKeyName": "219", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (219)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 219, + "propertyName": "dimmingDuration", + "propertyKeyName": "219", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (219)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 220, + "propertyName": "level", + "propertyKeyName": "220", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (220)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 220, + "propertyName": "dimmingDuration", + "propertyKeyName": "220", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (220)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 221, + "propertyName": "level", + "propertyKeyName": "221", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (221)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 221, + "propertyName": "dimmingDuration", + "propertyKeyName": "221", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (221)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 222, + "propertyName": "level", + "propertyKeyName": "222", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (222)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 222, + "propertyName": "dimmingDuration", + "propertyKeyName": "222", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (222)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 223, + "propertyName": "level", + "propertyKeyName": "223", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (223)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 223, + "propertyName": "dimmingDuration", + "propertyKeyName": "223", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (223)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 224, + "propertyName": "level", + "propertyKeyName": "224", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (224)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 224, + "propertyName": "dimmingDuration", + "propertyKeyName": "224", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (224)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 225, + "propertyName": "level", + "propertyKeyName": "225", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (225)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 225, + "propertyName": "dimmingDuration", + "propertyKeyName": "225", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (225)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 226, + "propertyName": "level", + "propertyKeyName": "226", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (226)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 226, + "propertyName": "dimmingDuration", + "propertyKeyName": "226", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (226)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 227, + "propertyName": "level", + "propertyKeyName": "227", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (227)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 227, + "propertyName": "dimmingDuration", + "propertyKeyName": "227", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (227)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 228, + "propertyName": "level", + "propertyKeyName": "228", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (228)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 228, + "propertyName": "dimmingDuration", + "propertyKeyName": "228", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (228)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 229, + "propertyName": "level", + "propertyKeyName": "229", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (229)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 229, + "propertyName": "dimmingDuration", + "propertyKeyName": "229", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (229)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 230, + "propertyName": "level", + "propertyKeyName": "230", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (230)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 230, + "propertyName": "dimmingDuration", + "propertyKeyName": "230", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (230)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 231, + "propertyName": "level", + "propertyKeyName": "231", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (231)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 231, + "propertyName": "dimmingDuration", + "propertyKeyName": "231", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (231)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 232, + "propertyName": "level", + "propertyKeyName": "232", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (232)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 232, + "propertyName": "dimmingDuration", + "propertyKeyName": "232", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (232)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 233, + "propertyName": "level", + "propertyKeyName": "233", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (233)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 233, + "propertyName": "dimmingDuration", + "propertyKeyName": "233", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (233)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 234, + "propertyName": "level", + "propertyKeyName": "234", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (234)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 234, + "propertyName": "dimmingDuration", + "propertyKeyName": "234", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (234)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 235, + "propertyName": "level", + "propertyKeyName": "235", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (235)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 235, + "propertyName": "dimmingDuration", + "propertyKeyName": "235", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (235)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 236, + "propertyName": "level", + "propertyKeyName": "236", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (236)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 236, + "propertyName": "dimmingDuration", + "propertyKeyName": "236", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (236)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 237, + "propertyName": "level", + "propertyKeyName": "237", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (237)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 237, + "propertyName": "dimmingDuration", + "propertyKeyName": "237", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (237)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 238, + "propertyName": "level", + "propertyKeyName": "238", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (238)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 238, + "propertyName": "dimmingDuration", + "propertyKeyName": "238", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (238)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 239, + "propertyName": "level", + "propertyKeyName": "239", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (239)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 239, + "propertyName": "dimmingDuration", + "propertyKeyName": "239", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (239)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 240, + "propertyName": "level", + "propertyKeyName": "240", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (240)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 240, + "propertyName": "dimmingDuration", + "propertyKeyName": "240", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (240)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 241, + "propertyName": "level", + "propertyKeyName": "241", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (241)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 241, + "propertyName": "dimmingDuration", + "propertyKeyName": "241", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (241)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 242, + "propertyName": "level", + "propertyKeyName": "242", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (242)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 242, + "propertyName": "dimmingDuration", + "propertyKeyName": "242", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (242)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 243, + "propertyName": "level", + "propertyKeyName": "243", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (243)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 243, + "propertyName": "dimmingDuration", + "propertyKeyName": "243", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (243)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 244, + "propertyName": "level", + "propertyKeyName": "244", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (244)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 244, + "propertyName": "dimmingDuration", + "propertyKeyName": "244", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (244)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 245, + "propertyName": "level", + "propertyKeyName": "245", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (245)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 245, + "propertyName": "dimmingDuration", + "propertyKeyName": "245", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (245)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 246, + "propertyName": "level", + "propertyKeyName": "246", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (246)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 246, + "propertyName": "dimmingDuration", + "propertyKeyName": "246", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (246)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 247, + "propertyName": "level", + "propertyKeyName": "247", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (247)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 247, + "propertyName": "dimmingDuration", + "propertyKeyName": "247", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (247)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 248, + "propertyName": "level", + "propertyKeyName": "248", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (248)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 248, + "propertyName": "dimmingDuration", + "propertyKeyName": "248", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (248)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 249, + "propertyName": "level", + "propertyKeyName": "249", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (249)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 249, + "propertyName": "dimmingDuration", + "propertyKeyName": "249", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (249)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 250, + "propertyName": "level", + "propertyKeyName": "250", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (250)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 250, + "propertyName": "dimmingDuration", + "propertyKeyName": "250", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (250)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 251, + "propertyName": "level", + "propertyKeyName": "251", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (251)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 251, + "propertyName": "dimmingDuration", + "propertyKeyName": "251", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (251)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 252, + "propertyName": "level", + "propertyKeyName": "252", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (252)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 252, + "propertyName": "dimmingDuration", + "propertyKeyName": "252", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (252)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 253, + "propertyName": "level", + "propertyKeyName": "253", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (253)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 253, + "propertyName": "dimmingDuration", + "propertyKeyName": "253", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (253)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 254, + "propertyName": "level", + "propertyKeyName": "254", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (254)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 254, + "propertyName": "dimmingDuration", + "propertyKeyName": "254", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (254)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "level", + "propertyKey": 255, + "propertyName": "level", + "propertyKeyName": "255", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Level (255)", + "valueChangeOptions": ["transitionDuration"], + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 44, + "commandClassName": "Scene Actuator Configuration", + "property": "dimmingDuration", + "propertyKey": 255, + "propertyName": "dimmingDuration", + "propertyKeyName": "255", + "ccVersion": 1, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Dimming duration (255)", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "productId", + "propertyName": "productId", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Product ID", + "min": 0, + "max": 65535, + "stateful": true, + "secret": false + }, + "value": 521 + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "productType", + "propertyName": "productType", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Product type", + "min": 0, + "max": 65535, + "stateful": true, + "secret": false + }, + "value": 4097 + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "manufacturerId", + "propertyName": "manufacturerId", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Manufacturer ID", + "min": 0, + "max": 65535, + "stateful": true, + "secret": false + }, + "value": 29 + }, + { + "endpoint": 0, + "commandClass": 119, + "commandClassName": "Node Naming and Location", + "property": "name", + "propertyName": "name", + "ccVersion": 1, + "metadata": { + "type": "string", + "readable": true, + "writeable": true, + "label": "Node name", + "stateful": true, + "secret": false + }, + "value": "Fan" + }, + { + "endpoint": 0, + "commandClass": 119, + "commandClassName": "Node Naming and Location", + "property": "location", + "propertyName": "location", + "ccVersion": 1, + "metadata": { + "type": "string", + "readable": true, + "writeable": true, + "label": "Node location", + "stateful": true, + "secret": false + }, + "value": "Family Room" + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "firmwareVersions", + "propertyName": "firmwareVersions", + "ccVersion": 1, + "metadata": { + "type": "string[]", + "readable": true, + "writeable": false, + "label": "Z-Wave chip firmware versions", + "stateful": true, + "secret": false + }, + "value": ["0.5"] + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "protocolVersion", + "propertyName": "protocolVersion", + "ccVersion": 1, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Z-Wave protocol version", + "stateful": true, + "secret": false + }, + "value": "2.9" + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "libraryType", + "propertyName": "libraryType", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Library type", + "states": { + "0": "Unknown", + "1": "Static Controller", + "2": "Controller", + "3": "Enhanced Slave", + "4": "Slave", + "5": "Installer", + "6": "Routing Slave", + "7": "Bridge Controller", + "8": "Device under Test", + "9": "N/A", + "10": "AV Remote", + "11": "AV Device" + }, + "stateful": true, + "secret": false + }, + "value": 3 + } + ], + "endpoints": [ + { + "nodeId": 35, + "index": 0, + "deviceClass": { + "basic": { + "key": 4, + "label": "Routing End Node" + }, + "generic": { + "key": 17, + "label": "Multilevel Switch" + }, + "specific": { + "key": 4, + "label": "Multilevel Scene Switch" + } + }, + "commandClasses": [ + { + "id": 38, + "name": "Multilevel Switch", + "version": 1, + "isSecure": false + }, + { + "id": 43, + "name": "Scene Activation", + "version": 1, + "isSecure": false + }, + { + "id": 44, + "name": "Scene Actuator Configuration", + "version": 1, + "isSecure": false + }, + { + "id": 133, + "name": "Association", + "version": 1, + "isSecure": false + }, + { + "id": 114, + "name": "Manufacturer Specific", + "version": 1, + "isSecure": false + }, + { + "id": 134, + "name": "Version", + "version": 1, + "isSecure": false + }, + { + "id": 145, + "name": "Manufacturer Proprietary", + "version": 1, + "isSecure": false + }, + { + "id": 119, + "name": "Node Naming and Location", + "version": 1, + "isSecure": false + }, + { + "id": 115, + "name": "Powerlevel", + "version": 1, + "isSecure": false + } + ] + } + ] +} diff --git a/tests/components/zwave_js/test_config_flow.py b/tests/components/zwave_js/test_config_flow.py index 2885a9b872adcd..1b1c320b6c2a7f 100644 --- a/tests/components/zwave_js/test_config_flow.py +++ b/tests/components/zwave_js/test_config_flow.py @@ -2522,6 +2522,94 @@ async def test_not_addon(hass: HomeAssistant) -> None: assert len(mock_setup_entry.mock_calls) == 1 +@pytest.mark.usefixtures("supervisor", "addon_running") +async def test_addon_already_configured( + hass: HomeAssistant, + addon_options: dict[str, Any], + set_addon_options: AsyncMock, +) -> None: + """Test flow aborts when another entry already uses the add-on.""" + addon_options["device"] = "/test" + + entry = MockConfigEntry( + domain=DOMAIN, + data={ + "url": "ws://localhost:3000", + "usb_path": "/other", + "use_addon": True, + }, + title=TITLE, + unique_id="4321", + ) + entry.add_to_hass(hass) + + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + + assert result["type"] is FlowResultType.MENU + assert result["step_id"] == "installation_type" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {"next_step_id": "intent_custom"} + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "on_supervisor" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {"use_addon": True} + ) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "addon_already_configured" + assert len(hass.config_entries.async_entries(DOMAIN)) == 1 + # The flow must not have touched the add-on config of the existing entry. + set_addon_options.assert_not_called() + assert addon_options["device"] == "/test" + + +@pytest.mark.usefixtures("supervisor", "addon_running") +async def test_reconfigure_addon_already_configured( + hass: HomeAssistant, + integration: MockConfigEntry, + set_addon_options: AsyncMock, +) -> None: + """Test reconfigure to add-on aborts when another entry uses the add-on.""" + addon_entry = MockConfigEntry( + domain=DOMAIN, + data={ + "url": "ws://localhost:3000", + "usb_path": "/other", + "use_addon": True, + }, + title=TITLE, + unique_id="4321", + ) + addon_entry.add_to_hass(hass) + + result = await integration.start_reconfigure_flow(hass) + + assert result["type"] is FlowResultType.MENU + assert result["step_id"] == "reconfigure" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {"next_step_id": "intent_reconfigure"} + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "on_supervisor_reconfigure" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {"use_addon": True} + ) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "addon_already_configured" + # The other entry's add-on config is untouched. + set_addon_options.assert_not_called() + + @pytest.mark.usefixtures("supervisor", "addon_running") async def test_addon_running( hass: HomeAssistant, diff --git a/tests/components/zwave_js/test_discovery.py b/tests/components/zwave_js/test_discovery.py index 8763a8a49f6fc7..0dee5ff7b6f993 100644 --- a/tests/components/zwave_js/test_discovery.py +++ b/tests/components/zwave_js/test_discovery.py @@ -139,6 +139,17 @@ async def test_inovelli_lzw36( assert state +async def test_leviton_vrf01( + hass: HomeAssistant, client, leviton_vrf01, integration +) -> None: + """Test Leviton VRF01 multilevel switch is discovered as a fan, not a light.""" + node = leviton_vrf01 + assert node.device_class.specific.label == "Multilevel Scene Switch" + + assert hass.states.get("fan.fan") + assert not hass.states.get("light.fan") + + async def test_vision_security_zl7432( hass: HomeAssistant, client, vision_security_zl7432, integration ) -> None: diff --git a/tests/components/zwave_js/test_fan.py b/tests/components/zwave_js/test_fan.py index 49bac6d4826247..01ad16c4b0a7de 100644 --- a/tests/components/zwave_js/test_fan.py +++ b/tests/components/zwave_js/test_fan.py @@ -719,6 +719,76 @@ async def get_percentage_from_zwave_speed(zwave_speed): assert state.attributes[ATTR_PRESET_MODES] == [] +async def test_leviton_vrf01_fan( + hass: HomeAssistant, client, leviton_vrf01, integration +) -> None: + """Test a Leviton VRF01 fan with 3 fixed speeds.""" + node = leviton_vrf01 + node_id = node.node_id + entity_id = "fan.fan" + + async def get_zwave_speed_from_percentage(percentage): + """Set the fan to a particular percentage and get the resulting Zwave speed.""" + client.async_send_command.reset_mock() + + await hass.services.async_call( + "fan", + "turn_on", + {"entity_id": entity_id, "percentage": percentage}, + blocking=True, + ) + + assert len(client.async_send_command.call_args_list) == 1 + args = client.async_send_command.call_args[0][0] + assert args["command"] == "node.set_value" + assert args["nodeId"] == node_id + return args["value"] + + async def get_percentage_from_zwave_speed(zwave_speed): + """Set the underlying device speed and get the resulting percentage.""" + event = Event( + type="value updated", + data={ + "source": "node", + "event": "value updated", + "nodeId": node_id, + "args": { + "commandClassName": "Multilevel Switch", + "commandClass": 38, + "endpoint": 0, + "property": "currentValue", + "newValue": zwave_speed, + "prevValue": 0, + "propertyName": "currentValue", + }, + }, + ) + node.receive_event(event) + state = hass.states.get(entity_id) + return state.attributes[ATTR_PERCENTAGE] + + # This device has the speeds: + # 1 = 1-32, 2 = 33-66, 3 = 67-99 + percentages_to_zwave_speeds = [ + [[0], [0]], + [range(1, 34), range(1, 33)], + [range(34, 67), range(33, 67)], + [range(67, 101), range(67, 100)], + ] + + for percentages, zwave_speeds in percentages_to_zwave_speeds: + for percentage in percentages: + actual_zwave_speed = await get_zwave_speed_from_percentage(percentage) + assert actual_zwave_speed in zwave_speeds + for zwave_speed in zwave_speeds: + actual_percentage = await get_percentage_from_zwave_speed(zwave_speed) + assert actual_percentage in percentages + + state = hass.states.get(entity_id) + assert state.attributes[ATTR_PERCENTAGE_STEP] == pytest.approx(100 / 3, rel=1e-3) + assert state.attributes[ATTR_PRESET_MODES] == [] + + async def test_enbrighten_55258_zw4002_fan( hass: HomeAssistant, client, enbrighten_55258_zw4002, integration ) -> None: