Refactor zwave_js.sensor and add test coverage (#93259)
* Refactor zwave_js.sensor and add test coverage * use walrus * inherit config parameter class from list class * use walrus in more places * improve config parameter test
This commit is contained in:
parent
d6997d8656
commit
e1dd7118e0
2 changed files with 125 additions and 97 deletions
|
@ -38,10 +38,10 @@ from homeassistant.const import (
|
|||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import entity_platform
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
|
||||
from .const import (
|
||||
ATTR_METER_TYPE,
|
||||
|
@ -311,11 +311,7 @@ async def async_setup_entry(
|
|||
|
||||
entity_description = get_entity_description(data)
|
||||
|
||||
if info.platform_hint == "string_sensor":
|
||||
entities.append(
|
||||
ZWaveStringSensor(config_entry, driver, info, entity_description)
|
||||
)
|
||||
elif info.platform_hint == "numeric_sensor":
|
||||
if info.platform_hint == "numeric_sensor":
|
||||
entities.append(
|
||||
ZWaveNumericSensor(
|
||||
config_entry,
|
||||
|
@ -340,12 +336,7 @@ async def async_setup_entry(
|
|||
ZWaveMeterSensor(config_entry, driver, info, entity_description)
|
||||
)
|
||||
else:
|
||||
LOGGER.warning(
|
||||
"Sensor not implemented for %s/%s",
|
||||
info.platform_hint,
|
||||
info.primary_value.property_name,
|
||||
)
|
||||
return
|
||||
entities.append(ZwaveSensor(config_entry, driver, info, entity_description))
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
@ -383,7 +374,7 @@ async def async_setup_entry(
|
|||
)
|
||||
|
||||
|
||||
class ZwaveSensorBase(ZWaveBaseEntity, SensorEntity):
|
||||
class ZwaveSensor(ZWaveBaseEntity, SensorEntity):
|
||||
"""Basic Representation of a Z-Wave sensor."""
|
||||
|
||||
def __init__(
|
||||
|
@ -403,26 +394,25 @@ class ZwaveSensorBase(ZWaveBaseEntity, SensorEntity):
|
|||
self._attr_force_update = True
|
||||
self._attr_name = self.generate_name(include_value_name=True)
|
||||
|
||||
|
||||
class ZWaveStringSensor(ZwaveSensorBase):
|
||||
"""Representation of a Z-Wave String sensor."""
|
||||
|
||||
@property
|
||||
def native_value(self) -> str | None:
|
||||
def native_value(self) -> StateType:
|
||||
"""Return state of the sensor."""
|
||||
if self.info.primary_value.value is None:
|
||||
return None
|
||||
return str(self.info.primary_value.value)
|
||||
key = str(self.info.primary_value.value)
|
||||
if key not in self.info.primary_value.metadata.states:
|
||||
return self.info.primary_value.value
|
||||
return str(self.info.primary_value.metadata.states[key])
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return unit of measurement the value is expressed in."""
|
||||
if (unit := super().native_unit_of_measurement) is not None:
|
||||
return unit
|
||||
if self.info.primary_value.metadata.unit is None:
|
||||
return None
|
||||
return str(self.info.primary_value.metadata.unit)
|
||||
|
||||
|
||||
class ZWaveNumericSensor(ZwaveSensorBase):
|
||||
class ZWaveNumericSensor(ZwaveSensor):
|
||||
"""Representation of a Z-Wave Numeric sensor."""
|
||||
|
||||
@callback
|
||||
|
@ -439,18 +429,6 @@ class ZWaveNumericSensor(ZwaveSensorBase):
|
|||
return 0
|
||||
return round(float(self.info.primary_value.value), 2)
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return unit of measurement the value is expressed in."""
|
||||
if self.entity_description.native_unit_of_measurement is not None:
|
||||
return self.entity_description.native_unit_of_measurement
|
||||
if self._attr_native_unit_of_measurement is not None:
|
||||
return self._attr_native_unit_of_measurement
|
||||
if self.info.primary_value.metadata.unit is None:
|
||||
return None
|
||||
|
||||
return str(self.info.primary_value.metadata.unit)
|
||||
|
||||
|
||||
class ZWaveMeterSensor(ZWaveNumericSensor):
|
||||
"""Representation of a Z-Wave Meter CC sensor."""
|
||||
|
@ -458,21 +436,18 @@ class ZWaveMeterSensor(ZWaveNumericSensor):
|
|||
@property
|
||||
def extra_state_attributes(self) -> Mapping[str, int | str] | None:
|
||||
"""Return extra state attributes."""
|
||||
if meter_type := get_meter_type(self.info.primary_value):
|
||||
return {
|
||||
ATTR_METER_TYPE: meter_type.value,
|
||||
ATTR_METER_TYPE_NAME: meter_type.name,
|
||||
}
|
||||
return None
|
||||
meter_type = get_meter_type(self.info.primary_value)
|
||||
return {
|
||||
ATTR_METER_TYPE: meter_type.value,
|
||||
ATTR_METER_TYPE_NAME: meter_type.name,
|
||||
}
|
||||
|
||||
async def async_reset_meter(
|
||||
self, meter_type: int | None = None, value: int | None = None
|
||||
) -> None:
|
||||
"""Reset meter(s) on device."""
|
||||
node = self.info.node
|
||||
primary_value = self.info.primary_value
|
||||
if (endpoint := primary_value.endpoint) is None:
|
||||
raise HomeAssistantError("Missing endpoint on device.")
|
||||
endpoint = self.info.primary_value.endpoint or 0
|
||||
options = {}
|
||||
if meter_type is not None:
|
||||
options[RESET_METER_OPTION_TYPE] = meter_type
|
||||
|
@ -485,35 +460,19 @@ class ZWaveMeterSensor(ZWaveNumericSensor):
|
|||
LOGGER.debug(
|
||||
"Meters on node %s endpoint %s reset with the following options: %s",
|
||||
node,
|
||||
primary_value.endpoint,
|
||||
endpoint,
|
||||
options,
|
||||
)
|
||||
|
||||
|
||||
class ZWaveListSensor(ZwaveSensorBase):
|
||||
"""Representation of a Z-Wave List sensor with multiple states."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config_entry: ConfigEntry,
|
||||
driver: Driver,
|
||||
info: ZwaveDiscoveryInfo,
|
||||
entity_description: SensorEntityDescription,
|
||||
unit_of_measurement: str | None = None,
|
||||
) -> None:
|
||||
"""Initialize a ZWaveListSensor entity."""
|
||||
super().__init__(
|
||||
config_entry, driver, info, entity_description, unit_of_measurement
|
||||
)
|
||||
|
||||
# Entity class attributes
|
||||
self._attr_name = self.generate_name(include_value_name=True)
|
||||
class ZWaveListSensor(ZwaveSensor):
|
||||
"""Representation of a Z-Wave Numeric sensor with multiple states."""
|
||||
|
||||
@property
|
||||
def device_class(self) -> SensorDeviceClass | None:
|
||||
"""Return sensor device class."""
|
||||
if super().device_class is not None:
|
||||
return super().device_class
|
||||
if (device_class := super().device_class) is not None:
|
||||
return device_class
|
||||
if self.info.primary_value.metadata.states:
|
||||
return SensorDeviceClass.ENUM
|
||||
return None
|
||||
|
@ -525,16 +484,6 @@ class ZWaveListSensor(ZwaveSensorBase):
|
|||
return list(self.info.primary_value.metadata.states.values())
|
||||
return None
|
||||
|
||||
@property
|
||||
def native_value(self) -> str | None:
|
||||
"""Return state of the sensor."""
|
||||
if self.info.primary_value.value is None:
|
||||
return None
|
||||
key = str(self.info.primary_value.value)
|
||||
if key not in self.info.primary_value.metadata.states:
|
||||
return key
|
||||
return str(self.info.primary_value.metadata.states[key])
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, str] | None:
|
||||
"""Return the device specific state attributes."""
|
||||
|
@ -544,7 +493,7 @@ class ZWaveListSensor(ZwaveSensorBase):
|
|||
return {ATTR_VALUE: value}
|
||||
|
||||
|
||||
class ZWaveConfigParameterSensor(ZwaveSensorBase):
|
||||
class ZWaveConfigParameterSensor(ZWaveListSensor):
|
||||
"""Representation of a Z-Wave config parameter sensor."""
|
||||
|
||||
def __init__(
|
||||
|
@ -572,8 +521,8 @@ class ZWaveConfigParameterSensor(ZwaveSensorBase):
|
|||
@property
|
||||
def device_class(self) -> SensorDeviceClass | None:
|
||||
"""Return sensor device class."""
|
||||
if super().device_class is not None:
|
||||
return super().device_class
|
||||
if (device_class := super(ZwaveSensor, self).device_class) is not None:
|
||||
return device_class
|
||||
if (
|
||||
self._primary_value.configuration_value_type
|
||||
== ConfigurationValueType.ENUMERATED
|
||||
|
@ -581,26 +530,6 @@ class ZWaveConfigParameterSensor(ZwaveSensorBase):
|
|||
return SensorDeviceClass.ENUM
|
||||
return None
|
||||
|
||||
@property
|
||||
def options(self) -> list[str] | None:
|
||||
"""Return options for enum sensor."""
|
||||
if self.device_class == SensorDeviceClass.ENUM:
|
||||
return list(self.info.primary_value.metadata.states.values())
|
||||
return None
|
||||
|
||||
@property
|
||||
def native_value(self) -> str | None:
|
||||
"""Return state of the sensor."""
|
||||
if self.info.primary_value.value is None:
|
||||
return None
|
||||
key = str(self.info.primary_value.value)
|
||||
if (
|
||||
self._primary_value.configuration_value_type == ConfigurationValueType.RANGE
|
||||
or (key not in self.info.primary_value.metadata.states)
|
||||
):
|
||||
return key
|
||||
return str(self.info.primary_value.metadata.states[key])
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, str] | None:
|
||||
"""Return the device specific state attributes."""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue