From b52f020fdb64fbabbc3eb72f8ce9daed54445fad Mon Sep 17 00:00:00 2001 From: Serge Arbuzov Date: Sat, 11 Nov 2023 14:30:48 +0300 Subject: [PATCH] Enable power off interval management Signed-off-by: Serge Arbuzov --- README.md | 5 ++- .../delonghi_primadonna/const.py | 30 +++++++++++-- .../delonghi_primadonna/device.py | 41 +++++++++++------- .../delonghi_primadonna/manifest.json | 2 +- .../delonghi_primadonna/select.py | 42 ++++++++++++++----- 5 files changed, 86 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 5d88157..b873a66 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ [![hacs_badge](https://img.shields.io/badge/HACS-Custom-41BDF5.svg?style=for-the-badge)](https://github.com/hacs/integration) [![License](https://img.shields.io/github/license/Arbuzov/home_assistant_delonghi_primadonna?style=for-the-badge)](https://github.com/Arbuzov/home_assistant_delonghi_primadonna/blob/master/LICENSE) [![Latest Release](https://img.shields.io/github/v/release/Arbuzov/home_assistant_delonghi_primadonna?style=for-the-badge)](https://github.com/Arbuzov/home_assistant_delonghi_primadonna/releases) + + [![Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=Arbuzov&repository=home_assistant_delonghi_primadonna&category=integration) [![Open your Home Assistant instance and start setting up a new integration.](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=home_assistant_delonghi_primadonna) @@ -62,5 +64,4 @@ Copy all files from this repository in custom_components/delonghi_primadonna to * De'Longhi ECAM 650.85.MS * De'Longhi ECAM 550.55.W * De'Longhi ECAM 650.55.MS EX:1 -* De'Longhi Eletta Explore 450.65.G -* Please add... +* Feel free to add your model... diff --git a/custom_components/delonghi_primadonna/const.py b/custom_components/delonghi_primadonna/const.py index 1f21936..28811d7 100644 --- a/custom_components/delonghi_primadonna/const.py +++ b/custom_components/delonghi_primadonna/const.py @@ -18,6 +18,14 @@ 'Guest': 4 } +POWER_OFF_OPTIONS = { + '15min': 0, + '30min': 1, + '1h': 2, + '2h': 3, + '3h': 4 +} + ENTITY_CATEGORY = { 'None': None, 'Configuration': EntityCategory.CONFIG, @@ -29,14 +37,28 @@ """ BYTES_POWER = [0x0d, 0x07, 0x84, 0x0f, 0x02, 0x01, 0x55, 0x12] -# This command change device state -BYTES_GENERAL_COMMAND = [ +# Default bitmask for commands +BASE_COMMAND = '10000001' + +# This command change device switches +BYTES_SWITCH_COMMAND = [ 0x0d, 0x0b, 0x90, 0x0f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] -# Default bitmask for commands -BASE_COMMAND = '10000001' +BYTES_AUTOPOWEROFF_COMMAND = [ + 0x0d, 0x0b, 0x90, 0x0f, 0x00, 0x3e, + 0x00, 0x00, 0x00, 0x00, 0x81, 0xe3 +] + +BYTES_WATER_HARDNESS_COMMAND = [ + 0x0d, 0x0b, 0x90, 0x0f, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +] + +# Water hardness + +# 0d 0b 90 0f 00 32 00 00 00 03 3a ab COFFE_ON = [0x0d, 0x0f, 0x83, 0xf0, 0x02, 0x01, 0x01, 0x00, 0x67, 0x02, 0x02, 0x00, 0x00, 0x06, 0x77, 0xff] diff --git a/custom_components/delonghi_primadonna/device.py b/custom_components/delonghi_primadonna/device.py index 2fe67a6..932df93 100644 --- a/custom_components/delonghi_primadonna/device.py +++ b/custom_components/delonghi_primadonna/device.py @@ -13,8 +13,9 @@ from homeassistant.helpers import device_registry as dr from .const import (AMERICANO_OFF, AMERICANO_ON, BASE_COMMAND, - BYTES_GENERAL_COMMAND, BYTES_POWER, COFFE_OFF, COFFE_ON, - COFFEE_GROUNDS_CONTAINER_DETACHED, + BYTES_AUTOPOWEROFF_COMMAND, BYTES_POWER, + BYTES_SWITCH_COMMAND, BYTES_WATER_HARDNESS_COMMAND, + COFFE_OFF, COFFE_ON, COFFEE_GROUNDS_CONTAINER_DETACHED, COFFEE_GROUNDS_CONTAINER_FULL, CONTROLL_CHARACTERISTIC, DEBUG, DEVICE_READY, DEVICE_TURNOFF, DOMAIN, DOPPIO_OFF, DOPPIO_ON, ESPRESSO2_OFF, ESPRESSO2_ON, ESPRESSO_OFF, @@ -222,19 +223,15 @@ async def _connect(self): raise error self._connecting = False - def _make_command(self): + def _make_switch_command(self): """Make hex command""" base_command = list(BASE_COMMAND) base_command[3] = '1' if self.switches.energy_save else '0' base_command[4] = '1' if self.switches.cup_light else '0' base_command[5] = '1' if self.switches.sounds else '0' - if self.notify: - _LOGGER.warning('Command bin: %s', ''.join(base_command)) - bytes_general_command = BYTES_GENERAL_COMMAND - bytes_general_command[9] = int(''.join(base_command), 2) - if self.notify: - _LOGGER.warning('Command bytes: %s', bytes_general_command) - return bytes_general_command + hex_command = BYTES_SWITCH_COMMAND + hex_command[9] = int(''.join(base_command), 2) + return hex_command async def _event_trigger(self, value): """ @@ -296,32 +293,32 @@ async def power_on(self) -> None: async def cup_light_on(self) -> None: """Turn the cup light on.""" self.switches.cup_light = True - await self.send_command(self._make_command()) + await self.send_command(self._make_switch_command()) async def cup_light_off(self) -> None: """Turn the cup light off.""" self.switches.cup_light = False - await self.send_command(self._make_command()) + await self.send_command(self._make_switch_command()) async def energy_save_on(self): """Enable energy save mode""" self.switches.energy_save = True - await self.send_command(self._make_command()) + await self.send_command(self._make_switch_command()) async def energy_save_off(self): """Enable energy save mode""" self.switches.energy_save = False - await self.send_command(self._make_command()) + await self.send_command(self._make_switch_command()) async def sound_alarm_on(self): """Enable sound alarm""" self.switches.sounds = True - await self.send_command(self._make_command()) + await self.send_command(self._make_switch_command()) async def sound_alarm_off(self): """Disable sound alarm""" self.switches.sounds = False - await self.send_command(self._make_command()) + await self.send_command(self._make_switch_command()) async def beverage_start(self, beverage: AvailableBeverage) -> None: """Start beverage""" @@ -368,6 +365,18 @@ async def select_profile(self, profile_id) -> None: message = [0x0D, 0x06, 0xA9, 0xF0, profile_id, 0xD7, 0xC0] await self.send_command(message) + async def set_auto_power_off(self, power_off_interval) -> None: + """Set auto power off time.""" + message = BYTES_AUTOPOWEROFF_COMMAND + message[9] = power_off_interval + await self.send_command(message) + + async def set_water_hardness(self, hardness_level) -> None: + """Set water hardness""" + message = BYTES_WATER_HARDNESS_COMMAND + message[9] = hardness_level + await self.send_command(message) + async def common_command(self, command: str) -> None: """Send custom BLE command""" message = [int(x, 16) for x in command.split(' ')] diff --git a/custom_components/delonghi_primadonna/manifest.json b/custom_components/delonghi_primadonna/manifest.json index adb94fc..023e6b7 100644 --- a/custom_components/delonghi_primadonna/manifest.json +++ b/custom_components/delonghi_primadonna/manifest.json @@ -19,5 +19,5 @@ "documentation": "https://github.com/Arbuzov/home_assistant_delonghi_primadonna", "iot_class": "local_polling", "issue_tracker": "https://github.com/Arbuzov/home_assistant_delonghi_primadonna/issues", - "version": "1.5.2" + "version": "1.5.3-beta" } diff --git a/custom_components/delonghi_primadonna/select.py b/custom_components/delonghi_primadonna/select.py index 16273b0..20a292a 100644 --- a/custom_components/delonghi_primadonna/select.py +++ b/custom_components/delonghi_primadonna/select.py @@ -7,7 +7,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from .const import AVAILABLE_PROFILES, DOMAIN +from .const import AVAILABLE_PROFILES, DOMAIN, POWER_OFF_OPTIONS from .device import AvailableBeverage, DelonghiDeviceEntity, DelongiPrimadonna _LOGGER = logging.getLogger(__name__) @@ -21,9 +21,10 @@ async def async_setup_entry( delongh_device: DelongiPrimadonna = hass.data[DOMAIN][entry.unique_id] async_add_entities( [ - ProfileSelect(delongh_device, hass), BeverageSelect(delongh_device, hass), EnergySaveModeSelect(delongh_device, hass), + ProfileSelect(delongh_device, hass), + WaterHardnessSelect(delongh_device, hass) ] ) return True @@ -65,14 +66,8 @@ class EnergySaveModeSelect(DelonghiDeviceEntity, SelectEntity): """Energy save mode management""" _attr_name = 'Energy Save Mode' - _attr_options = [ - '15min', - '30min', - '1h', - '2h', - '3h' - ] - _attr_current_option = '15min' + _attr_options = list(POWER_OFF_OPTIONS.keys()) + _attr_current_option = list(POWER_OFF_OPTIONS.keys())[3] @property def entity_category(self, **kwargs: Any) -> None: @@ -81,4 +76,29 @@ def entity_category(self, **kwargs: Any) -> None: async def async_select_option(self, option: str) -> None: """Select energy save mode action""" - _LOGGER.warning('Energy save mode is not implemented yet') + power_off_interval = POWER_OFF_OPTIONS.get(option) + self.hass.async_create_task( + self.device.set_auto_power_off(power_off_interval) + ) + self._attr_current_option = option + + +class WaterHardnessSelect(DelonghiDeviceEntity, SelectEntity): + """Water hardness management""" + + _attr_name = 'Water Hardness' + _attr_options = ['Soft', 'Medium', 'Hard', 'Very Hard'] + _attr_current_option = 'Soft' + + @property + def entity_category(self, **kwargs: Any) -> None: + """Return the category of the entity.""" + return EntityCategory.CONFIG + + async def async_select_option(self, option: str) -> None: + """Select water hardness action""" + water_hardness = self._attr_options.index(option) + self.hass.async_create_task( + self.device.set_water_hardness(water_hardness) + ) + self._attr_current_option = option