From 31bb31a72d7081f3cf41052b7641c5ce6fbfa189 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Wed, 10 Apr 2024 22:39:49 +0200 Subject: [PATCH 1/8] Added EEPs A5-30-01 and A5-30-03 --- README.md | 3 +- changes.md | 3 ++ custom_components/eltako/binary_sensor.py | 60 +++++++++++++++++++++-- custom_components/eltako/schema.py | 9 +++- requirements.txt | 2 +- 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 09b577b0..b016d19a 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,12 @@ Elatko devices are exemplarily mentioned. You can find [here](https://www.eltako **Supported sensor EEPs** * Binary sensor + * A5-07-01 (Occupancy sensor) + * A5-30-01, A5-30-03 (Digital Input - used for water sensor FSM60B) * F6-02-01 ([Rocker switch](https://github.com/grimmpp/home-assistant-eltako/tree/main/docs/rocker_switch/readme.md), FTS14EM) * F6-02-02 ([Rocker switch](https://github.com/grimmpp/home-assistant-eltako/tree/main/docs/rocker_switch/readme.md)) * F6-10-00 (Window handle, classic switches or contacs via FTS14EM, window and door contacts like FTKE, supported states: open, closed) * D5-00-01 ([Contact sensor](https://github.com/grimmpp/home-assistant-eltako/tree/main//docs/window_sensor_setup_FTS14EM.md), FTS14EM) incl. signal inverter - * A5-07-01 (Occupancy sensor) * Sensor * A5-04-01 (Temperature and Humidity Sensor) * A5-04-02 (Temperature and Humidity Sensor e.g.: FLGTF, FLT58, FFT60) diff --git a/changes.md b/changes.md index efb7b421..c83b752e 100644 --- a/changes.md +++ b/changes.md @@ -1,5 +1,8 @@ # Changes and Feature List +## Version 1.4.2 Added EEPs A5-30-01 and A5-30-03 +* Added EEPs for digital input with is used in water sensor (FSM60B) + ## Version 1.4.1 Support for sending arbitrary messages * Added Service for sending arbitrary EnOcean (ESP2) messages. Intended to be used in conjunction with [Home Assistant Automations](https://www.home-assistant.io/getting-started/automation/). * 🐞 Fix for TargetTemperatureSensor (EEP: A5-10-06 and A5-10-12) diff --git a/custom_components/eltako/binary_sensor.py b/custom_components/eltako/binary_sensor.py index 9dd30409..70600dbe 100644 --- a/custom_components/eltako/binary_sensor.py +++ b/custom_components/eltako/binary_sensor.py @@ -41,8 +41,31 @@ async def async_setup_entry( try: dev_conf = config_helpers.DeviceConf(entity_config, [CONF_DEVICE_CLASS, CONF_INVERT_SIGNAL]) if dev_conf.eep.eep_string in CONF_EEP_SUPPORTED_BINARY_SENSOR: - entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, - dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL))) + if dev_conf.eep == A5_30_03: + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), + description_key="0")) + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), + description_key="1")) + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), + description_key="2")) + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), + description_key="3")) + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), + description_key="wake")) + elif dev_conf.eep == A5_30_01: + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL))) + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), + description_key="low_battery")) + else: + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL))) except Exception as e: LOGGER.warning("[%s] Could not load configuration for platform_id %s", platform, platform_id) @@ -86,11 +109,12 @@ class EltakoBinarySensor(AbstractBinarySensor): - D5-00-01 """ - def __init__(self, platform: str, gateway: EnOceanGateway, dev_id: AddressExpression, dev_name:str, dev_eep: EEP, device_class: str, invert_signal: bool): + def __init__(self, platform: str, gateway: EnOceanGateway, dev_id: AddressExpression, dev_name:str, dev_eep: EEP, device_class: str, invert_signal: bool, description_key: str=None): """Initialize the Eltako binary sensor.""" - super().__init__(platform, gateway, dev_id, dev_name, dev_eep) + super().__init__(platform, gateway, dev_id, dev_name, dev_eep, description_key) self.invert_signal = invert_signal self._attr_device_class = device_class + self._channel = description_key if device_class is None or device_class == '': if dev_eep in [A5_07_01, A5_08_01]: @@ -237,6 +261,34 @@ def value_changed(self, msg: ESP2Message): if self.invert_signal: self._attr_is_on = not self._attr_is_on + elif self.dev_eep in [A5_30_01]: + + if self.description_key == "low_battery": + self._attr_is_on = decoded.low_battery + else: + self._attr_is_on = decoded._contact_closed + + if self.invert_signal: + self._attr_is_on = not self._attr_is_on + + elif self.dev_eep in [A5_30_03]: + + if self.description_key == "0": + self._attr_is_on = decoded.digital_input_0 + elif self.description_key == "1": + self._attr_is_on = decoded.digital_input_1 + elif self.description_key == "2": + self._attr_is_on = decoded.digital_input_2 + elif self.description_key == "3": + self._attr_is_on = decoded.digital_input_3 + elif self.description_key == "wake": + self._attr_is_on = decoded.status_of_wake + else: + raise Exception("[%s %s] EEP %s Unknown description key for A5-30-03", Platform.BINARY_SENSOR, str(self.dev_id), A5_30_03.eep_string) + + if self.invert_signal: + self._attr_is_on = not self._attr_is_on + else: LOGGER.warn("[%s %s] EEP %s not found for data processing.", Platform.BINARY_SENSOR, str(self.dev_id), self.dev_eep.eep_string) return diff --git a/custom_components/eltako/schema.py b/custom_components/eltako/schema.py index a41df48f..71665004 100644 --- a/custom_components/eltako/schema.py +++ b/custom_components/eltako/schema.py @@ -32,7 +32,14 @@ CONF_LANGUAGE, ) -CONF_EEP_SUPPORTED_BINARY_SENSOR = [F6_02_01.eep_string, F6_02_02.eep_string, F6_10_00.eep_string, D5_00_01.eep_string, A5_07_01.eep_string, A5_08_01.eep_string] +CONF_EEP_SUPPORTED_BINARY_SENSOR = [F6_02_01.eep_string, + F6_02_02.eep_string, + F6_10_00.eep_string, + D5_00_01.eep_string, + A5_07_01.eep_string, + A5_08_01.eep_string, + A5_30_01.eep_string, + A5_30_03.eep_string] CONF_EEP_SUPPORTED_SENSOR_ROCKER_SWITCH = [F6_02_01.eep_string, F6_02_02.eep_string] def _get_sender_schema(supported_sender_eep) -> vol.Schema: diff --git a/requirements.txt b/requirements.txt index 65173452..caad776f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ aiocoap pyserial-asyncio -eltako14bus==0.0.49 +eltako14bus==0.0.51 enocean==0.60.1 homeassistant termcolor From c97d9d5ad42eee366aa3fa3193cd27135d043ea8 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 11 Apr 2024 12:48:53 +0200 Subject: [PATCH 2/8] Added EEPs A5-30-01 and A5-30-03 --- changes.md | 8 +-- custom_components/eltako/manifest.json | 2 +- docs/service-send-message/eep-params.md | 4 +- tests/test_binary_sensor_A5_30_01.py | 60 +++++++++++++++++++ tests/test_binary_sensor_A5_30_03.py | 79 +++++++++++++++++++++++++ tests/test_binary_sensor_generic.py | 4 +- tests/test_sensor_A5_04_03.py | 2 +- 7 files changed, 150 insertions(+), 9 deletions(-) create mode 100644 tests/test_binary_sensor_A5_30_01.py create mode 100644 tests/test_binary_sensor_A5_30_03.py diff --git a/changes.md b/changes.md index c83b752e..7b18fb7c 100644 --- a/changes.md +++ b/changes.md @@ -1,12 +1,12 @@ # Changes and Feature List ## Version 1.4.2 Added EEPs A5-30-01 and A5-30-03 -* Added EEPs for digital input with is used in water sensor (FSM60B) +* Added EEPs (A5-30-01 preferred) for digital input which is used in water sensor (FSM60B) ## Version 1.4.1 Support for sending arbitrary messages * Added Service for sending arbitrary EnOcean (ESP2) messages. Intended to be used in conjunction with [Home Assistant Automations](https://www.home-assistant.io/getting-started/automation/). * 🐞 Fix for TargetTemperatureSensor (EEP: A5-10-06 and A5-10-12) -* 🐞 Fix for unknow cover positions and intermediate state + unit-tests added. +* 🐞 Fix for unknown cover positions and intermediate state + unit-tests added. * Unit-Tests added and improved for EEP A5-04-01, A5-04-02, A5-10-06, A5-10-12, A5-13-01, and F6-10-00. * EEP A5-04-03 added for Eltako FFT60 (temperature and humidity) * EEP A5-06-01 added for light sensor (currently twilight and daylight are combined in one illumination sensor/entity) @@ -20,7 +20,7 @@ * Added library for ESP3 (USB300 Support) => [esp2_gateway_adapter](https://github.com/grimmpp/esp2_gateway_adapter) * Better support for Teach-In Button -## Version 1.3.8 Fixes and Smaller Imrovements +## Version 1.3.8 Fixes and Smaller Improvements * Fixed window handle F6-10-00 in binary sensor * Added better tests for binary sensors * Fixed covers which behaved differently after introducing recovery state feature. @@ -36,7 +36,7 @@ * Trial to remove import warnings Reported Issue: https://github.com/grimmpp/home-assistant-eltako/issues/61 * 🐞 Removed entity_id bug from GatewayConnectionState 🐞 => Requires removing and adding gateway again ❗ -* Added state cache of device entities. When restarting HA entities like temperature sensors will show previouse state/value after restart. +* Added state cache of device entities. When restarting HA entities like temperature sensors will show previous state/value after restart. Reported Feature: https://github.com/grimmpp/home-assistant-eltako/issues/63 ## Version 1.3.6 Dependencies fixed for 1.3.5 diff --git a/custom_components/eltako/manifest.json b/custom_components/eltako/manifest.json index aca7540f..cc195908 100644 --- a/custom_components/eltako/manifest.json +++ b/custom_components/eltako/manifest.json @@ -9,6 +9,6 @@ "iot_class": "local_push", "issue_tracker": "https://github.com/grimmpp/home-assistant-eltako/issues", "loggers": ["eltako"], - "requirements": ["eltako14bus==0.0.49","enocean==0.60.1", "StrEnum", "esp2-gateway-adapter==0.1"], + "requirements": ["eltako14bus==0.0.51","enocean==0.60.1", "StrEnum", "esp2-gateway-adapter==0.1"], "version": "1.4.1" } diff --git a/docs/service-send-message/eep-params.md b/docs/service-send-message/eep-params.md index 7b747b11..9b42f6af 100644 --- a/docs/service-send-message/eep-params.md +++ b/docs/service-send-message/eep-params.md @@ -1,5 +1,5 @@ # Paramters for EEPs in Send Message Events -(This file was auto-generated by using [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py) in [version 0.0.49](https://pypi.org/project/eltako14bus/) from unit-test `TestSendMessageService` in file `./tests/test_send_message_service.py`). +(This file was auto-generated by using [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py) in [version 0.0.51](https://pypi.org/project/eltako14bus/) from unit-test `TestSendMessageService` in file `./tests/test_send_message_service.py`). ## Not Supported EEPs * `A5-09-0C` @@ -18,6 +18,8 @@ * `A5-12-02`: data_type, divisor, learn_button, measurement_channel, meter_reading * `A5-12-03`: data_type, divisor, learn_button, measurement_channel, meter_reading * `A5-13-01`: dawn_sensor, day_night, hemisphere, identifier, learn_button, rain_indication, sun_east, sun_south, sun_west, temperature, wind_speed +* `A5-30-01`: battery_status, contact_status, learn_button +* `A5-30-03`: digital_input_0, digital_input_1, digital_input_2, digital_input_3, learn_button, status_of_wake, temperature * `D5-00-01`: contact, learn_button * `F6-02-01`: energy_bow, rocker_first_action, rocker_second_action, second_action * `F6-02-02`: energy_bow, rocker_first_action, rocker_second_action, second_action diff --git a/tests/test_binary_sensor_A5_30_01.py b/tests/test_binary_sensor_A5_30_01.py new file mode 100644 index 00000000..1e0c0e66 --- /dev/null +++ b/tests/test_binary_sensor_A5_30_01.py @@ -0,0 +1,60 @@ +import unittest +from mocks import * +from unittest import mock +from homeassistant.helpers.entity import Entity +from homeassistant.const import Platform +from custom_components.eltako.binary_sensor import EltakoBinarySensor +from custom_components.eltako.config_helpers import * +from eltakobus import * +from eltakobus.eep import * + +from tests.test_binary_sensor_generic import TestBinarySensor + +# mock update of Home Assistant +Entity.schedule_update_ha_state = mock.Mock(return_value=None) +# EltakoBinarySensor.hass.bus.fire is mocked by class HassMock + + +class TestBinarySensor_A5_30_01(unittest.TestCase): + + def test_digital_input(self): + bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string) + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\x00\x0E') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, True) + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\xFF\x0E') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, False) + + + def test_inverted_digital_input(self): + bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string) + bs.invert_signal = True + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\x00\x0E') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, False) + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\xFF\x0E') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, True) + + + def test_battery(self): + bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string, description_key="low_battery") + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\x00\x0E') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, False) + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\FF\x92\xFF\x0E') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, True) \ No newline at end of file diff --git a/tests/test_binary_sensor_A5_30_03.py b/tests/test_binary_sensor_A5_30_03.py new file mode 100644 index 00000000..85c5b7f3 --- /dev/null +++ b/tests/test_binary_sensor_A5_30_03.py @@ -0,0 +1,79 @@ +import unittest +from mocks import * +from unittest import mock +from homeassistant.helpers.entity import Entity +from homeassistant.const import Platform +from custom_components.eltako.binary_sensor import EltakoBinarySensor +from custom_components.eltako.config_helpers import * +from eltakobus import * +from eltakobus.eep import * + +from tests.test_binary_sensor_generic import TestBinarySensor + +# mock update of Home Assistant +Entity.schedule_update_ha_state = mock.Mock(return_value=None) +# EltakoBinarySensor.hass.bus.fire is mocked by class HassMock + + +class TestBinarySensor_A5_30_03(unittest.TestCase): + + def test_digital_input(self): + + for key in ["0", "1", "2", "3", "wake"]: + bs = TestBinarySensor().create_binary_sensor(A5_30_03.eep_string, description_key=key) + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x00\x1F\x08') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, True) + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x00\x00\x08') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, False) + + + def test_inverted_digital_input(self): + + for key in ["0", "1", "2", "3", "wake"]: + bs = TestBinarySensor().create_binary_sensor(A5_30_03.eep_string, description_key=key) + bs.invert_signal = True + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x00\x1F\x08') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, False) + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x00\x00\x08') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, True) + + + def test_battery(self): + bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string, description_key="low_battery") + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\x00\x0E') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, False) + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\FF\x92\xFF\x0E') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, True) + + + def test_inverted_battery(self): + bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string, description_key="low_battery") + bs.invert_signal = True + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\x00\x0E') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, True) + + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\FF\x92\xFF\x0E') + bs.value_changed(msg) + + self.assertEqual(bs.is_on, False) \ No newline at end of file diff --git a/tests/test_binary_sensor_generic.py b/tests/test_binary_sensor_generic.py index dad4aa77..b87289ec 100644 --- a/tests/test_binary_sensor_generic.py +++ b/tests/test_binary_sensor_generic.py @@ -16,14 +16,14 @@ class TestBinarySensor(unittest.TestCase): - def create_binary_sensor(self, eep_string:str="F6-02-01", device_class = "none", invert_signal:bool=False) -> EltakoBinarySensor: + def create_binary_sensor(self, eep_string:str="F6-02-01", device_class = "none", invert_signal:bool=False, description_key:str=None) -> EltakoBinarySensor: gateway = GatewayMock(dev_id=123) dev_id = AddressExpression.parse("00-00-00-01") dev_name = "device name" dev_eep = EEP.find(eep_string) - bs = EltakoBinarySensor(Platform.BINARY_SENSOR, gateway, dev_id, dev_name, dev_eep, device_class, invert_signal) + bs = EltakoBinarySensor(Platform.BINARY_SENSOR, gateway, dev_id, dev_name, dev_eep, device_class, invert_signal, description_key) bs.hass = HassMock() self.assertEqual(bs._attr_is_on, None) diff --git a/tests/test_sensor_A5_04_03.py b/tests/test_sensor_A5_04_03.py index f3ee51d3..0abe03cd 100644 --- a/tests/test_sensor_A5_04_03.py +++ b/tests/test_sensor_A5_04_03.py @@ -15,7 +15,7 @@ class TestSensor_A5_04_02(unittest.TestCase): - msg1 = Regular4BSMessage (address=b'\xFF\xFF\x00\x80', data=b'\x99\x02\x12\x09', status=0x00) + msg1 = Regular4BSMessage(address=b'\xFF\xFF\x00\x80', data=b'\x99\x02\x12\x09', status=0x00) def create_temperature_sensor(self) -> EltakoTemperatureSensor: gateway = GatewayMock() From fbd18e9aba6f03a53bc51afa0d8da9ad1f88d2bb Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 11 Apr 2024 13:48:11 +0200 Subject: [PATCH 3/8] Added EEPs A5-30-01 and A5-30-03 --- custom_components/eltako/manifest.json | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/eltako/manifest.json b/custom_components/eltako/manifest.json index cc195908..82df3aa7 100644 --- a/custom_components/eltako/manifest.json +++ b/custom_components/eltako/manifest.json @@ -9,6 +9,6 @@ "iot_class": "local_push", "issue_tracker": "https://github.com/grimmpp/home-assistant-eltako/issues", "loggers": ["eltako"], - "requirements": ["eltako14bus==0.0.51","enocean==0.60.1", "StrEnum", "esp2-gateway-adapter==0.1"], + "requirements": ["eltako14bus==0.0.52","enocean==0.60.1", "StrEnum", "esp2-gateway-adapter==0.1"], "version": "1.4.1" } diff --git a/requirements.txt b/requirements.txt index caad776f..4c304392 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ aiocoap pyserial-asyncio -eltako14bus==0.0.51 +eltako14bus==0.0.52 enocean==0.60.1 homeassistant termcolor From b291760a4922b4396860d36133b4390f01c020c3 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 11 Apr 2024 14:13:55 +0200 Subject: [PATCH 4/8] Added EEPs A5-30-01 and A5-30-03 --- custom_components/eltako/binary_sensor.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/custom_components/eltako/binary_sensor.py b/custom_components/eltako/binary_sensor.py index 70600dbe..99578b97 100644 --- a/custom_components/eltako/binary_sensor.py +++ b/custom_components/eltako/binary_sensor.py @@ -42,7 +42,7 @@ async def async_setup_entry( dev_conf = config_helpers.DeviceConf(entity_config, [CONF_DEVICE_CLASS, CONF_INVERT_SIGNAL]) if dev_conf.eep.eep_string in CONF_EEP_SUPPORTED_BINARY_SENSOR: if dev_conf.eep == A5_30_03: - entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, "Digital Input 0", dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), description_key="0")) entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, @@ -58,9 +58,11 @@ async def async_setup_entry( dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), description_key="wake")) elif dev_conf.eep == A5_30_01: - entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + name = "Digital Input" + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL))) - entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + name = "Low Battery" + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), description_key="low_battery")) else: From 0af3c55e66dbf6292d2ee25dd8efe54f98e20b65 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 11 Apr 2024 14:22:18 +0200 Subject: [PATCH 5/8] Added EEPs A5-30-01 and A5-30-03 --- custom_components/eltako/binary_sensor.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/custom_components/eltako/binary_sensor.py b/custom_components/eltako/binary_sensor.py index 99578b97..2ce0897f 100644 --- a/custom_components/eltako/binary_sensor.py +++ b/custom_components/eltako/binary_sensor.py @@ -42,19 +42,24 @@ async def async_setup_entry( dev_conf = config_helpers.DeviceConf(entity_config, [CONF_DEVICE_CLASS, CONF_INVERT_SIGNAL]) if dev_conf.eep.eep_string in CONF_EEP_SUPPORTED_BINARY_SENSOR: if dev_conf.eep == A5_30_03: - entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, "Digital Input 0", dev_conf.eep, + name = "Digital Input 0" + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), description_key="0")) - entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + name = "Digital Input 1" + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), description_key="1")) - entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + name = "Digital Input 2" + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), description_key="2")) - entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + name = "Digital Input 3" + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), description_key="3")) - entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, + name = "Staus of Wake" + entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), description_key="wake")) elif dev_conf.eep == A5_30_01: From ddea9f16bc2742c8dbb6c449c8aac6b6c644c911 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 11 Apr 2024 14:22:50 +0200 Subject: [PATCH 6/8] Added EEPs A5-30-01 and A5-30-03 --- custom_components/eltako/binary_sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/eltako/binary_sensor.py b/custom_components/eltako/binary_sensor.py index 2ce0897f..39ea4298 100644 --- a/custom_components/eltako/binary_sensor.py +++ b/custom_components/eltako/binary_sensor.py @@ -58,7 +58,7 @@ async def async_setup_entry( entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), description_key="3")) - name = "Staus of Wake" + name = "Status of Wake" entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), description_key="wake")) From f8770612d98098486d2d6e543ccb4a4d0b9a353e Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 11 Apr 2024 14:33:33 +0200 Subject: [PATCH 7/8] Added EEPs A5-30-01 and A5-30-03 --- custom_components/eltako/binary_sensor.py | 32 +++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/custom_components/eltako/binary_sensor.py b/custom_components/eltako/binary_sensor.py index 39ea4298..9cf4e35f 100644 --- a/custom_components/eltako/binary_sensor.py +++ b/custom_components/eltako/binary_sensor.py @@ -10,7 +10,7 @@ from homeassistant.const import CONF_DEVICE_CLASS, STATE_ON, STATE_OFF from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.entity import DeviceInfo +from homeassistant.helpers.entity import DeviceInfo, EntityDescription from homeassistant.helpers.typing import ConfigType from homeassistant.helpers import entity_registry as er @@ -45,31 +45,32 @@ async def async_setup_entry( name = "Digital Input 0" entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), - description_key="0")) + EntityDescription(key="0", name=name) )) name = "Digital Input 1" entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), - description_key="1")) + EntityDescription(key="1", name=name) )) name = "Digital Input 2" entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), - description_key="2")) + EntityDescription(key="2", name=name) )) name = "Digital Input 3" entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), - description_key="3")) + EntityDescription(key="3", name=name) )) name = "Status of Wake" entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), - description_key="wake")) + EntityDescription(key="wake", name=name) )) elif dev_conf.eep == A5_30_01: name = "Digital Input" entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, - dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL))) + dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), + EntityDescription(key="0", name=name) )) name = "Low Battery" entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL), - description_key="low_battery")) + EntityDescription(key="low_battery", name=name) )) else: entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep, dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL))) @@ -116,12 +117,21 @@ class EltakoBinarySensor(AbstractBinarySensor): - D5-00-01 """ - def __init__(self, platform: str, gateway: EnOceanGateway, dev_id: AddressExpression, dev_name:str, dev_eep: EEP, device_class: str, invert_signal: bool, description_key: str=None): + def __init__(self, platform: str, gateway: EnOceanGateway, dev_id: AddressExpression, dev_name:str, dev_eep: EEP, + device_class: str, invert_signal: bool, description: EntityDescription=None): """Initialize the Eltako binary sensor.""" - super().__init__(platform, gateway, dev_id, dev_name, dev_eep, description_key) + if description: + self.entity_description = EntityDescription( + key=description.key, + name=description.name + ) + self._channel = description.key + else: + self._channel = None + + super().__init__(platform, gateway, dev_id, dev_name, dev_eep, self._channel) self.invert_signal = invert_signal self._attr_device_class = device_class - self._channel = description_key if device_class is None or device_class == '': if dev_eep in [A5_07_01, A5_08_01]: From 2bbc824e46b83b9d3b3a9595cfcbef5059e47243 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 11 Apr 2024 15:05:19 +0200 Subject: [PATCH 8/8] Added EEPs A5-30-01 and A5-30-03 --- docs/service-send-message/eep-params.md | 2 +- tests/__init__.py | 0 tests/test_binary_sensor_A5_30_01.py | 12 ++++----- tests/test_binary_sensor_A5_30_03.py | 36 +++---------------------- tests/test_binary_sensor_generic.py | 6 ++--- 5 files changed, 14 insertions(+), 42 deletions(-) create mode 100644 tests/__init__.py diff --git a/docs/service-send-message/eep-params.md b/docs/service-send-message/eep-params.md index 9b42f6af..7cda2ca2 100644 --- a/docs/service-send-message/eep-params.md +++ b/docs/service-send-message/eep-params.md @@ -1,5 +1,5 @@ # Paramters for EEPs in Send Message Events -(This file was auto-generated by using [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py) in [version 0.0.51](https://pypi.org/project/eltako14bus/) from unit-test `TestSendMessageService` in file `./tests/test_send_message_service.py`). +(This file was auto-generated by using [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py) in [version 0.0.52](https://pypi.org/project/eltako14bus/) from unit-test `TestSendMessageService` in file `./tests/test_send_message_service.py`). ## Not Supported EEPs * `A5-09-0C` diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_binary_sensor_A5_30_01.py b/tests/test_binary_sensor_A5_30_01.py index 1e0c0e66..30005e18 100644 --- a/tests/test_binary_sensor_A5_30_01.py +++ b/tests/test_binary_sensor_A5_30_01.py @@ -1,7 +1,7 @@ import unittest from mocks import * from unittest import mock -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.const import Platform from custom_components.eltako.binary_sensor import EltakoBinarySensor from custom_components.eltako.config_helpers import * @@ -18,7 +18,7 @@ class TestBinarySensor_A5_30_01(unittest.TestCase): def test_digital_input(self): - bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string) + bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string, EntityDescription(key="0", name="Digital Input") ) msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\x00\x0E') bs.value_changed(msg) @@ -32,7 +32,7 @@ def test_digital_input(self): def test_inverted_digital_input(self): - bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string) + bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string, EntityDescription(key="0", name="Digital Input") ) bs.invert_signal = True msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\x00\x0E') @@ -47,14 +47,14 @@ def test_inverted_digital_input(self): def test_battery(self): - bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string, description_key="low_battery") + bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string, EntityDescription(key="low_battery", name="Low Battery") ) - msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\x00\x0E') + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\xFF\x0E') bs.value_changed(msg) self.assertEqual(bs.is_on, False) - msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\FF\x92\xFF\x0E') + msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\FF\x92\x00\x0E') bs.value_changed(msg) self.assertEqual(bs.is_on, True) \ No newline at end of file diff --git a/tests/test_binary_sensor_A5_30_03.py b/tests/test_binary_sensor_A5_30_03.py index 85c5b7f3..e9d41dbb 100644 --- a/tests/test_binary_sensor_A5_30_03.py +++ b/tests/test_binary_sensor_A5_30_03.py @@ -1,7 +1,7 @@ import unittest from mocks import * from unittest import mock -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.const import Platform from custom_components.eltako.binary_sensor import EltakoBinarySensor from custom_components.eltako.config_helpers import * @@ -20,7 +20,7 @@ class TestBinarySensor_A5_30_03(unittest.TestCase): def test_digital_input(self): for key in ["0", "1", "2", "3", "wake"]: - bs = TestBinarySensor().create_binary_sensor(A5_30_03.eep_string, description_key=key) + bs = TestBinarySensor().create_binary_sensor(A5_30_03.eep_string, description= EntityDescription(key=key, name=key)) msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x00\x1F\x08') bs.value_changed(msg) @@ -36,7 +36,7 @@ def test_digital_input(self): def test_inverted_digital_input(self): for key in ["0", "1", "2", "3", "wake"]: - bs = TestBinarySensor().create_binary_sensor(A5_30_03.eep_string, description_key=key) + bs = TestBinarySensor().create_binary_sensor(A5_30_03.eep_string, description= EntityDescription(key=key, name=key)) bs.invert_signal = True msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x00\x1F\x08') @@ -48,32 +48,4 @@ def test_inverted_digital_input(self): bs.value_changed(msg) self.assertEqual(bs.is_on, True) - - - def test_battery(self): - bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string, description_key="low_battery") - - msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\x00\x0E') - bs.value_changed(msg) - - self.assertEqual(bs.is_on, False) - - msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\FF\x92\xFF\x0E') - bs.value_changed(msg) - - self.assertEqual(bs.is_on, True) - - - def test_inverted_battery(self): - bs = TestBinarySensor().create_binary_sensor(A5_30_01.eep_string, description_key="low_battery") - bs.invert_signal = True - - msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\00\x92\x00\x0E') - bs.value_changed(msg) - - self.assertEqual(bs.is_on, True) - - msg = Regular4BSMessage(b'\00\x00\x00\x01', 0x20, b'\FF\x92\xFF\x0E') - bs.value_changed(msg) - - self.assertEqual(bs.is_on, False) \ No newline at end of file + \ No newline at end of file diff --git a/tests/test_binary_sensor_generic.py b/tests/test_binary_sensor_generic.py index b87289ec..b4648a76 100644 --- a/tests/test_binary_sensor_generic.py +++ b/tests/test_binary_sensor_generic.py @@ -1,7 +1,7 @@ import unittest from mocks import * from unittest import mock -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.const import Platform from custom_components.eltako.binary_sensor import EltakoBinarySensor from custom_components.eltako.config_helpers import * @@ -16,14 +16,14 @@ class TestBinarySensor(unittest.TestCase): - def create_binary_sensor(self, eep_string:str="F6-02-01", device_class = "none", invert_signal:bool=False, description_key:str=None) -> EltakoBinarySensor: + def create_binary_sensor(self, eep_string:str="F6-02-01", device_class = "none", invert_signal:bool=False, description:EntityDescription=None) -> EltakoBinarySensor: gateway = GatewayMock(dev_id=123) dev_id = AddressExpression.parse("00-00-00-01") dev_name = "device name" dev_eep = EEP.find(eep_string) - bs = EltakoBinarySensor(Platform.BINARY_SENSOR, gateway, dev_id, dev_name, dev_eep, device_class, invert_signal, description_key) + bs = EltakoBinarySensor(Platform.BINARY_SENSOR, gateway, dev_id, dev_name, dev_eep, device_class, invert_signal, description) bs.hass = HassMock() self.assertEqual(bs._attr_is_on, None)