mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Add missing ZHA metering device types (#109126)
* Update smartenergy.py metering_device_type enums * Added missing enum 127 * Enum 127 is also electric metering type * Meter type constants and status enums in smartenergy cluster handler Addresses https://github.com/home-assistant/core/pull/109126#discussion_r1471383887 Whilst I have the code open I've also added status handlers for the non-electrical meter types. * New tests for different metering device type statuses
This commit is contained in:
parent
bcb9a10d5a
commit
4ec3a17ed0
@ -129,24 +129,67 @@ class MeteringClusterHandler(ClusterHandler):
|
|||||||
Metering.AttributeDefs.unit_of_measure.name: True,
|
Metering.AttributeDefs.unit_of_measure.name: True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METERING_DEVICE_TYPES_ELECTRIC = {
|
||||||
|
0,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
10,
|
||||||
|
11,
|
||||||
|
13,
|
||||||
|
14,
|
||||||
|
15,
|
||||||
|
127,
|
||||||
|
134,
|
||||||
|
135,
|
||||||
|
136,
|
||||||
|
137,
|
||||||
|
138,
|
||||||
|
140,
|
||||||
|
141,
|
||||||
|
142,
|
||||||
|
}
|
||||||
|
METERING_DEVICE_TYPES_GAS = {1, 128}
|
||||||
|
METERING_DEVICE_TYPES_WATER = {2, 129}
|
||||||
|
METERING_DEVICE_TYPES_HEATING_COOLING = {3, 5, 6, 130, 132, 133}
|
||||||
|
|
||||||
metering_device_type = {
|
metering_device_type = {
|
||||||
0: "Electric Metering",
|
0: "Electric Metering",
|
||||||
1: "Gas Metering",
|
1: "Gas Metering",
|
||||||
2: "Water Metering",
|
2: "Water Metering",
|
||||||
3: "Thermal Metering",
|
3: "Thermal Metering", # depreciated
|
||||||
4: "Pressure Metering",
|
4: "Pressure Metering",
|
||||||
5: "Heat Metering",
|
5: "Heat Metering",
|
||||||
6: "Cooling Metering",
|
6: "Cooling Metering",
|
||||||
|
7: "End Use Measurement Device (EUMD) for metering electric vehicle charging",
|
||||||
|
8: "PV Generation Metering",
|
||||||
|
9: "Wind Turbine Generation Metering",
|
||||||
|
10: "Water Turbine Generation Metering",
|
||||||
|
11: "Micro Generation Metering",
|
||||||
|
12: "Solar Hot Water Generation Metering",
|
||||||
|
13: "Electric Metering Element/Phase 1",
|
||||||
|
14: "Electric Metering Element/Phase 2",
|
||||||
|
15: "Electric Metering Element/Phase 3",
|
||||||
|
127: "Mirrored Electric Metering",
|
||||||
128: "Mirrored Gas Metering",
|
128: "Mirrored Gas Metering",
|
||||||
129: "Mirrored Water Metering",
|
129: "Mirrored Water Metering",
|
||||||
130: "Mirrored Thermal Metering",
|
130: "Mirrored Thermal Metering", # depreciated
|
||||||
131: "Mirrored Pressure Metering",
|
131: "Mirrored Pressure Metering",
|
||||||
132: "Mirrored Heat Metering",
|
132: "Mirrored Heat Metering",
|
||||||
133: "Mirrored Cooling Metering",
|
133: "Mirrored Cooling Metering",
|
||||||
|
134: "Mirrored End Use Measurement Device (EUMD) for metering electric vehicle charging",
|
||||||
|
135: "Mirrored PV Generation Metering",
|
||||||
|
136: "Mirrored Wind Turbine Generation Metering",
|
||||||
|
137: "Mirrored Water Turbine Generation Metering",
|
||||||
|
138: "Mirrored Micro Generation Metering",
|
||||||
|
139: "Mirrored Solar Hot Water Generation Metering",
|
||||||
|
140: "Mirrored Electric Metering Element/Phase 1",
|
||||||
|
141: "Mirrored Electric Metering Element/Phase 2",
|
||||||
|
142: "Mirrored Electric Metering Element/Phase 3",
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeviceStatusElectric(enum.IntFlag):
|
class DeviceStatusElectric(enum.IntFlag):
|
||||||
"""Metering Device Status."""
|
"""Electric Metering Device Status."""
|
||||||
|
|
||||||
NO_ALARMS = 0
|
NO_ALARMS = 0
|
||||||
CHECK_METER = 1
|
CHECK_METER = 1
|
||||||
@ -158,6 +201,45 @@ class MeteringClusterHandler(ClusterHandler):
|
|||||||
SERVICE_DISCONNECT = 64
|
SERVICE_DISCONNECT = 64
|
||||||
RESERVED = 128
|
RESERVED = 128
|
||||||
|
|
||||||
|
class DeviceStatusGas(enum.IntFlag):
|
||||||
|
"""Gas Metering Device Status."""
|
||||||
|
|
||||||
|
NO_ALARMS = 0
|
||||||
|
CHECK_METER = 1
|
||||||
|
LOW_BATTERY = 2
|
||||||
|
TAMPER_DETECT = 4
|
||||||
|
NOT_DEFINED = 8
|
||||||
|
LOW_PRESSURE = 16
|
||||||
|
LEAK_DETECT = 32
|
||||||
|
SERVICE_DISCONNECT = 64
|
||||||
|
REVERSE_FLOW = 128
|
||||||
|
|
||||||
|
class DeviceStatusWater(enum.IntFlag):
|
||||||
|
"""Water Metering Device Status."""
|
||||||
|
|
||||||
|
NO_ALARMS = 0
|
||||||
|
CHECK_METER = 1
|
||||||
|
LOW_BATTERY = 2
|
||||||
|
TAMPER_DETECT = 4
|
||||||
|
PIPE_EMPTY = 8
|
||||||
|
LOW_PRESSURE = 16
|
||||||
|
LEAK_DETECT = 32
|
||||||
|
SERVICE_DISCONNECT = 64
|
||||||
|
REVERSE_FLOW = 128
|
||||||
|
|
||||||
|
class DeviceStatusHeatingCooling(enum.IntFlag):
|
||||||
|
"""Heating and Cooling Metering Device Status."""
|
||||||
|
|
||||||
|
NO_ALARMS = 0
|
||||||
|
CHECK_METER = 1
|
||||||
|
LOW_BATTERY = 2
|
||||||
|
TAMPER_DETECT = 4
|
||||||
|
TEMPERATURE_SENSOR = 8
|
||||||
|
BURST_DETECT = 16
|
||||||
|
LEAK_DETECT = 32
|
||||||
|
SERVICE_DISCONNECT = 64
|
||||||
|
REVERSE_FLOW = 128
|
||||||
|
|
||||||
class DeviceStatusDefault(enum.IntFlag):
|
class DeviceStatusDefault(enum.IntFlag):
|
||||||
"""Metering Device Status."""
|
"""Metering Device Status."""
|
||||||
|
|
||||||
@ -198,9 +280,18 @@ class MeteringClusterHandler(ClusterHandler):
|
|||||||
"""Return metering device status."""
|
"""Return metering device status."""
|
||||||
if (status := self.cluster.get(Metering.AttributeDefs.status.name)) is None:
|
if (status := self.cluster.get(Metering.AttributeDefs.status.name)) is None:
|
||||||
return None
|
return None
|
||||||
if self.cluster.get(Metering.AttributeDefs.metering_device_type.name) == 0:
|
|
||||||
# Electric metering device type
|
metering_device_type = self.cluster.get(
|
||||||
|
Metering.AttributeDefs.metering_device_type.name
|
||||||
|
)
|
||||||
|
if metering_device_type in self.METERING_DEVICE_TYPES_ELECTRIC:
|
||||||
return self.DeviceStatusElectric(status)
|
return self.DeviceStatusElectric(status)
|
||||||
|
if metering_device_type in self.METERING_DEVICE_TYPES_GAS:
|
||||||
|
return self.DeviceStatusGas(status)
|
||||||
|
if metering_device_type in self.METERING_DEVICE_TYPES_WATER:
|
||||||
|
return self.DeviceStatusWater(status)
|
||||||
|
if metering_device_type in self.METERING_DEVICE_TYPES_HEATING_COOLING:
|
||||||
|
return self.DeviceStatusHeatingCooling(status)
|
||||||
return self.DeviceStatusDefault(status)
|
return self.DeviceStatusDefault(status)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -155,9 +155,33 @@ async def async_test_metering(hass: HomeAssistant, cluster, entity_id):
|
|||||||
)
|
)
|
||||||
|
|
||||||
await send_attributes_report(
|
await send_attributes_report(
|
||||||
hass, cluster, {"status": 32, "metering_device_type": 1}
|
hass, cluster, {"status": 64 + 8, "metering_device_type": 1}
|
||||||
|
)
|
||||||
|
assert hass.states.get(entity_id).attributes["status"] in (
|
||||||
|
"SERVICE_DISCONNECT|NOT_DEFINED",
|
||||||
|
"NOT_DEFINED|SERVICE_DISCONNECT",
|
||||||
|
)
|
||||||
|
|
||||||
|
await send_attributes_report(
|
||||||
|
hass, cluster, {"status": 64 + 8, "metering_device_type": 2}
|
||||||
|
)
|
||||||
|
assert hass.states.get(entity_id).attributes["status"] in (
|
||||||
|
"SERVICE_DISCONNECT|PIPE_EMPTY",
|
||||||
|
"PIPE_EMPTY|SERVICE_DISCONNECT",
|
||||||
|
)
|
||||||
|
|
||||||
|
await send_attributes_report(
|
||||||
|
hass, cluster, {"status": 64 + 8, "metering_device_type": 5}
|
||||||
|
)
|
||||||
|
assert hass.states.get(entity_id).attributes["status"] in (
|
||||||
|
"SERVICE_DISCONNECT|TEMPERATURE_SENSOR",
|
||||||
|
"TEMPERATURE_SENSOR|SERVICE_DISCONNECT",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Status for other meter types
|
||||||
|
await send_attributes_report(
|
||||||
|
hass, cluster, {"status": 32, "metering_device_type": 4}
|
||||||
)
|
)
|
||||||
# currently only statuses for electric meters are supported
|
|
||||||
assert hass.states.get(entity_id).attributes["status"] in ("<bitmap8.32: 32>", "32")
|
assert hass.states.get(entity_id).attributes["status"] in ("<bitmap8.32: 32>", "32")
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user