When I go to Settings → Devices & Services → Entities I see an EnOcean switch, but there are no events fired when I press one of the buttons on the switch.
However, the logs show “received radio packet” and the device ID including the packet data: 2022-11-22 09:11:36.619 DEBUG (Thread-2) [homeassistant.components.enocean.dongle] Received radio packet: 00:12:9B:A8->FF:FF:FF:FF (-73 dBm): 0x01 ['0xf6', '0x10', '0x0', '0x12', '0x9b', '0xa8', '0x30'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x49', '0x0'] OrderedDict()
Why is the received packet not correctly shown as a button press in HA?
Thank you!
Hello i have the same problem
i would like to have it in dashboard
is it possible to modify sensor.py to authorize the decode of wall switch
this is this file in the plugin enocean
so we can write something like this
"""Support for EnOcean sensors."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from enocean.utils import combine_hex
import voluptuous as vol
from homeassistant.components.sensor import (
PLATFORM_SCHEMA,
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import (
CONF_DEVICE_CLASS,
CONF_ID,
CONF_NAME,
PERCENTAGE,
STATE_CLOSED,
STATE_OPEN,
UnitOfPower,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from .device import EnOceanEntity
CONF_MAX_TEMP = "max_temp"
CONF_MIN_TEMP = "min_temp"
CONF_RANGE_FROM = "range_from"
CONF_RANGE_TO = "range_to"
DEFAULT_NAME = "EnOcean sensor"
SENSOR_TYPE_HUMIDITY = "humidity"
SENSOR_TYPE_POWER = "powersensor"
SENSOR_TYPE_TEMPERATURE = "temperature"
SENSOR_TYPE_WINDOWHANDLE = "windowhandle"
SENSOR_TYPE_WINDOWHANDLE = "wallswitch"
@dataclass
class EnOceanSensorEntityDescriptionMixin:
"""Mixin for required keys."""
unique_id: Callable[[list[int]], str | None]
@dataclass
class EnOceanSensorEntityDescription(
SensorEntityDescription, EnOceanSensorEntityDescriptionMixin
):
"""Describes EnOcean sensor entity."""
SENSOR_DESC_TEMPERATURE = EnOceanSensorEntityDescription(
key=SENSOR_TYPE_TEMPERATURE,
name="Temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:thermometer",
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
unique_id=lambda dev_id: f"{combine_hex(dev_id)}-{SENSOR_TYPE_TEMPERATURE}",
)
SENSOR_DESC_HUMIDITY = EnOceanSensorEntityDescription(
key=SENSOR_TYPE_HUMIDITY,
name="Humidity",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:water-percent",
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
unique_id=lambda dev_id: f"{combine_hex(dev_id)}-{SENSOR_TYPE_HUMIDITY}",
)
SENSOR_DESC_POWER = EnOceanSensorEntityDescription(
key=SENSOR_TYPE_POWER,
name="Power",
native_unit_of_measurement=UnitOfPower.WATT,
icon="mdi:power-plug",
device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT,
unique_id=lambda dev_id: f"{combine_hex(dev_id)}-{SENSOR_TYPE_POWER}",
)
SENSOR_DESC_WINDOWHANDLE = EnOceanSensorEntityDescription(
key=SENSOR_TYPE_WINDOWHANDLE,
name="WindowHandle",
icon="mdi:window-open-variant",
unique_id=lambda dev_id: f"{combine_hex(dev_id)}-{SENSOR_TYPE_WINDOWHANDLE}",
)
SENSOR_DESC_WALLSWITCH = EnOceanSensorEntityDescription(
key=SENSOR_TYPE_WALLSWITCH,
name="WallSwitch",
icon="mdi:remote-tv",
unique_id=lambda dev_id: f"{combine_hex(dev_id)}-{SENSOR_TYPE_WALLSWITCH}",
)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_ID): vol.All(cv.ensure_list, [vol.Coerce(int)]),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_DEVICE_CLASS, default=SENSOR_TYPE_POWER): cv.string,
vol.Optional(CONF_MAX_TEMP, default=40): vol.Coerce(int),
vol.Optional(CONF_MIN_TEMP, default=0): vol.Coerce(int),
vol.Optional(CONF_RANGE_FROM, default=255): cv.positive_int,
vol.Optional(CONF_RANGE_TO, default=0): cv.positive_int,
}
)
def setup_platform(
hass: HomeAssistant,
config: ConfigType,
add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Set up an EnOcean sensor device."""
dev_id = config[CONF_ID]
dev_name = config[CONF_NAME]
sensor_type = config[CONF_DEVICE_CLASS]
entities: list[EnOceanSensor] = []
if sensor_type == SENSOR_TYPE_TEMPERATURE:
temp_min = config[CONF_MIN_TEMP]
temp_max = config[CONF_MAX_TEMP]
range_from = config[CONF_RANGE_FROM]
range_to = config[CONF_RANGE_TO]
entities = [
EnOceanTemperatureSensor(
dev_id,
dev_name,
SENSOR_DESC_TEMPERATURE,
scale_min=temp_min,
scale_max=temp_max,
range_from=range_from,
range_to=range_to,
)
]
elif sensor_type == SENSOR_TYPE_HUMIDITY:
entities = [EnOceanHumiditySensor(dev_id, dev_name, SENSOR_DESC_HUMIDITY)]
elif sensor_type == SENSOR_TYPE_POWER:
entities = [EnOceanPowerSensor(dev_id, dev_name, SENSOR_DESC_POWER)]
elif sensor_type == SENSOR_TYPE_WINDOWHANDLE:
entities = [EnOceanWindowHandle(dev_id, dev_name, SENSOR_DESC_WINDOWHANDLE)]
elif sensor_type == SENSOR_TYPE_WALLSWITCH:
entities = [EnOceanWallSwitch(dev_id, dev_name, SENSOR_DESC_WALLSWITCH)]
add_entities(entities)
class EnOceanSensor(EnOceanEntity, RestoreEntity, SensorEntity):
"""Representation of an EnOcean sensor device such as a power meter."""
def __init__(self, dev_id, dev_name, description: EnOceanSensorEntityDescription):
"""Initialize the EnOcean sensor device."""
super().__init__(dev_id, dev_name)
self.entity_description = description
self._attr_name = f"{description.name} {dev_name}"
self._attr_unique_id = description.unique_id(dev_id)
async def async_added_to_hass(self) -> None:
"""Call when entity about to be added to hass."""
# If not None, we got an initial value.
await super().async_added_to_hass()
if self._attr_native_value is not None:
return
if (state := await self.async_get_last_state()) is not None:
self._attr_native_value = state.state
def value_changed(self, packet):
"""Update the internal state of the sensor."""
class EnOceanPowerSensor(EnOceanSensor):
"""Representation of an EnOcean power sensor.
EEPs (EnOcean Equipment Profiles):
- A5-12-01 (Automated Meter Reading, Electricity)
"""
def value_changed(self, packet):
"""Update the internal state of the sensor."""
if packet.rorg != 0xA5:
return
packet.parse_eep(0x12, 0x01)
if packet.parsed["DT"]["raw_value"] == 1:
# this packet reports the current value
raw_val = packet.parsed["MR"]["raw_value"]
divisor = packet.parsed["DIV"]["raw_value"]
self._attr_native_value = raw_val / (10**divisor)
self.schedule_update_ha_state()
class EnOceanTemperatureSensor(EnOceanSensor):
"""Representation of an EnOcean temperature sensor device.
EEPs (EnOcean Equipment Profiles):
- A5-02-01 to A5-02-1B All 8 Bit Temperature Sensors of A5-02
- A5-10-01 to A5-10-14 (Room Operating Panels)
- A5-04-01 (Temp. and Humidity Sensor, Range 0°C to +40°C and 0% to 100%)
- A5-04-02 (Temp. and Humidity Sensor, Range -20°C to +60°C and 0% to 100%)
- A5-10-10 (Temp. and Humidity Sensor and Set Point)
- A5-10-12 (Temp. and Humidity Sensor, Set Point and Occupancy Control)
- 10 Bit Temp. Sensors are not supported (A5-02-20, A5-02-30)
For the following EEPs the scales must be set to "0 to 250":
- A5-04-01
- A5-04-02
- A5-10-10 to A5-10-14
"""
def __init__(
self,
dev_id,
dev_name,
description: EnOceanSensorEntityDescription,
*,
scale_min,
scale_max,
range_from,
range_to,
):
"""Initialize the EnOcean temperature sensor device."""
super().__init__(dev_id, dev_name, description)
self._scale_min = scale_min
self._scale_max = scale_max
self.range_from = range_from
self.range_to = range_to
def value_changed(self, packet):
"""Update the internal state of the sensor."""
if packet.data[0] != 0xA5:
return
temp_scale = self._scale_max - self._scale_min
temp_range = self.range_to - self.range_from
raw_val = packet.data[3]
temperature = temp_scale / temp_range * (raw_val - self.range_from)
temperature += self._scale_min
self._attr_native_value = round(temperature, 1)
self.schedule_update_ha_state()
class EnOceanHumiditySensor(EnOceanSensor):
"""Representation of an EnOcean humidity sensor device.
EEPs (EnOcean Equipment Profiles):
- A5-04-01 (Temp. and Humidity Sensor, Range 0°C to +40°C and 0% to 100%)
- A5-04-02 (Temp. and Humidity Sensor, Range -20°C to +60°C and 0% to 100%)
- A5-10-10 to A5-10-14 (Room Operating Panels)
"""
def value_changed(self, packet):
"""Update the internal state of the sensor."""
if packet.rorg != 0xA5:
return
humidity = packet.data[2] * 100 / 250
self._attr_native_value = round(humidity, 1)
self.schedule_update_ha_state()
class EnOceanWindowHandle(EnOceanSensor):
"""Representation of an EnOcean window handle device.
EEPs (EnOcean Equipment Profiles):
- F6-10-00 (Mechanical handle / Hoppe AG)
"""
def value_changed(self, packet):
"""Update the internal state of the sensor."""
action = (packet.data[1] & 0x70) >> 4
if action == 0x07:
self._attr_native_value = STATE_CLOSED
if action in (0x04, 0x06):
self._attr_native_value = STATE_OPEN
if action == 0x05:
self._attr_native_value = "tilt"
self.schedule_update_ha_state()
class EnOceanWallSwitch(EnOceanSensor):
"""Representation of an EnOcean wall switch.
EEPs (EnOcean Equipment Profiles):
- F6-02-00
"""
def value_changed(self, packet):
"""Update the internal state of the sensor."""
action = packet.data[1]
if action == 0xF0:
self._attr_native_value = STATE_CLOSED
if action in (0xE0, 0xC0):
self._attr_native_value = STATE_OPEN
if action == 0xD0:
self._attr_native_value = "tilt"
if action == 0x00:
self._attr_native_value = "release"
if action == 0x30:
self._attr_native_value = "BP1"
if action == 0x10:
self._attr_native_value = "BP2"
if action == 0x70:
self._attr_native_value = "BP3"
if action == 0x50:
self._attr_native_value = "BP4"
if action == 0x37:
self._attr_native_value = "BP1+3"
if action == 0x15:
self._attr_native_value = "BP2+4"
if action == 0x17:
self._attr_native_value = "BP2+3"
if action == 0x35:
self._attr_native_value = "BP1+4"
if action == 0x07:
self._attr_native_value = "shock"
self.schedule_update_ha_state()
but in don’t know how to push it inside ha to test
i have a rpi3 with the last image
Thanks iknow but i Can Do it juste with node red and my mqtt serveur, without ha, but i work for and with enocean, and i Can help the community. I started with ha juste last week, because one of or custumers, want that it’s work with this plug-in. if we CAN help eatch other…
Best regards