diff --git a/homeassistant/components/zwave_js/__init__.py b/homeassistant/components/zwave_js/__init__.py index 9f928eb7d3d..5c583d8321f 100644 --- a/homeassistant/components/zwave_js/__init__.py +++ b/homeassistant/components/zwave_js/__init__.py @@ -124,13 +124,13 @@ def register_node_in_dev_reg( hass: HomeAssistant, entry: ConfigEntry, dev_reg: device_registry.DeviceRegistry, - client: ZwaveClient, + driver: Driver, node: ZwaveNode, remove_device_func: Callable[[device_registry.DeviceEntry], None], ) -> device_registry.DeviceEntry: """Register node in dev reg.""" - device_id = get_device_id(client, node) - device_id_ext = get_device_id_ext(client, node) + device_id = get_device_id(driver, node) + device_id_ext = get_device_id_ext(driver, node) device = dev_reg.async_get_device({device_id}) # Replace the device if it can be determined that this node is not the @@ -281,7 +281,7 @@ async def setup_driver( # noqa: C901 ent_reg, registered_unique_ids[device.id][disc_info.platform], device, - client, + driver, disc_info, ) @@ -316,7 +316,7 @@ async def setup_driver( # noqa: C901 LOGGER.debug("Processing node %s", node) # register (or update) node in device registry device = register_node_in_dev_reg( - hass, entry, dev_reg, client, node, remove_device + hass, entry, dev_reg, driver, node, remove_device ) # We only want to create the defaultdict once, even on reinterviews if device.id not in registered_unique_ids: @@ -384,7 +384,7 @@ async def setup_driver( # noqa: C901 ) # we do submit the node to device registry so user has # some visual feedback that something is (in the process of) being added - register_node_in_dev_reg(hass, entry, dev_reg, client, node, remove_device) + register_node_in_dev_reg(hass, entry, dev_reg, driver, node, remove_device) async def async_on_value_added( value_updates_disc_info: dict[str, ZwaveDiscoveryInfo], value: Value @@ -393,7 +393,7 @@ async def setup_driver( # noqa: C901 # If node isn't ready or a device for this node doesn't already exist, we can # let the node ready event handler perform discovery. If a value has already # been processed, we don't need to do it again - device_id = get_device_id(client, value.node) + device_id = get_device_id(driver, value.node) if ( not value.node.ready or not (device := dev_reg.async_get_device({device_id})) @@ -417,7 +417,7 @@ async def setup_driver( # noqa: C901 node: ZwaveNode = event["node"] replaced: bool = event.get("replaced", False) # grab device in device registry attached to this node - dev_id = get_device_id(client, node) + dev_id = get_device_id(driver, node) device = dev_reg.async_get_device({dev_id}) # We assert because we know the device exists assert device @@ -426,7 +426,7 @@ async def setup_driver( # noqa: C901 async_dispatcher_send( hass, - f"{DOMAIN}_{get_valueless_base_unique_id(client, node)}_remove_entity", + f"{DOMAIN}_{get_valueless_base_unique_id(driver, node)}_remove_entity", ) else: remove_device(device) @@ -434,7 +434,7 @@ async def setup_driver( # noqa: C901 @callback def async_on_value_notification(notification: ValueNotification) -> None: """Relay stateless value notification events from Z-Wave nodes to hass.""" - device = dev_reg.async_get_device({get_device_id(client, notification.node)}) + device = dev_reg.async_get_device({get_device_id(driver, notification.node)}) # We assert because we know the device exists assert device raw_value = value = notification.value @@ -469,7 +469,7 @@ async def setup_driver( # noqa: C901 notification: EntryControlNotification | NotificationNotification | PowerLevelNotification | MultilevelSwitchNotification = event[ "notification" ] - device = dev_reg.async_get_device({get_device_id(client, notification.node)}) + device = dev_reg.async_get_device({get_device_id(driver, notification.node)}) # We assert because we know the device exists assert device event_data = { @@ -533,11 +533,11 @@ async def setup_driver( # noqa: C901 return disc_info = value_updates_disc_info[value.value_id] - device = dev_reg.async_get_device({get_device_id(client, value.node)}) + device = dev_reg.async_get_device({get_device_id(driver, value.node)}) # We assert because we know the device exists assert device - unique_id = get_unique_id(client, disc_info.primary_value.value_id) + unique_id = get_unique_id(driver, disc_info.primary_value.value_id) entity_id = ent_reg.async_get_entity_id(disc_info.platform, DOMAIN, unique_id) raw_value = value_ = value.value @@ -575,7 +575,7 @@ async def setup_driver( # noqa: C901 dev_reg, entry.entry_id ) known_devices = [ - dev_reg.async_get_device({get_device_id(client, node)}) + dev_reg.async_get_device({get_device_id(driver, node)}) for node in driver.controller.nodes.values() ] diff --git a/homeassistant/components/zwave_js/binary_sensor.py b/homeassistant/components/zwave_js/binary_sensor.py index 8a86898239a..7e9882377bd 100644 --- a/homeassistant/components/zwave_js/binary_sensor.py +++ b/homeassistant/components/zwave_js/binary_sensor.py @@ -10,6 +10,7 @@ from zwave_js_server.const.command_class.lock import DOOR_STATUS_PROPERTY from zwave_js_server.const.command_class.notification import ( CC_SPECIFIC_NOTIFICATION_TYPE, ) +from zwave_js_server.model.driver import Driver from homeassistant.components.binary_sensor import ( DOMAIN as BINARY_SENSOR_DOMAIN, @@ -267,6 +268,8 @@ async def async_setup_entry( @callback def async_add_binary_sensor(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave Binary Sensor.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[BinarySensorEntity] = [] if info.platform_hint == "notification": @@ -298,7 +301,7 @@ async def async_setup_entry( entities.append( ZWaveNotificationBinarySensor( - config_entry, client, info, state_key, notification_description + config_entry, driver, info, state_key, notification_description ) ) elif info.platform_hint == "property" and ( @@ -308,12 +311,12 @@ async def async_setup_entry( ): entities.append( ZWavePropertyBinarySensor( - config_entry, client, info, property_description + config_entry, driver, info, property_description ) ) else: # boolean sensor - entities.append(ZWaveBooleanBinarySensor(config_entry, client, info)) + entities.append(ZWaveBooleanBinarySensor(config_entry, driver, info)) async_add_entities(entities) @@ -332,11 +335,11 @@ class ZWaveBooleanBinarySensor(ZWaveBaseEntity, BinarySensorEntity): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, ) -> None: """Initialize a ZWaveBooleanBinarySensor entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) # Entity class attributes self._attr_name = self.generate_name(include_value_name=True) @@ -359,13 +362,13 @@ class ZWaveNotificationBinarySensor(ZWaveBaseEntity, BinarySensorEntity): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, state_key: str, description: NotificationZWaveJSEntityDescription | None = None, ) -> None: """Initialize a ZWaveNotificationBinarySensor entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self.state_key = state_key if description: self.entity_description = description @@ -394,12 +397,12 @@ class ZWavePropertyBinarySensor(ZWaveBaseEntity, BinarySensorEntity): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, description: PropertyZWaveJSEntityDescription, ) -> None: """Initialize a ZWavePropertyBinarySensor entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self.entity_description = description self._attr_name = self.generate_name(include_value_name=True) diff --git a/homeassistant/components/zwave_js/button.py b/homeassistant/components/zwave_js/button.py index 49c2a76cccf..cef64f1724a 100644 --- a/homeassistant/components/zwave_js/button.py +++ b/homeassistant/components/zwave_js/button.py @@ -2,6 +2,7 @@ from __future__ import annotations from zwave_js_server.client import Client as ZwaveClient +from zwave_js_server.model.driver import Driver from zwave_js_server.model.node import Node as ZwaveNode from homeassistant.components.button import ButtonEntity @@ -28,7 +29,9 @@ async def async_setup_entry( @callback def async_add_ping_button_entity(node: ZwaveNode) -> None: """Add ping button entity.""" - async_add_entities([ZWaveNodePingButton(client, node)]) + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. + async_add_entities([ZWaveNodePingButton(driver, node)]) config_entry.async_on_unload( async_dispatcher_connect( @@ -45,7 +48,7 @@ class ZWaveNodePingButton(ButtonEntity): _attr_should_poll = False _attr_entity_category = EntityCategory.CONFIG - def __init__(self, client: ZwaveClient, node: ZwaveNode) -> None: + def __init__(self, driver: Driver, node: ZwaveNode) -> None: """Initialize a ping Z-Wave device button entity.""" self.node = node name: str = ( @@ -53,11 +56,11 @@ class ZWaveNodePingButton(ButtonEntity): ) # Entity class attributes self._attr_name = f"{name}: Ping" - self._base_unique_id = get_valueless_base_unique_id(client, node) + self._base_unique_id = get_valueless_base_unique_id(driver, node) self._attr_unique_id = f"{self._base_unique_id}.ping" # device is precreated in main handler self._attr_device_info = DeviceInfo( - identifiers={get_device_id(client, node)}, + identifiers={get_device_id(driver, node)}, ) async def async_poll_value(self, _: bool) -> None: diff --git a/homeassistant/components/zwave_js/climate.py b/homeassistant/components/zwave_js/climate.py index 67def698fc2..f721db41d9f 100644 --- a/homeassistant/components/zwave_js/climate.py +++ b/homeassistant/components/zwave_js/climate.py @@ -17,6 +17,7 @@ from zwave_js_server.const.command_class.thermostat import ( ThermostatOperatingState, ThermostatSetpointType, ) +from zwave_js_server.model.driver import Driver from zwave_js_server.model.value import Value as ZwaveValue from homeassistant.components.climate import ( @@ -103,11 +104,13 @@ async def async_setup_entry( @callback def async_add_climate(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave Climate.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[ZWaveBaseEntity] = [] if info.platform_hint == "dynamic_current_temp": - entities.append(DynamicCurrentTempClimate(config_entry, client, info)) + entities.append(DynamicCurrentTempClimate(config_entry, driver, info)) else: - entities.append(ZWaveClimate(config_entry, client, info)) + entities.append(ZWaveClimate(config_entry, driver, info)) async_add_entities(entities) @@ -124,10 +127,10 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity): """Representation of a Z-Wave climate.""" def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize thermostat.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self._hvac_modes: dict[HVACMode, int | None] = {} self._hvac_presets: dict[str, int | None] = {} self._unit_value: ZwaveValue | None = None @@ -479,10 +482,10 @@ class DynamicCurrentTempClimate(ZWaveClimate): """Representation of a thermostat that can dynamically use a different Zwave Value for current temp.""" def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize thermostat.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self.data_template = cast( DynamicCurrentTempClimateDataTemplate, self.info.platform_data_template ) diff --git a/homeassistant/components/zwave_js/cover.py b/homeassistant/components/zwave_js/cover.py index c7ba50ee7e7..f9a9990ed77 100644 --- a/homeassistant/components/zwave_js/cover.py +++ b/homeassistant/components/zwave_js/cover.py @@ -15,6 +15,7 @@ from zwave_js_server.const.command_class.multilevel_switch import ( COVER_OPEN_PROPERTY, COVER_UP_PROPERTY, ) +from zwave_js_server.model.driver import Driver from zwave_js_server.model.value import Value as ZwaveValue from homeassistant.components.cover import ( @@ -51,13 +52,15 @@ async def async_setup_entry( @callback def async_add_cover(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave cover.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[ZWaveBaseEntity] = [] if info.platform_hint == "motorized_barrier": - entities.append(ZwaveMotorizedBarrier(config_entry, client, info)) + entities.append(ZwaveMotorizedBarrier(config_entry, driver, info)) elif info.platform_hint == "window_shutter_tilt": - entities.append(ZWaveTiltCover(config_entry, client, info)) + entities.append(ZWaveTiltCover(config_entry, driver, info)) else: - entities.append(ZWaveCover(config_entry, client, info)) + entities.append(ZWaveCover(config_entry, driver, info)) async_add_entities(entities) config_entry.async_on_unload( @@ -105,11 +108,11 @@ class ZWaveCover(ZWaveBaseEntity, CoverEntity): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, ) -> None: """Initialize a ZWaveCover entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) # Entity class attributes self._attr_device_class = CoverDeviceClass.WINDOW @@ -188,11 +191,11 @@ class ZWaveTiltCover(ZWaveCover): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, ) -> None: """Initialize a ZWaveCover entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self.data_template = cast( CoverTiltDataTemplate, self.info.platform_data_template ) @@ -233,11 +236,11 @@ class ZwaveMotorizedBarrier(ZWaveBaseEntity, CoverEntity): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, ) -> None: """Initialize a ZwaveMotorizedBarrier entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self._target_state: ZwaveValue = self.get_zwave_value( TARGET_STATE_PROPERTY, add_to_watched_value_ids=False ) diff --git a/homeassistant/components/zwave_js/entity.py b/homeassistant/components/zwave_js/entity.py index b89b4c9c9de..a4271ac1c02 100644 --- a/homeassistant/components/zwave_js/entity.py +++ b/homeassistant/components/zwave_js/entity.py @@ -3,8 +3,8 @@ from __future__ import annotations import logging -from zwave_js_server.client import Client as ZwaveClient from zwave_js_server.const import NodeStatus +from zwave_js_server.model.driver import Driver from zwave_js_server.model.value import Value as ZwaveValue, get_value_id from homeassistant.config_entries import ConfigEntry @@ -30,11 +30,11 @@ class ZWaveBaseEntity(Entity): _attr_should_poll = False def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize a generic Z-Wave device entity.""" self.config_entry = config_entry - self.client = client + self.driver = driver self.info = info # entities requiring additional values, can add extra ids to this list self.watched_value_ids = {self.info.primary_value.value_id} @@ -46,16 +46,14 @@ class ZWaveBaseEntity(Entity): # Entity class attributes self._attr_name = self.generate_name() - self._attr_unique_id = get_unique_id( - self.client, self.info.primary_value.value_id - ) + self._attr_unique_id = get_unique_id(driver, self.info.primary_value.value_id) self._attr_entity_registry_enabled_default = ( self.info.entity_registry_enabled_default ) self._attr_assumed_state = self.info.assumed_state # device is precreated in main handler self._attr_device_info = DeviceInfo( - identifiers={get_device_id(self.client, self.info.node)}, + identifiers={get_device_id(driver, self.info.node)}, ) @callback @@ -145,7 +143,10 @@ class ZWaveBaseEntity(Entity): if item: name += f" - {item}" # append endpoint if > 1 - if self.info.primary_value.endpoint > 1: + if ( + self.info.primary_value.endpoint is not None + and self.info.primary_value.endpoint > 1 + ): name += f" ({self.info.primary_value.endpoint})" return name @@ -154,7 +155,7 @@ class ZWaveBaseEntity(Entity): def available(self) -> bool: """Return entity availability.""" return ( - self.client.connected + self.driver.client.connected and bool(self.info.node.ready) and self.info.node.status != NodeStatus.DEAD ) diff --git a/homeassistant/components/zwave_js/fan.py b/homeassistant/components/zwave_js/fan.py index f571884ac80..eb6d053f958 100644 --- a/homeassistant/components/zwave_js/fan.py +++ b/homeassistant/components/zwave_js/fan.py @@ -10,6 +10,7 @@ from zwave_js_server.const.command_class.thermostat import ( THERMOSTAT_FAN_OFF_PROPERTY, THERMOSTAT_FAN_STATE_PROPERTY, ) +from zwave_js_server.model.driver import Driver from zwave_js_server.model.value import Value as ZwaveValue from homeassistant.components.fan import ( @@ -53,13 +54,15 @@ async def async_setup_entry( @callback def async_add_fan(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave fan.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[ZWaveBaseEntity] = [] if info.platform_hint == "has_fan_value_mapping": - entities.append(ValueMappingZwaveFan(config_entry, client, info)) + entities.append(ValueMappingZwaveFan(config_entry, driver, info)) elif info.platform_hint == "thermostat_fan": - entities.append(ZwaveThermostatFan(config_entry, client, info)) + entities.append(ZwaveThermostatFan(config_entry, driver, info)) else: - entities.append(ZwaveFan(config_entry, client, info)) + entities.append(ZwaveFan(config_entry, driver, info)) async_add_entities(entities) @@ -78,10 +81,10 @@ class ZwaveFan(ZWaveBaseEntity, FanEntity): _attr_supported_features = FanEntityFeature.SET_SPEED def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize the fan.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self._target_value = self.get_zwave_value(TARGET_VALUE_PROPERTY) async def async_set_percentage(self, percentage: int) -> None: @@ -147,10 +150,10 @@ class ValueMappingZwaveFan(ZwaveFan): """A Zwave fan with a value mapping data (e.g., 1-24 is low).""" def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize the fan.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self.data_template = cast( FanValueMappingDataTemplate, self.info.platform_data_template ) @@ -300,10 +303,10 @@ class ZwaveThermostatFan(ZWaveBaseEntity, FanEntity): _fan_state: ZwaveValue | None = None def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize the thermostat fan.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self._fan_mode = self.info.primary_value diff --git a/homeassistant/components/zwave_js/helpers.py b/homeassistant/components/zwave_js/helpers.py index 0657d8531f3..807ae0287eb 100644 --- a/homeassistant/components/zwave_js/helpers.py +++ b/homeassistant/components/zwave_js/helpers.py @@ -110,29 +110,29 @@ def update_data_collection_preference( @callback -def get_valueless_base_unique_id(client: ZwaveClient, node: ZwaveNode) -> str: +def get_valueless_base_unique_id(driver: Driver, node: ZwaveNode) -> str: """Return the base unique ID for an entity that is not based on a value.""" - return f"{client.driver.controller.home_id}.{node.node_id}" + return f"{driver.controller.home_id}.{node.node_id}" -def get_unique_id(client: ZwaveClient, value_id: str) -> str: +def get_unique_id(driver: Driver, value_id: str) -> str: """Get unique ID from client and value ID.""" - return f"{client.driver.controller.home_id}.{value_id}" + return f"{driver.controller.home_id}.{value_id}" @callback -def get_device_id(client: ZwaveClient, node: ZwaveNode) -> tuple[str, str]: +def get_device_id(driver: Driver, node: ZwaveNode) -> tuple[str, str]: """Get device registry identifier for Z-Wave node.""" - return (DOMAIN, f"{client.driver.controller.home_id}-{node.node_id}") + return (DOMAIN, f"{driver.controller.home_id}-{node.node_id}") @callback -def get_device_id_ext(client: ZwaveClient, node: ZwaveNode) -> tuple[str, str] | None: +def get_device_id_ext(driver: Driver, node: ZwaveNode) -> tuple[str, str] | None: """Get extended device registry identifier for Z-Wave node.""" if None in (node.manufacturer_id, node.product_type, node.product_id): return None - domain, dev_id = get_device_id(client, node) + domain, dev_id = get_device_id(driver, node) return ( domain, f"{dev_id}-{node.manufacturer_id}:{node.product_type}:{node.product_id}", diff --git a/homeassistant/components/zwave_js/humidifier.py b/homeassistant/components/zwave_js/humidifier.py index 8cf0b6aec7c..5aeb6d0272f 100644 --- a/homeassistant/components/zwave_js/humidifier.py +++ b/homeassistant/components/zwave_js/humidifier.py @@ -11,6 +11,7 @@ from zwave_js_server.const.command_class.humidity_control import ( HumidityControlMode, HumidityControlSetpointType, ) +from zwave_js_server.model.driver import Driver from zwave_js_server.model.value import Value as ZwaveValue from homeassistant.components.humidifier import ( @@ -85,6 +86,8 @@ async def async_setup_entry( @callback def async_add_humidifier(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave Humidifier.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[ZWaveBaseEntity] = [] if ( @@ -93,7 +96,7 @@ async def async_setup_entry( ): entities.append( ZWaveHumidifier( - config_entry, client, info, HUMIDIFIER_ENTITY_DESCRIPTION + config_entry, driver, info, HUMIDIFIER_ENTITY_DESCRIPTION ) ) @@ -103,7 +106,7 @@ async def async_setup_entry( ): entities.append( ZWaveHumidifier( - config_entry, client, info, DEHUMIDIFIER_ENTITY_DESCRIPTION + config_entry, driver, info, DEHUMIDIFIER_ENTITY_DESCRIPTION ) ) @@ -128,12 +131,12 @@ class ZWaveHumidifier(ZWaveBaseEntity, HumidifierEntity): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, description: ZwaveHumidifierEntityDescription, ) -> None: """Initialize humidifier.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self.entity_description = description diff --git a/homeassistant/components/zwave_js/light.py b/homeassistant/components/zwave_js/light.py index 534a86f1c86..d026868b418 100644 --- a/homeassistant/components/zwave_js/light.py +++ b/homeassistant/components/zwave_js/light.py @@ -23,6 +23,7 @@ from zwave_js_server.const.command_class.color_switch import ( TARGET_COLOR_PROPERTY, ColorComponent, ) +from zwave_js_server.model.driver import Driver from homeassistant.components.light import ( ATTR_BRIGHTNESS, @@ -72,11 +73,13 @@ async def async_setup_entry( @callback def async_add_light(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave Light.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. if info.platform_hint == "black_is_off": - async_add_entities([ZwaveBlackIsOffLight(config_entry, client, info)]) + async_add_entities([ZwaveBlackIsOffLight(config_entry, driver, info)]) else: - async_add_entities([ZwaveLight(config_entry, client, info)]) + async_add_entities([ZwaveLight(config_entry, driver, info)]) config_entry.async_on_unload( async_dispatcher_connect( @@ -101,10 +104,10 @@ class ZwaveLight(ZWaveBaseEntity, LightEntity): """Representation of a Z-Wave light.""" def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize the light.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self._supports_color = False self._supports_rgbw = False self._supports_color_temp = False @@ -445,10 +448,10 @@ class ZwaveBlackIsOffLight(ZwaveLight): """ def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize the light.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self._last_color: dict[str, int] | None = None self._supported_color_modes.discard(ColorMode.BRIGHTNESS) diff --git a/homeassistant/components/zwave_js/lock.py b/homeassistant/components/zwave_js/lock.py index 3781821e4c7..e7fbbeb3f99 100644 --- a/homeassistant/components/zwave_js/lock.py +++ b/homeassistant/components/zwave_js/lock.py @@ -61,8 +61,10 @@ async def async_setup_entry( @callback def async_add_lock(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave Lock.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[ZWaveBaseEntity] = [] - entities.append(ZWaveLock(config_entry, client, info)) + entities.append(ZWaveLock(config_entry, driver, info)) async_add_entities(entities) diff --git a/homeassistant/components/zwave_js/migrate.py b/homeassistant/components/zwave_js/migrate.py index 1413bf8e5b4..400c2b3cffe 100644 --- a/homeassistant/components/zwave_js/migrate.py +++ b/homeassistant/components/zwave_js/migrate.py @@ -4,7 +4,7 @@ from __future__ import annotations from dataclasses import dataclass import logging -from zwave_js_server.client import Client as ZwaveClient +from zwave_js_server.model.driver import Driver from zwave_js_server.model.value import Value as ZwaveValue from homeassistant.const import STATE_UNAVAILABLE @@ -138,12 +138,12 @@ def async_migrate_discovered_value( ent_reg: EntityRegistry, registered_unique_ids: set[str], device: DeviceEntry, - client: ZwaveClient, + driver: Driver, disc_info: ZwaveDiscoveryInfo, ) -> None: """Migrate unique ID for entity/entities tied to discovered value.""" - new_unique_id = get_unique_id(client, disc_info.primary_value.value_id) + new_unique_id = get_unique_id(driver, disc_info.primary_value.value_id) # On reinterviews, there is no point in going through this logic again for already # discovered values @@ -155,7 +155,7 @@ def async_migrate_discovered_value( # 2021.2.*, 2021.3.0b0, and 2021.3.0 formats old_unique_ids = [ - get_unique_id(client, value_id) + get_unique_id(driver, value_id) for value_id in get_old_value_ids(disc_info.primary_value) ] diff --git a/homeassistant/components/zwave_js/number.py b/homeassistant/components/zwave_js/number.py index fb9266ac071..56a7ce33be6 100644 --- a/homeassistant/components/zwave_js/number.py +++ b/homeassistant/components/zwave_js/number.py @@ -3,6 +3,7 @@ from __future__ import annotations from zwave_js_server.client import Client as ZwaveClient from zwave_js_server.const import TARGET_VALUE_PROPERTY +from zwave_js_server.model.driver import Driver from homeassistant.components.number import DOMAIN as NUMBER_DOMAIN, NumberEntity from homeassistant.config_entries import ConfigEntry @@ -28,11 +29,13 @@ async def async_setup_entry( @callback def async_add_number(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave number entity.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[ZWaveBaseEntity] = [] if info.platform_hint == "volume": - entities.append(ZwaveVolumeNumberEntity(config_entry, client, info)) + entities.append(ZwaveVolumeNumberEntity(config_entry, driver, info)) else: - entities.append(ZwaveNumberEntity(config_entry, client, info)) + entities.append(ZwaveNumberEntity(config_entry, driver, info)) async_add_entities(entities) config_entry.async_on_unload( @@ -48,10 +51,10 @@ class ZwaveNumberEntity(ZWaveBaseEntity, NumberEntity): """Representation of a Z-Wave number entity.""" def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize a ZwaveNumberEntity entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) if self.info.primary_value.metadata.writeable: self._target_value = self.info.primary_value else: @@ -99,10 +102,10 @@ class ZwaveVolumeNumberEntity(ZWaveBaseEntity, NumberEntity): """Representation of a volume number entity.""" def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize a ZwaveVolumeNumberEntity entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self.correction_factor = int( self.info.primary_value.metadata.max - self.info.primary_value.metadata.min ) diff --git a/homeassistant/components/zwave_js/select.py b/homeassistant/components/zwave_js/select.py index 085c694fc0e..f8cb294919e 100644 --- a/homeassistant/components/zwave_js/select.py +++ b/homeassistant/components/zwave_js/select.py @@ -6,6 +6,7 @@ from typing import cast from zwave_js_server.client import Client as ZwaveClient from zwave_js_server.const import TARGET_VALUE_PROPERTY, CommandClass from zwave_js_server.const.command_class.sound_switch import ToneID +from zwave_js_server.model.driver import Driver from homeassistant.components.select import DOMAIN as SELECT_DOMAIN, SelectEntity from homeassistant.config_entries import ConfigEntry @@ -32,15 +33,17 @@ async def async_setup_entry( @callback def async_add_select(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave select entity.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[ZWaveBaseEntity] = [] if info.platform_hint == "Default tone": - entities.append(ZwaveDefaultToneSelectEntity(config_entry, client, info)) + entities.append(ZwaveDefaultToneSelectEntity(config_entry, driver, info)) elif info.platform_hint == "multilevel_switch": entities.append( - ZwaveMultilevelSwitchSelectEntity(config_entry, client, info) + ZwaveMultilevelSwitchSelectEntity(config_entry, driver, info) ) else: - entities.append(ZwaveSelectEntity(config_entry, client, info)) + entities.append(ZwaveSelectEntity(config_entry, driver, info)) async_add_entities(entities) config_entry.async_on_unload( @@ -58,10 +61,10 @@ class ZwaveSelectEntity(ZWaveBaseEntity, SelectEntity): _attr_entity_category = EntityCategory.CONFIG def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize a ZwaveSelectEntity entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) # Entity class attributes self._attr_name = self.generate_name(include_value_name=True) @@ -94,10 +97,10 @@ class ZwaveDefaultToneSelectEntity(ZWaveBaseEntity, SelectEntity): _attr_entity_category = EntityCategory.CONFIG def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize a ZwaveDefaultToneSelectEntity entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self._tones_value = self.get_zwave_value( "toneId", command_class=CommandClass.SOUND_SWITCH ) @@ -145,10 +148,10 @@ class ZwaveMultilevelSwitchSelectEntity(ZWaveBaseEntity, SelectEntity): """Representation of a Z-Wave Multilevel Switch CC select entity.""" def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize a ZwaveSelectEntity entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self._target_value = self.get_zwave_value(TARGET_VALUE_PROPERTY) assert self.info.platform_data_template self._lookup_map = cast( diff --git a/homeassistant/components/zwave_js/sensor.py b/homeassistant/components/zwave_js/sensor.py index 71e6bc48952..eb5bf778cc0 100644 --- a/homeassistant/components/zwave_js/sensor.py +++ b/homeassistant/components/zwave_js/sensor.py @@ -12,6 +12,7 @@ from zwave_js_server.const.command_class.meter import ( RESET_METER_OPTION_TARGET_VALUE, RESET_METER_OPTION_TYPE, ) +from zwave_js_server.model.driver import Driver from zwave_js_server.model.node import Node as ZwaveNode from zwave_js_server.model.value import ConfigurationValue from zwave_js_server.util.command_class.meter import get_meter_type @@ -179,6 +180,8 @@ async def async_setup_entry( @callback def async_add_sensor(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave Sensor.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[ZWaveBaseEntity] = [] if info.platform_data: @@ -191,13 +194,13 @@ async def async_setup_entry( if info.platform_hint == "string_sensor": entities.append( - ZWaveStringSensor(config_entry, client, info, entity_description) + ZWaveStringSensor(config_entry, driver, info, entity_description) ) elif info.platform_hint == "numeric_sensor": entities.append( ZWaveNumericSensor( config_entry, - client, + driver, info, entity_description, data.unit_of_measurement, @@ -205,17 +208,17 @@ async def async_setup_entry( ) elif info.platform_hint == "list_sensor": entities.append( - ZWaveListSensor(config_entry, client, info, entity_description) + ZWaveListSensor(config_entry, driver, info, entity_description) ) elif info.platform_hint == "config_parameter": entities.append( ZWaveConfigParameterSensor( - config_entry, client, info, entity_description + config_entry, driver, info, entity_description ) ) elif info.platform_hint == "meter": entities.append( - ZWaveMeterSensor(config_entry, client, info, entity_description) + ZWaveMeterSensor(config_entry, driver, info, entity_description) ) else: LOGGER.warning( @@ -230,7 +233,9 @@ async def async_setup_entry( @callback def async_add_node_status_sensor(node: ZwaveNode) -> None: """Add node status sensor.""" - async_add_entities([ZWaveNodeStatusSensor(config_entry, client, node)]) + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. + async_add_entities([ZWaveNodeStatusSensor(config_entry, driver, node)]) config_entry.async_on_unload( async_dispatcher_connect( @@ -265,13 +270,13 @@ class ZwaveSensorBase(ZWaveBaseEntity, SensorEntity): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, entity_description: SensorEntityDescription, unit_of_measurement: str | None = None, ) -> None: """Initialize a ZWaveSensorBase entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self.entity_description = entity_description self._attr_native_unit_of_measurement = unit_of_measurement @@ -370,14 +375,14 @@ class ZWaveListSensor(ZwaveSensorBase): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, entity_description: SensorEntityDescription, unit_of_measurement: str | None = None, ) -> None: """Initialize a ZWaveListSensor entity.""" super().__init__( - config_entry, client, info, entity_description, unit_of_measurement + config_entry, driver, info, entity_description, unit_of_measurement ) # Entity class attributes @@ -414,14 +419,14 @@ class ZWaveConfigParameterSensor(ZwaveSensorBase): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, entity_description: SensorEntityDescription, unit_of_measurement: str | None = None, ) -> None: """Initialize a ZWaveConfigParameterSensor entity.""" super().__init__( - config_entry, client, info, entity_description, unit_of_measurement + config_entry, driver, info, entity_description, unit_of_measurement ) self._primary_value = cast(ConfigurationValue, self.info.primary_value) @@ -466,11 +471,10 @@ class ZWaveNodeStatusSensor(SensorEntity): _attr_entity_category = EntityCategory.DIAGNOSTIC def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, node: ZwaveNode + self, config_entry: ConfigEntry, driver: Driver, node: ZwaveNode ) -> None: """Initialize a generic Z-Wave device entity.""" self.config_entry = config_entry - self.client = client self.node = node name: str = ( self.node.name @@ -479,11 +483,11 @@ class ZWaveNodeStatusSensor(SensorEntity): ) # Entity class attributes self._attr_name = f"{name}: Node Status" - self._base_unique_id = get_valueless_base_unique_id(client, node) + self._base_unique_id = get_valueless_base_unique_id(driver, node) self._attr_unique_id = f"{self._base_unique_id}.node_status" # device is precreated in main handler self._attr_device_info = DeviceInfo( - identifiers={get_device_id(self.client, self.node)}, + identifiers={get_device_id(driver, self.node)}, ) self._attr_native_value: str = node.status.name.lower() diff --git a/homeassistant/components/zwave_js/siren.py b/homeassistant/components/zwave_js/siren.py index e686c5446ca..67e6aa4afb4 100644 --- a/homeassistant/components/zwave_js/siren.py +++ b/homeassistant/components/zwave_js/siren.py @@ -5,6 +5,7 @@ from typing import Any from zwave_js_server.client import Client as ZwaveClient from zwave_js_server.const.command_class.sound_switch import ToneID +from zwave_js_server.model.driver import Driver from homeassistant.components.siren import ( DOMAIN as SIREN_DOMAIN, @@ -35,8 +36,10 @@ async def async_setup_entry( @callback def async_add_siren(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave siren entity.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[ZWaveBaseEntity] = [] - entities.append(ZwaveSirenEntity(config_entry, client, info)) + entities.append(ZwaveSirenEntity(config_entry, driver, info)) async_add_entities(entities) config_entry.async_on_unload( @@ -52,10 +55,10 @@ class ZwaveSirenEntity(ZWaveBaseEntity, SirenEntity): """Representation of a Z-Wave siren entity.""" def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize a ZwaveSirenEntity entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) # Entity class attributes self._attr_available_tones = { int(id): val for id, val in self.info.primary_value.metadata.states.items() diff --git a/homeassistant/components/zwave_js/switch.py b/homeassistant/components/zwave_js/switch.py index 115f90b8e11..52b8f813326 100644 --- a/homeassistant/components/zwave_js/switch.py +++ b/homeassistant/components/zwave_js/switch.py @@ -9,6 +9,7 @@ from zwave_js_server.const import TARGET_VALUE_PROPERTY from zwave_js_server.const.command_class.barrier_operator import ( BarrierEventSignalingSubsystemState, ) +from zwave_js_server.model.driver import Driver from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN, SwitchEntity from homeassistant.config_entries import ConfigEntry @@ -36,13 +37,15 @@ async def async_setup_entry( @callback def async_add_switch(info: ZwaveDiscoveryInfo) -> None: """Add Z-Wave Switch.""" + driver = client.driver + assert driver is not None # Driver is ready before platforms are loaded. entities: list[ZWaveBaseEntity] = [] if info.platform_hint == "barrier_event_signaling_state": entities.append( - ZWaveBarrierEventSignalingSwitch(config_entry, client, info) + ZWaveBarrierEventSignalingSwitch(config_entry, driver, info) ) else: - entities.append(ZWaveSwitch(config_entry, client, info)) + entities.append(ZWaveSwitch(config_entry, driver, info)) async_add_entities(entities) @@ -59,10 +62,10 @@ class ZWaveSwitch(ZWaveBaseEntity, SwitchEntity): """Representation of a Z-Wave switch.""" def __init__( - self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo + self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo ) -> None: """Initialize the switch.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self._target_value = self.get_zwave_value(TARGET_VALUE_PROPERTY) @@ -91,11 +94,11 @@ class ZWaveBarrierEventSignalingSwitch(ZWaveBaseEntity, SwitchEntity): def __init__( self, config_entry: ConfigEntry, - client: ZwaveClient, + driver: Driver, info: ZwaveDiscoveryInfo, ) -> None: """Initialize a ZWaveBarrierEventSignalingSwitch entity.""" - super().__init__(config_entry, client, info) + super().__init__(config_entry, driver, info) self._state: bool | None = None self._update_state() diff --git a/homeassistant/components/zwave_js/triggers/event.py b/homeassistant/components/zwave_js/triggers/event.py index fd46c89832b..83fd7570ab9 100644 --- a/homeassistant/components/zwave_js/triggers/event.py +++ b/homeassistant/components/zwave_js/triggers/event.py @@ -207,7 +207,9 @@ async def async_attach_trigger( unsubs.append(source.on(event_name, async_on_event)) for node in nodes: - device_identifier = get_device_id(node.client, node) + driver = node.client.driver + assert driver is not None # The node comes from the driver. + device_identifier = get_device_id(driver, node) device = dev_reg.async_get_device({device_identifier}) assert device # We need to store the device for the callback diff --git a/homeassistant/components/zwave_js/triggers/value_updated.py b/homeassistant/components/zwave_js/triggers/value_updated.py index 8a0b287c26b..38a19eaa377 100644 --- a/homeassistant/components/zwave_js/triggers/value_updated.py +++ b/homeassistant/components/zwave_js/triggers/value_updated.py @@ -162,7 +162,9 @@ async def async_attach_trigger( dev_reg = dr.async_get(hass) for node in nodes: - device_identifier = get_device_id(node.client, node) + driver = node.client.driver + assert driver is not None # The node comes from the driver. + device_identifier = get_device_id(driver, node) device = dev_reg.async_get_device({device_identifier}) assert device value_id = get_value_id(node, command_class, property_, endpoint, property_key) diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index 3d491b98f93..58c26cd5797 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -78,7 +78,7 @@ from homeassistant.helpers import device_registry as dr def get_device(hass, node): """Get device ID for a node.""" dev_reg = dr.async_get(hass) - device_id = get_device_id(node.client, node) + device_id = get_device_id(node.client.driver, node) return dev_reg.async_get_device({device_id}) @@ -124,11 +124,12 @@ async def test_node_ready( node_data = deepcopy(multisensor_6_state) # Copy to allow modification in tests. node = Node(client, node_data) node.data["ready"] = False - client.driver.controller.nodes[node.node_id] = node + driver = client.driver + driver.controller.nodes[node.node_id] = node dev_reg = dr.async_get(hass) device = dev_reg.async_get_or_create( - config_entry_id=entry.entry_id, identifiers={get_device_id(client, node)} + config_entry_id=entry.entry_id, identifiers={get_device_id(driver, node)} ) await ws_client.send_json( diff --git a/tests/components/zwave_js/test_button.py b/tests/components/zwave_js/test_button.py index 29858e0eb97..5ae5f8e7254 100644 --- a/tests/components/zwave_js/test_button.py +++ b/tests/components/zwave_js/test_button.py @@ -49,11 +49,12 @@ async def test_ping_entity( assert "There is no value to refresh for this entity" in caplog.text # Assert a node ping button entity is not created for the controller - node = client.driver.controller.nodes[1] + driver = client.driver + node = driver.controller.nodes[1] assert node.is_controller_node assert ( async_get(hass).async_get_entity_id( - DOMAIN, "sensor", f"{get_valueless_base_unique_id(client, node)}.ping" + DOMAIN, "sensor", f"{get_valueless_base_unique_id(driver, node)}.ping" ) is None ) diff --git a/tests/components/zwave_js/test_device_action.py b/tests/components/zwave_js/test_device_action.py index b8fa43d9cec..ad9d61b3f33 100644 --- a/tests/components/zwave_js/test_device_action.py +++ b/tests/components/zwave_js/test_device_action.py @@ -30,7 +30,9 @@ async def test_get_actions( """Test we get the expected actions from a zwave_js node.""" node = lock_schlage_be469 dev_reg = device_registry.async_get(hass) - device = dev_reg.async_get_device({get_device_id(client, node)}) + driver = client.driver + assert driver + device = dev_reg.async_get_device({get_device_id(driver, node)}) assert device expected_actions = [ { @@ -99,7 +101,9 @@ async def test_get_actions_meter( """Test we get the expected meter actions from a zwave_js node.""" node = aeon_smart_switch_6 dev_reg = device_registry.async_get(hass) - device = dev_reg.async_get_device({get_device_id(client, node)}) + driver = client.driver + assert driver + device = dev_reg.async_get_device({get_device_id(driver, node)}) assert device actions = await async_get_device_automations( hass, DeviceAutomationType.ACTION, device.id @@ -116,7 +120,9 @@ async def test_actions( ) -> None: """Test actions.""" node = climate_radio_thermostat_ct100_plus - device_id = get_device_id(client, node) + driver = client.driver + assert driver + device_id = get_device_id(driver, node) dev_reg = device_registry.async_get(hass) device = dev_reg.async_get_device({device_id}) assert device @@ -236,7 +242,9 @@ async def test_actions_multiple_calls( ) -> None: """Test actions can be called multiple times and still work.""" node = climate_radio_thermostat_ct100_plus - device_id = get_device_id(client, node) + driver = client.driver + assert driver + device_id = get_device_id(driver, node) dev_reg = device_registry.async_get(hass) device = dev_reg.async_get_device({device_id}) assert device @@ -281,7 +289,9 @@ async def test_lock_actions( ) -> None: """Test actions for locks.""" node = lock_schlage_be469 - device_id = get_device_id(client, node) + driver = client.driver + assert driver + device_id = get_device_id(driver, node) dev_reg = device_registry.async_get(hass) device = dev_reg.async_get_device({device_id}) assert device @@ -350,7 +360,9 @@ async def test_reset_meter_action( ) -> None: """Test reset_meter action.""" node = aeon_smart_switch_6 - device_id = get_device_id(client, node) + driver = client.driver + assert driver + device_id = get_device_id(driver, node) dev_reg = device_registry.async_get(hass) device = dev_reg.async_get_device({device_id}) assert device @@ -613,7 +625,9 @@ async def test_get_action_capabilities_meter_triggers( """Test we get the expected action capabilities for meter triggers.""" node = aeon_smart_switch_6 dev_reg = device_registry.async_get(hass) - device = dev_reg.async_get_device({get_device_id(client, node)}) + driver = client.driver + assert driver + device = dev_reg.async_get_device({get_device_id(driver, node)}) assert device capabilities = await device_action.async_get_action_capabilities( hass, @@ -669,7 +683,9 @@ async def test_unavailable_entity_actions( await hass.async_block_till_done() node = lock_schlage_be469 dev_reg = device_registry.async_get(hass) - device = dev_reg.async_get_device({get_device_id(client, node)}) + driver = client.driver + assert driver + device = dev_reg.async_get_device({get_device_id(driver, node)}) assert device actions = await async_get_device_automations( hass, DeviceAutomationType.ACTION, device.id diff --git a/tests/components/zwave_js/test_diagnostics.py b/tests/components/zwave_js/test_diagnostics.py index 99475cd63ec..8d00c9a2f64 100644 --- a/tests/components/zwave_js/test_diagnostics.py +++ b/tests/components/zwave_js/test_diagnostics.py @@ -51,7 +51,7 @@ async def test_device_diagnostics( ): """Test the device level diagnostics data dump.""" dev_reg = async_get(hass) - device = dev_reg.async_get_device({get_device_id(client, multisensor_6)}) + device = dev_reg.async_get_device({get_device_id(client.driver, multisensor_6)}) assert device # Update a value and ensure it is reflected in the node state diff --git a/tests/components/zwave_js/test_init.py b/tests/components/zwave_js/test_init.py index 7b3fd773839..a2962261ac3 100644 --- a/tests/components/zwave_js/test_init.py +++ b/tests/components/zwave_js/test_init.py @@ -800,8 +800,10 @@ async def test_removed_device( hass, client, climate_radio_thermostat_ct100_plus, lock_schlage_be469, integration ): """Test that the device registry gets updated when a device gets removed.""" + driver = client.driver + assert driver # Verify how many nodes are available - assert len(client.driver.controller.nodes) == 2 + assert len(driver.controller.nodes) == 2 # Make sure there are the same number of devices dev_reg = dr.async_get(hass) @@ -814,7 +816,7 @@ async def test_removed_device( assert len(entity_entries) == 29 # Remove a node and reload the entry - old_node = client.driver.controller.nodes.pop(13) + old_node = driver.controller.nodes.pop(13) await hass.config_entries.async_reload(integration.entry_id) await hass.async_block_till_done() @@ -824,7 +826,7 @@ async def test_removed_device( assert len(device_entries) == 1 entity_entries = er.async_entries_for_config_entry(ent_reg, integration.entry_id) assert len(entity_entries) == 17 - assert dev_reg.async_get_device({get_device_id(client, old_node)}) is None + assert dev_reg.async_get_device({get_device_id(driver, old_node)}) is None async def test_suggested_area(hass, client, eaton_rf9640_dimmer): diff --git a/tests/components/zwave_js/test_migrate.py b/tests/components/zwave_js/test_migrate.py index 37c53700d95..cf1e3ee7eaa 100644 --- a/tests/components/zwave_js/test_migrate.py +++ b/tests/components/zwave_js/test_migrate.py @@ -190,12 +190,14 @@ async def test_old_entity_migration( ): """Test old entity on a different endpoint is migrated to a new one.""" node = Node(client, copy.deepcopy(hank_binary_switch_state)) + driver = client.driver + assert driver ent_reg = er.async_get(hass) dev_reg = dr.async_get(hass) device = dev_reg.async_get_or_create( config_entry_id=integration.entry_id, - identifiers={get_device_id(client, node)}, + identifiers={get_device_id(driver, node)}, manufacturer=hank_binary_switch_state["deviceConfig"]["manufacturer"], model=hank_binary_switch_state["deviceConfig"]["label"], ) @@ -204,7 +206,7 @@ async def test_old_entity_migration( entity_name = SENSOR_NAME.split(".")[1] # Create entity RegistryEntry using fake endpoint - old_unique_id = f"{client.driver.controller.home_id}.32-50-1-value-66049" + old_unique_id = f"{driver.controller.home_id}.32-50-1-value-66049" entity_entry = ent_reg.async_get_or_create( "sensor", DOMAIN, @@ -221,7 +223,7 @@ async def test_old_entity_migration( for i in range(0, 2): # Add a ready node, unique ID should be migrated event = {"node": node} - client.driver.controller.emit("node added", event) + driver.controller.emit("node added", event) await hass.async_block_till_done() # Check that new RegistryEntry is using new unique ID format @@ -236,12 +238,14 @@ async def test_different_endpoint_migration_status_sensor( ): """Test that the different endpoint migration logic skips over the status sensor.""" node = Node(client, copy.deepcopy(hank_binary_switch_state)) + driver = client.driver + assert driver ent_reg = er.async_get(hass) dev_reg = dr.async_get(hass) device = dev_reg.async_get_or_create( config_entry_id=integration.entry_id, - identifiers={get_device_id(client, node)}, + identifiers={get_device_id(driver, node)}, manufacturer=hank_binary_switch_state["deviceConfig"]["manufacturer"], model=hank_binary_switch_state["deviceConfig"]["label"], ) @@ -250,7 +254,7 @@ async def test_different_endpoint_migration_status_sensor( entity_name = SENSOR_NAME.split(".")[1] # Create entity RegistryEntry using fake endpoint - old_unique_id = f"{client.driver.controller.home_id}.32.node_status" + old_unique_id = f"{driver.controller.home_id}.32.node_status" entity_entry = ent_reg.async_get_or_create( "sensor", DOMAIN, @@ -267,7 +271,7 @@ async def test_different_endpoint_migration_status_sensor( for i in range(0, 2): # Add a ready node, unique ID should be migrated event = {"node": node} - client.driver.controller.emit("node added", event) + driver.controller.emit("node added", event) await hass.async_block_till_done() # Check that the RegistryEntry is using the same unique ID @@ -280,12 +284,14 @@ async def test_skip_old_entity_migration_for_multiple( ): """Test that multiple entities of the same value but on a different endpoint get skipped.""" node = Node(client, copy.deepcopy(hank_binary_switch_state)) + driver = client.driver + assert driver ent_reg = er.async_get(hass) dev_reg = dr.async_get(hass) device = dev_reg.async_get_or_create( config_entry_id=integration.entry_id, - identifiers={get_device_id(client, node)}, + identifiers={get_device_id(driver, node)}, manufacturer=hank_binary_switch_state["deviceConfig"]["manufacturer"], model=hank_binary_switch_state["deviceConfig"]["label"], ) @@ -294,7 +300,7 @@ async def test_skip_old_entity_migration_for_multiple( entity_name = SENSOR_NAME.split(".")[1] # Create two entity entrrys using different endpoints - old_unique_id_1 = f"{client.driver.controller.home_id}.32-50-1-value-66049" + old_unique_id_1 = f"{driver.controller.home_id}.32-50-1-value-66049" entity_entry = ent_reg.async_get_or_create( "sensor", DOMAIN, @@ -308,7 +314,7 @@ async def test_skip_old_entity_migration_for_multiple( assert entity_entry.unique_id == old_unique_id_1 # Create two entity entrrys using different endpoints - old_unique_id_2 = f"{client.driver.controller.home_id}.32-50-2-value-66049" + old_unique_id_2 = f"{driver.controller.home_id}.32-50-2-value-66049" entity_entry = ent_reg.async_get_or_create( "sensor", DOMAIN, @@ -322,12 +328,12 @@ async def test_skip_old_entity_migration_for_multiple( assert entity_entry.unique_id == old_unique_id_2 # Add a ready node, unique ID should be migrated event = {"node": node} - client.driver.controller.emit("node added", event) + driver.controller.emit("node added", event) await hass.async_block_till_done() # Check that new RegistryEntry is created using new unique ID format entity_entry = ent_reg.async_get(SENSOR_NAME) - new_unique_id = f"{client.driver.controller.home_id}.32-50-0-value-66049" + new_unique_id = f"{driver.controller.home_id}.32-50-0-value-66049" assert entity_entry.unique_id == new_unique_id # Check that the old entities stuck around because we skipped the migration step @@ -340,12 +346,14 @@ async def test_old_entity_migration_notification_binary_sensor( ): """Test old entity on a different endpoint is migrated to a new one for a notification binary sensor.""" node = Node(client, copy.deepcopy(multisensor_6_state)) + driver = client.driver + assert driver ent_reg = er.async_get(hass) dev_reg = dr.async_get(hass) device = dev_reg.async_get_or_create( config_entry_id=integration.entry_id, - identifiers={get_device_id(client, node)}, + identifiers={get_device_id(driver, node)}, manufacturer=multisensor_6_state["deviceConfig"]["manufacturer"], model=multisensor_6_state["deviceConfig"]["label"], ) @@ -353,7 +361,9 @@ async def test_old_entity_migration_notification_binary_sensor( entity_name = NOTIFICATION_MOTION_BINARY_SENSOR.split(".")[1] # Create entity RegistryEntry using old unique ID format - old_unique_id = f"{client.driver.controller.home_id}.52-113-1-Home Security-Motion sensor status.8" + old_unique_id = ( + f"{driver.controller.home_id}.52-113-1-Home Security-Motion sensor status.8" + ) entity_entry = ent_reg.async_get_or_create( "binary_sensor", DOMAIN, @@ -370,12 +380,14 @@ async def test_old_entity_migration_notification_binary_sensor( for _ in range(0, 2): # Add a ready node, unique ID should be migrated event = {"node": node} - client.driver.controller.emit("node added", event) + driver.controller.emit("node added", event) await hass.async_block_till_done() # Check that new RegistryEntry is using new unique ID format entity_entry = ent_reg.async_get(NOTIFICATION_MOTION_BINARY_SENSOR) - new_unique_id = f"{client.driver.controller.home_id}.52-113-0-Home Security-Motion sensor status.8" + new_unique_id = ( + f"{driver.controller.home_id}.52-113-0-Home Security-Motion sensor status.8" + ) assert entity_entry.unique_id == new_unique_id assert ( ent_reg.async_get_entity_id("binary_sensor", DOMAIN, old_unique_id) is None diff --git a/tests/components/zwave_js/test_sensor.py b/tests/components/zwave_js/test_sensor.py index 1d41e145a95..848c4d7b0e5 100644 --- a/tests/components/zwave_js/test_sensor.py +++ b/tests/components/zwave_js/test_sensor.py @@ -205,13 +205,14 @@ async def test_node_status_sensor( assert hass.states.get(NODE_STATUS_ENTITY).state != STATE_UNAVAILABLE # Assert a node status sensor entity is not created for the controller - node = client.driver.controller.nodes[1] + driver = client.driver + node = driver.controller.nodes[1] assert node.is_controller_node assert ( ent_reg.async_get_entity_id( DOMAIN, "sensor", - f"{get_valueless_base_unique_id(client, node)}.node_status", + f"{get_valueless_base_unique_id(driver, node)}.node_status", ) is None ) diff --git a/tests/components/zwave_js/test_services.py b/tests/components/zwave_js/test_services.py index e04ec569c9f..dec4c3c0a9d 100644 --- a/tests/components/zwave_js/test_services.py +++ b/tests/components/zwave_js/test_services.py @@ -1367,11 +1367,11 @@ async def test_multicast_set_value( # Test using area ID dev_reg = async_get_dev_reg(hass) device_eurotronic = dev_reg.async_get_device( - {get_device_id(client, climate_eurotronic_spirit_z)} + {get_device_id(client.driver, climate_eurotronic_spirit_z)} ) assert device_eurotronic device_danfoss = dev_reg.async_get_device( - {get_device_id(client, climate_danfoss_lc_13)} + {get_device_id(client.driver, climate_danfoss_lc_13)} ) assert device_danfoss area_reg = async_get_area_reg(hass) @@ -1655,11 +1655,15 @@ async def test_ping( """Test ping service.""" dev_reg = async_get_dev_reg(hass) device_radio_thermostat = dev_reg.async_get_device( - {get_device_id(client, climate_radio_thermostat_ct100_plus_different_endpoints)} + { + get_device_id( + client.driver, climate_radio_thermostat_ct100_plus_different_endpoints + ) + } ) assert device_radio_thermostat device_danfoss = dev_reg.async_get_device( - {get_device_id(client, climate_danfoss_lc_13)} + {get_device_id(client.driver, climate_danfoss_lc_13)} ) assert device_danfoss @@ -1789,11 +1793,15 @@ async def test_invoke_cc_api( """Test invoke_cc_api service.""" dev_reg = async_get_dev_reg(hass) device_radio_thermostat = dev_reg.async_get_device( - {get_device_id(client, climate_radio_thermostat_ct100_plus_different_endpoints)} + { + get_device_id( + client.driver, climate_radio_thermostat_ct100_plus_different_endpoints + ) + } ) assert device_radio_thermostat device_danfoss = dev_reg.async_get_device( - {get_device_id(client, climate_danfoss_lc_13)} + {get_device_id(client.driver, climate_danfoss_lc_13)} ) assert device_danfoss