Handle zwave_js metadata/value updates when the unit changes (#63579)

* Handle zwave_js metadata updates when the unit changes

* Use value updated event instead of metadata updated event so we don't get an invalid state value

* update comments and formatting

* simplify

* Update tests/components/zwave_js/test_sensor.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/zwave_js/test_sensor.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/zwave_js/test_sensor.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* fix tests

* add additional assertions

* Add unit checks and simplify logic

* Add unit assertion

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Raman Gupta 2022-01-08 07:23:29 -05:00 committed by GitHub
parent b55b802aeb
commit 9e4e43cf77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 1 deletions

View file

@ -56,7 +56,10 @@ from .const import (
SERVICE_RESET_METER,
)
from .discovery import ZwaveDiscoveryInfo
from .discovery_data_template import NumericSensorDataTemplateData
from .discovery_data_template import (
NumericSensorDataTemplate,
NumericSensorDataTemplateData,
)
from .entity import ZWaveBaseEntity
from .helpers import get_device_id
@ -296,6 +299,15 @@ class ZWaveStringSensor(ZwaveSensorBase):
class ZWaveNumericSensor(ZwaveSensorBase):
"""Representation of a Z-Wave Numeric sensor."""
@callback
def on_value_update(self) -> None:
"""Handle scale changes for this value on value updated event."""
self._attr_native_unit_of_measurement = (
NumericSensorDataTemplate()
.resolve_data(self.info.primary_value)
.unit_of_measurement
)
@property
def native_value(self) -> float:
"""Return state of the sensor."""

View file

@ -358,3 +358,65 @@ async def test_special_meters(hass, aeon_smart_switch_6_state, client, integrati
assert state
assert ATTR_DEVICE_CLASS not in state.attributes
assert state.attributes[ATTR_STATE_CLASS] is SensorStateClass.MEASUREMENT
async def test_unit_change(hass, zp3111, client, integration):
"""Test unit change via metadata updated event is handled by numeric sensors."""
entity_id = "sensor.4_in_1_sensor_air_temperature"
state = hass.states.get(entity_id)
assert state
assert state.state == "21.98"
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == TEMP_CELSIUS
event = Event(
"metadata updated",
{
"source": "node",
"event": "metadata updated",
"nodeId": zp3111.node_id,
"args": {
"commandClassName": "Multilevel Sensor",
"commandClass": 49,
"endpoint": 0,
"property": "Air temperature",
"metadata": {
"type": "number",
"readable": True,
"writeable": False,
"label": "Air temperature",
"ccSpecific": {"sensorType": 1, "scale": 1},
"unit": "°F",
},
"propertyName": "Air temperature",
"nodeId": zp3111.node_id,
},
},
)
zp3111.receive_event(event)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert state.state == "21.98"
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == TEMP_CELSIUS
event = Event(
"value updated",
{
"source": "node",
"event": "value updated",
"nodeId": zp3111.node_id,
"args": {
"commandClassName": "Multilevel Sensor",
"commandClass": 49,
"endpoint": 0,
"property": "Air temperature",
"newValue": 212,
"prevValue": 21.98,
"propertyName": "Air temperature",
},
},
)
zp3111.receive_event(event)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert state.state == "100.0"
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == TEMP_CELSIUS