Switch to using entity class attributes where possible in zwave_js (#51207)

* Switch to using entity class attributes where possible in zwave_js

* fix

* revert docstring

* remove unused init

* Revert some changes based on feedback in #51181

* switch to class atributes
This commit is contained in:
Raman Gupta 2021-06-01 04:26:22 -04:00 committed by GitHub
parent 6b0e57e641
commit b91696c139
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 98 additions and 142 deletions

View file

@ -269,7 +269,20 @@ class ZWaveBooleanBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
) -> None:
"""Initialize a ZWaveBooleanBinarySensor entity."""
super().__init__(config_entry, client, info)
self._name = self.generate_name(include_value_name=True)
# Entity class attributes
self._attr_name = self.generate_name(include_value_name=True)
self._attr_device_class = (
DEVICE_CLASS_BATTERY
if self.info.primary_value.command_class == CommandClass.BATTERY
else None
)
# Legacy binary sensors are phased out (replaced by notification sensors)
# Disable by default to not confuse users
self._attr_entity_registry_enabled_default = bool(
self.info.primary_value.command_class != CommandClass.SENSOR_BINARY
or self.info.node.device_class.generic.key == 0x20
)
@property
def is_on(self) -> bool | None:
@ -278,23 +291,6 @@ class ZWaveBooleanBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
return None
return bool(self.info.primary_value.value)
@property
def device_class(self) -> str | None:
"""Return device class."""
if self.info.primary_value.command_class == CommandClass.BATTERY:
return DEVICE_CLASS_BATTERY
return None
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
# Legacy binary sensors are phased out (replaced by notification sensors)
# Disable by default to not confuse users
return bool(
self.info.primary_value.command_class != CommandClass.SENSOR_BINARY
or self.info.node.device_class.generic.key == 0x20
)
class ZWaveNotificationBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
"""Representation of a Z-Wave binary_sensor from Notification CommandClass."""
@ -309,13 +305,20 @@ class ZWaveNotificationBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
"""Initialize a ZWaveNotificationBinarySensor entity."""
super().__init__(config_entry, client, info)
self.state_key = state_key
self._name = self.generate_name(
# check if we have a custom mapping for this value
self._mapping_info = self._get_sensor_mapping()
# Entity class attributes
self._attr_name = self.generate_name(
include_value_name=True,
alternate_value_name=self.info.primary_value.property_name,
additional_info=[self.info.primary_value.metadata.states[self.state_key]],
)
# check if we have a custom mapping for this value
self._mapping_info = self._get_sensor_mapping()
self._attr_device_class = self._mapping_info.get("device_class")
self._attr_unique_id = f"{self._attr_unique_id}.{self.state_key}"
self._attr_entity_registry_enabled_default = (
True if not self._mapping_info else self._mapping_info.get("enabled", True)
)
@property
def is_on(self) -> bool | None:
@ -324,23 +327,6 @@ class ZWaveNotificationBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
return None
return int(self.info.primary_value.value) == int(self.state_key)
@property
def device_class(self) -> str | None:
"""Return device class."""
return self._mapping_info.get("device_class")
@property
def unique_id(self) -> str:
"""Return unique id for this entity."""
return f"{super().unique_id}.{self.state_key}"
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
if not self._mapping_info:
return True
return self._mapping_info.get("enabled", True)
@callback
def _get_sensor_mapping(self) -> NotificationSensorMapping:
"""Try to get a device specific mapping for this sensor."""
@ -366,7 +352,15 @@ class ZWavePropertyBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
super().__init__(config_entry, client, info)
# check if we have a custom mapping for this value
self._mapping_info = self._get_sensor_mapping()
self._name = self.generate_name(include_value_name=True)
# Entity class attributes
self._attr_name = self.generate_name(include_value_name=True)
self._attr_device_class = self._mapping_info.get("device_class")
# We hide some more advanced sensors by default to not overwhelm users
# unless explicitly stated in a mapping, assume deisabled by default
self._attr_entity_registry_enabled_default = self._mapping_info.get(
"enabled", False
)
@property
def is_on(self) -> bool | None:
@ -375,18 +369,6 @@ class ZWavePropertyBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
return None
return self.info.primary_value.value in self._mapping_info["on_states"]
@property
def device_class(self) -> str | None:
"""Return device class."""
return self._mapping_info.get("device_class")
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
# We hide some more advanced sensors by default to not overwhelm users
# unless explicitly stated in a mapping, assume deisabled by default
return self._mapping_info.get("enabled", False)
@callback
def _get_sensor_mapping(self) -> PropertySensorMapping:
"""Try to get a device specific mapping for this sensor."""

View file

@ -79,14 +79,21 @@ def percent_to_zwave_position(value: int) -> int:
class ZWaveCover(ZWaveBaseEntity, CoverEntity):
"""Representation of a Z-Wave Cover device."""
@property
def device_class(self) -> str | None:
"""Return the class of this device, from component DEVICE_CLASSES."""
def __init__(
self,
config_entry: ConfigEntry,
client: ZwaveClient,
info: ZwaveDiscoveryInfo,
) -> None:
"""Initialize a ZWaveCover entity."""
super().__init__(config_entry, client, info)
# Entity class attributes
self._attr_device_class = DEVICE_CLASS_WINDOW
if self.info.platform_hint == "window_shutter":
return DEVICE_CLASS_SHUTTER
self._attr_device_class = DEVICE_CLASS_SHUTTER
if self.info.platform_hint == "window_blind":
return DEVICE_CLASS_BLIND
return DEVICE_CLASS_WINDOW
self._attr_device_class = DEVICE_CLASS_BLIND
@property
def is_closed(self) -> bool | None:
@ -134,6 +141,9 @@ class ZWaveCover(ZWaveBaseEntity, CoverEntity):
class ZwaveMotorizedBarrier(ZWaveBaseEntity, CoverEntity):
"""Representation of a Z-Wave motorized barrier device."""
_attr_supported_features = SUPPORT_OPEN | SUPPORT_CLOSE
_attr_device_class = DEVICE_CLASS_GARAGE
def __init__(
self,
config_entry: ConfigEntry,
@ -146,16 +156,6 @@ class ZwaveMotorizedBarrier(ZWaveBaseEntity, CoverEntity):
"targetState", add_to_watched_value_ids=False
)
@property
def supported_features(self) -> int:
"""Flag supported features."""
return SUPPORT_OPEN | SUPPORT_CLOSE
@property
def device_class(self) -> str | None:
"""Return the class of this device, from component DEVICE_CLASSES."""
return DEVICE_CLASS_GARAGE
@property
def is_opening(self) -> bool | None:
"""Return if the cover is opening or not."""

View file

@ -9,7 +9,7 @@ from zwave_js_server.model.value import Value as ZwaveValue, get_value_id
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import DeviceInfo, Entity
from homeassistant.helpers.entity import Entity
from .const import DOMAIN
from .discovery import ZwaveDiscoveryInfo
@ -30,10 +30,6 @@ class ZWaveBaseEntity(Entity):
self.config_entry = config_entry
self.client = client
self.info = info
self._name = self.generate_name()
self._unique_id = get_unique_id(
self.client.driver.controller.home_id, self.info.primary_value.value_id
)
# entities requiring additional values, can add extra ids to this list
self.watched_value_ids = {self.info.primary_value.value_id}
@ -42,6 +38,17 @@ class ZWaveBaseEntity(Entity):
self.info.additional_value_ids_to_watch
)
# Entity class attributes
self._attr_name = self.generate_name()
self._attr_unique_id = get_unique_id(
self.client.driver.controller.home_id, self.info.primary_value.value_id
)
self._attr_assumed_state = self.info.assumed_state
# device is precreated in main handler
self._attr_device_info = {
"identifiers": {get_device_id(self.client, self.info.node)},
}
@callback
def on_value_update(self) -> None:
"""Call when one of the watched values change.
@ -91,14 +98,6 @@ class ZWaveBaseEntity(Entity):
)
)
@property
def device_info(self) -> DeviceInfo:
"""Return device information for the device registry."""
# device is precreated in main handler
return {
"identifiers": {get_device_id(self.client, self.info.node)},
}
def generate_name(
self,
include_value_name: bool = False,
@ -133,16 +132,6 @@ class ZWaveBaseEntity(Entity):
return name
@property
def name(self) -> str:
"""Return default name from device name and value name combination."""
return self._name
@property
def unique_id(self) -> str:
"""Return the unique_id of the entity."""
return self._unique_id
@property
def available(self) -> bool:
"""Return entity availability."""
@ -229,8 +218,3 @@ class ZWaveBaseEntity(Entity):
def should_poll(self) -> bool:
"""No polling needed."""
return False
@property
def assumed_state(self) -> bool:
"""Return True if unable to access real state of the entity."""
return self.info.assumed_state

View file

@ -107,13 +107,10 @@ class ZwaveLight(ZWaveBaseEntity, LightEntity):
value_property_key=ColorComponent.COLD_WHITE,
)
self._supported_color_modes = set()
self._supported_features = 0
# get additional (optional) values and set features
self._target_value = self.get_zwave_value("targetValue")
self._dimming_duration = self.get_zwave_value("duration")
if self._dimming_duration is not None:
self._supported_features |= SUPPORT_TRANSITION
self._calculate_color_values()
if self._supports_rgbw:
self._supported_color_modes.add(COLOR_MODE_RGBW)
@ -124,6 +121,11 @@ class ZwaveLight(ZWaveBaseEntity, LightEntity):
if not self._supported_color_modes:
self._supported_color_modes.add(COLOR_MODE_BRIGHTNESS)
# Entity class attributes
self._attr_supported_features = 0
if self._dimming_duration is not None:
self._attr_supported_features |= SUPPORT_TRANSITION
@callback
def on_value_update(self) -> None:
"""Call when a watched value is added or updated."""
@ -179,11 +181,6 @@ class ZwaveLight(ZWaveBaseEntity, LightEntity):
"""Flag supported features."""
return self._supported_color_modes
@property
def supported_features(self) -> int:
"""Flag supported features."""
return self._supported_features
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the device on."""
# RGB/HS color

