diff --git a/tests/test_sensor.py b/tests/test_sensor.py index f1eebd9f3..25bbb4a36 100644 --- a/tests/test_sensor.py +++ b/tests/test_sensor.py @@ -85,6 +85,17 @@ async def async_test_humidity( assert_state(entity, 10.0, "%") +async def async_test_flow( + zha_gateway: Gateway, cluster: Cluster, entity: PlatformEntity +) -> None: + """Test flow sensor.""" + await send_attributes_report(zha_gateway, cluster, {1: 1, 0: 40}) + assert_state(entity, 4.0, "m³/h") + + await send_attributes_report(zha_gateway, cluster, {1: 1, 0: 0xFFFF}) + assert_state(entity, None, "m³/h") + + async def async_test_temperature( zha_gateway: Gateway, cluster: Cluster, entity: PlatformEntity ) -> None: @@ -408,6 +419,13 @@ async def async_test_change_source_timestamp( None, None, ), + ( + measurement.FlowMeasurement.cluster_id, + sensor.Flow, + async_test_flow, + None, + None, + ), ( measurement.TemperatureMeasurement.cluster_id, sensor.Temperature, diff --git a/zha/application/platforms/sensor/__init__.py b/zha/application/platforms/sensor/__init__.py index 08140929a..c1095db90 100644 --- a/zha/application/platforms/sensor/__init__.py +++ b/zha/application/platforms/sensor/__init__.py @@ -67,6 +67,7 @@ CLUSTER_HANDLER_DEVICE_TEMPERATURE, CLUSTER_HANDLER_DIAGNOSTIC, CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT, + CLUSTER_HANDLER_FLOW, CLUSTER_HANDLER_HUMIDITY, CLUSTER_HANDLER_ILLUMINANCE, CLUSTER_HANDLER_INOVELLI, @@ -1132,6 +1133,23 @@ class Pressure(Sensor): _attr_native_unit_of_measurement = UnitOfPressure.HPA +@MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_FLOW) +class Flow(Sensor): + """Flow Measurement sensor.""" + + _attribute_name = "measured_value" + _attr_device_class: SensorDeviceClass = SensorDeviceClass.VOLUME_FLOW_RATE + _attr_state_class: SensorStateClass = SensorStateClass.MEASUREMENT + _divisor = 10 + _attr_native_unit_of_measurement = UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR + + def formatter(self, value: int) -> int | float | str | None: + """Handle unknown value state.""" + if value == 0xFFFF: + return None + return super().formatter(value) + + @MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_TEMPERATURE) class Temperature(Sensor): """Temperature Sensor.""" diff --git a/zha/zigbee/cluster_handlers/const.py b/zha/zigbee/cluster_handlers/const.py index 6c6e746b8..2ea2a047d 100644 --- a/zha/zigbee/cluster_handlers/const.py +++ b/zha/zigbee/cluster_handlers/const.py @@ -52,6 +52,7 @@ CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT: Final[str] = "electrical_measurement" CLUSTER_HANDLER_EVENT_RELAY: Final[str] = "event_relay" CLUSTER_HANDLER_FAN: Final[str] = "fan" +CLUSTER_HANDLER_FLOW: Final[str] = "flow" CLUSTER_HANDLER_HUMIDITY: Final[str] = "humidity" CLUSTER_HANDLER_HUE_OCCUPANCY: Final[str] = "philips_occupancy" CLUSTER_HANDLER_SOIL_MOISTURE: Final[str] = "soil_moisture"