1 """Support for EnOcean sensors."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
8 from enocean.utils
import combine_hex
9 import voluptuous
as vol
12 PLATFORM_SCHEMA
as SENSOR_PLATFORM_SCHEMA,
15 SensorEntityDescription,
33 from .entity
import EnOceanEntity
35 CONF_MAX_TEMP =
"max_temp"
36 CONF_MIN_TEMP =
"min_temp"
37 CONF_RANGE_FROM =
"range_from"
38 CONF_RANGE_TO =
"range_to"
40 DEFAULT_NAME =
"EnOcean sensor"
42 SENSOR_TYPE_HUMIDITY =
"humidity"
43 SENSOR_TYPE_POWER =
"powersensor"
44 SENSOR_TYPE_TEMPERATURE =
"temperature"
45 SENSOR_TYPE_WINDOWHANDLE =
"windowhandle"
48 @dataclass(frozen=True, kw_only=True)
50 """Describes EnOcean sensor entity."""
52 unique_id: Callable[[list[int]], str |
None]
56 key=SENSOR_TYPE_TEMPERATURE,
58 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
59 device_class=SensorDeviceClass.TEMPERATURE,
60 state_class=SensorStateClass.MEASUREMENT,
61 unique_id=
lambda dev_id: f
"{combine_hex(dev_id)}-{SENSOR_TYPE_TEMPERATURE}",
65 key=SENSOR_TYPE_HUMIDITY,
67 native_unit_of_measurement=PERCENTAGE,
68 device_class=SensorDeviceClass.HUMIDITY,
69 state_class=SensorStateClass.MEASUREMENT,
70 unique_id=
lambda dev_id: f
"{combine_hex(dev_id)}-{SENSOR_TYPE_HUMIDITY}",
74 key=SENSOR_TYPE_POWER,
76 native_unit_of_measurement=UnitOfPower.WATT,
77 device_class=SensorDeviceClass.POWER,
78 state_class=SensorStateClass.MEASUREMENT,
79 unique_id=
lambda dev_id: f
"{combine_hex(dev_id)}-{SENSOR_TYPE_POWER}",
83 key=SENSOR_TYPE_WINDOWHANDLE,
85 translation_key=
"window_handle",
86 unique_id=
lambda dev_id: f
"{combine_hex(dev_id)}-{SENSOR_TYPE_WINDOWHANDLE}",
90 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
92 vol.Required(CONF_ID): vol.All(cv.ensure_list, [vol.Coerce(int)]),
93 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
94 vol.Optional(CONF_DEVICE_CLASS, default=SENSOR_TYPE_POWER): cv.string,
95 vol.Optional(CONF_MAX_TEMP, default=40): vol.Coerce(int),
96 vol.Optional(CONF_MIN_TEMP, default=0): vol.Coerce(int),
97 vol.Optional(CONF_RANGE_FROM, default=255): cv.positive_int,
98 vol.Optional(CONF_RANGE_TO, default=0): cv.positive_int,
106 add_entities: AddEntitiesCallback,
107 discovery_info: DiscoveryInfoType |
None =
None,
109 """Set up an EnOcean sensor device."""
110 dev_id: list[int] = config[CONF_ID]
111 dev_name: str = config[CONF_NAME]
112 sensor_type: str = config[CONF_DEVICE_CLASS]
114 entities: list[EnOceanSensor] = []
115 if sensor_type == SENSOR_TYPE_TEMPERATURE:
116 temp_min: int = config[CONF_MIN_TEMP]
117 temp_max: int = config[CONF_MAX_TEMP]
118 range_from: int = config[CONF_RANGE_FROM]
119 range_to: int = config[CONF_RANGE_TO]
124 SENSOR_DESC_TEMPERATURE,
127 range_from=range_from,
132 elif sensor_type == SENSOR_TYPE_HUMIDITY:
135 elif sensor_type == SENSOR_TYPE_POWER:
138 elif sensor_type == SENSOR_TYPE_WINDOWHANDLE:
145 """Representation of an EnOcean sensor device such as a power meter."""
151 description: EnOceanSensorEntityDescription,
153 """Initialize the EnOcean sensor device."""
160 """Call when entity about to be added to hass."""
170 """Update the internal state of the sensor."""
173 class EnOceanPowerSensor(EnOceanSensor):
174 """Representation of an EnOcean power sensor.
176 EEPs (EnOcean Equipment Profiles):
177 - A5-12-01 (Automated Meter Reading, Electricity)
181 """Update the internal state of the sensor."""
182 if packet.rorg != 0xA5:
184 packet.parse_eep(0x12, 0x01)
185 if packet.parsed[
"DT"][
"raw_value"] == 1:
187 raw_val = packet.parsed[
"MR"][
"raw_value"]
188 divisor = packet.parsed[
"DIV"][
"raw_value"]
194 """Representation of an EnOcean temperature sensor device.
196 EEPs (EnOcean Equipment Profiles):
197 - A5-02-01 to A5-02-1B All 8 Bit Temperature Sensors of A5-02
198 - A5-10-01 to A5-10-14 (Room Operating Panels)
199 - A5-04-01 (Temp. and Humidity Sensor, Range 0°C to +40°C and 0% to 100%)
200 - A5-04-02 (Temp. and Humidity Sensor, Range -20°C to +60°C and 0% to 100%)
201 - A5-10-10 (Temp. and Humidity Sensor and Set Point)
202 - A5-10-12 (Temp. and Humidity Sensor, Set Point and Occupancy Control)
203 - 10 Bit Temp. Sensors are not supported (A5-02-20, A5-02-30)
205 For the following EEPs the scales must be set to "0 to 250":
208 - A5-10-10 to A5-10-14
215 description: EnOceanSensorEntityDescription,
222 """Initialize the EnOcean temperature sensor device."""
223 super().
__init__(dev_id, dev_name, description)
230 """Update the internal state of the sensor."""
231 if packet.data[0] != 0xA5:
235 raw_val = packet.data[3]
236 temperature = temp_scale / temp_range * (raw_val - self.
range_fromrange_from)
243 """Representation of an EnOcean humidity sensor device.
245 EEPs (EnOcean Equipment Profiles):
246 - A5-04-01 (Temp. and Humidity Sensor, Range 0°C to +40°C and 0% to 100%)
247 - A5-04-02 (Temp. and Humidity Sensor, Range -20°C to +60°C and 0% to 100%)
248 - A5-10-10 to A5-10-14 (Room Operating Panels)
252 """Update the internal state of the sensor."""
253 if packet.rorg != 0xA5:
255 humidity = packet.data[2] * 100 / 250
261 """Representation of an EnOcean window handle device.
263 EEPs (EnOcean Equipment Profiles):
264 - F6-10-00 (Mechanical handle / Hoppe AG)
268 """Update the internal state of the sensor."""
269 action = (packet.data[1] & 0x70) >> 4
273 if action
in (0x04, 0x06):
def value_changed(self, packet)
def value_changed(self, packet)
def value_changed(self, packet)
None __init__(self, list[int] dev_id, str dev_name, EnOceanSensorEntityDescription description)
None async_added_to_hass(self)
def value_changed(self, packet)
None __init__(self, list[int] dev_id, str dev_name, EnOceanSensorEntityDescription description, *int scale_min, int scale_max, int range_from, int range_to)
def value_changed(self, packet)
SensorExtraStoredData|None async_get_last_sensor_data(self)
None schedule_update_ha_state(self, bool force_refresh=False)
None setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)
def add_entities(account, async_add_entities, tracked)