View file

@ -46,14 +46,16 @@ class ZwaveNumberEntity(ZWaveBaseEntity, NumberEntity):
) -> None:
"""Initialize a ZwaveNumberEntity entity."""
super().__init__(config_entry, client, info)
self._name = self.generate_name(
include_value_name=True, alternate_value_name=info.platform_hint
)
if self.info.primary_value.metadata.writeable:
self._target_value = self.info.primary_value
else:
self._target_value = self.get_zwave_value("targetValue")
# Entity class attributes
self._attr_name = self.generate_name(
include_value_name=True, alternate_value_name=info.platform_hint
)
@property
def min_value(self) -> float:
"""Return the minimum value."""

View file

@ -101,9 +101,20 @@ class ZwaveSensorBase(ZWaveBaseEntity, SensorEntity):
) -> None:
"""Initialize a ZWaveSensorBase entity."""
super().__init__(config_entry, client, info)
self._name = self.generate_name(include_value_name=True)
self._device_class = self._get_device_class()
self._state_class = self._get_state_class()
# Entity class attributes
self._attr_name = self.generate_name(include_value_name=True)
self._attr_device_class = self._get_device_class()
self._attr_state_class = self._get_state_class()
self._attr_entity_registry_enabled_default = True
# We hide some of the more advanced sensors by default to not overwhelm users
if self.info.primary_value.command_class in [
CommandClass.BASIC,
CommandClass.CONFIGURATION,
CommandClass.INDICATOR,
CommandClass.NOTIFICATION,
]:
self._attr_entity_registry_enabled_default = False
def _get_device_class(self) -> str | None:
"""
@ -145,29 +156,6 @@ class ZwaveSensorBase(ZWaveBaseEntity, SensorEntity):
return STATE_CLASS_MEASUREMENT
return None
@property
def device_class(self) -> str | None:
"""Return the device class of the sensor."""
return self._device_class
@property
def state_class(self) -> str | None:
"""Return the state class of the sensor."""
return self._state_class
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
# We hide some of the more advanced sensors by default to not overwhelm users
if self.info.primary_value.command_class in [
CommandClass.BASIC,
CommandClass.CONFIGURATION,
CommandClass.INDICATOR,
CommandClass.NOTIFICATION,
]:
return False
return True
@property
def force_update(self) -> bool:
"""Force updates."""
@ -203,8 +191,10 @@ class ZWaveNumericSensor(ZwaveSensorBase):
) -> None:
"""Initialize a ZWaveNumericSensor entity."""
super().__init__(config_entry, client, info)
# Entity class attributes
if self.info.primary_value.command_class == CommandClass.BASIC:
self._name = self.generate_name(
self._attr_name = self.generate_name(
include_value_name=True,
alternate_value_name=self.info.primary_value.command_class_name,
)
@ -240,7 +230,9 @@ class ZWaveListSensor(ZwaveSensorBase):
) -> None:
"""Initialize a ZWaveListSensor entity."""
super().__init__(config_entry, client, info)
self._name = self.generate_name(
# Entity class attributes
self._attr_name = self.generate_name(
include_value_name=True,
alternate_value_name=self.info.primary_value.property_name,
additional_info=[self.info.primary_value.property_key_name],
@ -278,13 +270,15 @@ class ZWaveConfigParameterSensor(ZwaveSensorBase):
) -> None:
"""Initialize a ZWaveConfigParameterSensor entity."""
super().__init__(config_entry, client, info)
self._name = self.generate_name(
self._primary_value = cast(ConfigurationValue, self.info.primary_value)
# Entity class attributes
self._attr_name = self.generate_name(
include_value_name=True,
alternate_value_name=self.info.primary_value.property_name,
additional_info=[self.info.primary_value.property_key_name],
name_suffix="Config Parameter",
)
self._primary_value = cast(ConfigurationValue, self.info.primary_value)
@property
def state(self) -> str | None:

View file

@ -88,21 +88,18 @@ class ZWaveBarrierEventSignalingSwitch(ZWaveBaseEntity, SwitchEntity):
) -> None:
"""Initialize a ZWaveBarrierEventSignalingSwitch entity."""
super().__init__(config_entry, client, info)
self._name = self.generate_name(include_value_name=True)
self._state: bool | None = None
self._update_state()
# Entity class attributes
self._attr_name = self.generate_name(include_value_name=True)
@callback
def on_value_update(self) -> None:
"""Call when a watched value is added or updated."""
self._update_state()
@property
def name(self) -> str:
"""Return default name from device name and value name combination."""
return self._name
@property
def is_on(self) -> bool | None: # type: ignore
"""Return a boolean for the state of the switch."""