From f54de1bbb7dda9494d4a6627e55023ce58c332a3 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Mon, 13 May 2024 13:42:43 +0200 Subject: [PATCH 1/6] Add zappi phase setting select * custom_components/myenergi/select.py: * custom_components/myenergi/translations/en.json: --- custom_components/myenergi/select.py | 43 ++++++++++++------- .../myenergi/translations/en.json | 11 +++++ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/custom_components/myenergi/select.py b/custom_components/myenergi/select.py index f6c2065..40b23c5 100644 --- a/custom_components/myenergi/select.py +++ b/custom_components/myenergi/select.py @@ -11,6 +11,8 @@ LIBBI_MODE_NAMES = {0: "Stopped", 1: "Normal", 5: "Export"} +ZAPPI_PHASE_SETTING = ["1", "3", "auto"] + ATTR_BOOST_AMOUNT = "amount" ATTR_BOOST_TIME = "time" ATTR_BOOST_TARGET = "target" @@ -66,6 +68,7 @@ async def async_setup_entry(hass, entry, async_add_devices): "unlock", ) devices.append(ZappiChargeModeSelect(coordinator, device, entry)) + devices.append(ZappiPhaseSettingSelect(coordinator, device, entry)) elif device.kind == "eddi": platform.async_register_entity_service( "myenergi_eddi_boost", @@ -113,26 +116,38 @@ def options(self): return EDDI_MODES -class ZappiChargeModeSelect(MyenergiEntity, SelectEntity): +class ZappiPhaseSettingSelect(MyenergiEntity, SelectEntity): """myenergi Sensor class.""" def __init__(self, coordinator, device, config_entry): super().__init__(coordinator, device, config_entry) + self._attr_icon = "mdi:ev-station" + self._attr_unique_id = f"{self.config_entry.entry_id}-{self.device.serial_number}-phase_setting_select" + self._attr_name = f"myenergi {self.device.name} Phase Setting" + self._attr_translation_key = "phase_setting" + self._attr_options = ZAPPI_PHASE_SETTING @property - def unique_id(self): - """Return a unique ID to use for this entity.""" - return f"{self.config_entry.entry_id}-{self.device.serial_number}-charge_mode" + def current_option(self): + """Return the state of the sensor.""" + return self.device.num_phases - @property - def name(self): - """Return the name of the sensor.""" - return f"myenergi {self.device.name} Charge Mode" + async def async_select_option(self, option: str) -> None: + """Change the selected option.""" + await self.device.set_phase_setting(option) + self.async_schedule_update_ha_state() - @property - def icon(self): - """Return the icon of the select.""" - return "mdi:ev-station" + +class ZappiChargeModeSelect(MyenergiEntity, SelectEntity): + """myenergi Sensor class.""" + + def __init__(self, coordinator, device, config_entry): + super().__init__(coordinator, device, config_entry) + self._attr_icon = "mdi:ev-station" + self._attr_unique_id = f"{self.config_entry.entry_id}-{self.device.serial_number}-charge_mode" + self._attr_name = f"myenergi {self.device.name} Charge Mode" + self._attr_translation_key = "phase_setting" + self._attr_options = CHARGE_MODES[1:] @property def current_option(self): @@ -144,10 +159,6 @@ async def async_select_option(self, option: str) -> None: await self.device.set_charge_mode(option) self.async_schedule_update_ha_state() - @property - def options(self): - return CHARGE_MODES[1:] - class LibbiOperatingModeSelect(MyenergiEntity, SelectEntity): """myenergi Sensor class.""" diff --git a/custom_components/myenergi/translations/en.json b/custom_components/myenergi/translations/en.json index bdf9f85..5c2925c 100644 --- a/custom_components/myenergi/translations/en.json +++ b/custom_components/myenergi/translations/en.json @@ -26,5 +26,16 @@ } } } + }, + "entity": { + "select": { + "phase_setting": { + "state" : { + "1" : "1", + "3" : "3", + "auto" : "Automatic" + } + } + } } } From 9a6aa9946b59dc2f7a9b1660295f92e060ffb6db Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Mon, 13 May 2024 13:50:53 +0200 Subject: [PATCH 2/6] precommit fixes * custom_components/myenergi/select.py: * custom_components/myenergi/translations/en.json: --- custom_components/myenergi/select.py | 4 +++- custom_components/myenergi/translations/en.json | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/custom_components/myenergi/select.py b/custom_components/myenergi/select.py index 40b23c5..8f012bf 100644 --- a/custom_components/myenergi/select.py +++ b/custom_components/myenergi/select.py @@ -144,7 +144,9 @@ class ZappiChargeModeSelect(MyenergiEntity, SelectEntity): def __init__(self, coordinator, device, config_entry): super().__init__(coordinator, device, config_entry) self._attr_icon = "mdi:ev-station" - self._attr_unique_id = f"{self.config_entry.entry_id}-{self.device.serial_number}-charge_mode" + self._attr_unique_id = ( + f"{self.config_entry.entry_id}-{self.device.serial_number}-charge_mode" + ) self._attr_name = f"myenergi {self.device.name} Charge Mode" self._attr_translation_key = "phase_setting" self._attr_options = CHARGE_MODES[1:] diff --git a/custom_components/myenergi/translations/en.json b/custom_components/myenergi/translations/en.json index 5c2925c..cf89a05 100644 --- a/custom_components/myenergi/translations/en.json +++ b/custom_components/myenergi/translations/en.json @@ -30,10 +30,10 @@ "entity": { "select": { "phase_setting": { - "state" : { - "1" : "1", - "3" : "3", - "auto" : "Automatic" + "state": { + "1": "1", + "3": "3", + "auto": "Automatic" } } } From 13024325d3810314067f77be48c3b8598b91e1cb Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Mon, 3 Jun 2024 13:57:06 +0200 Subject: [PATCH 3/6] Test phase setting * tests/test_select.py: --- tests/test_select.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_select.py b/tests/test_select.py index c8b896c..f60ba03 100644 --- a/tests/test_select.py +++ b/tests/test_select.py @@ -10,10 +10,34 @@ from . import setup_mock_myenergi_config_entry TEST_ZAPPI_SELECT_CHARGE_MODE = "select.myenergi_test_zappi_1_charge_mode" +TEST_ZAPPI_SELECT_PHASE_SETTING = "select.myenergi_test_zappi_1_phase_setting_select" TEST_EDDI_SELECT_OP_MODE = "select.myenergi_test_eddi_1_operating_mode" async def test_zappi_select( + hass: HomeAssistant, mock_zappi_set_phase_setting: MagicMock +) -> None: + """Verify device information includes expected details.""" + + await setup_mock_myenergi_config_entry(hass) + + await hass.services.async_call( + SELECT_DOMAIN, + SERVICE_SELECT_OPTION, + { + ATTR_ENTITY_ID: TEST_ZAPPI_SELECT_PHASE_SETTING, + ATTR_OPTION: "1", + }, + blocking=False, + ) + assert mock_zappi_set_phase_setting.call_count == 0 + await hass.async_block_till_done() + assert mock_zappi_set_phase_setting.call_count == 1 + mock_zappi_set_phase_setting.assert_called_with("1") + + + +async def test_zappi_phaseselect( hass: HomeAssistant, mock_zappi_set_charge_mode: MagicMock ) -> None: """Verify device information includes expected details.""" From 89c43b2196d63521415ef69d8cdaa8f8b025aac6 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Mon, 3 Jun 2024 14:00:20 +0200 Subject: [PATCH 4/6] precommit * tests/test_select.py: --- tests/test_select.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_select.py b/tests/test_select.py index f60ba03..0f0535d 100644 --- a/tests/test_select.py +++ b/tests/test_select.py @@ -36,7 +36,6 @@ async def test_zappi_select( mock_zappi_set_phase_setting.assert_called_with("1") - async def test_zappi_phaseselect( hass: HomeAssistant, mock_zappi_set_charge_mode: MagicMock ) -> None: From 36964027d99d9c2afe9479f344399516756d31dc Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Mon, 3 Jun 2024 14:18:34 +0200 Subject: [PATCH 5/6] Fixed test * tests/conftest.py: * tests/test_select.py: --- tests/conftest.py | 6 ++++++ tests/test_select.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index e49740a..1cf20d6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -91,6 +91,12 @@ def mock_zappi_set_charge_mode(): yield charge_mode +@pytest.fixture +def mock_zappi_set_phase_setting(): + """Return a mocked Zappi object.""" + with patch("pymyenergi.client.Zappi.set_phase_setting") as phase_setting: + yield phase_setting + @pytest.fixture def mock_eddi_set_operating_mode(): """Return a mocked Eddi object.""" diff --git a/tests/test_select.py b/tests/test_select.py index 0f0535d..d12ca25 100644 --- a/tests/test_select.py +++ b/tests/test_select.py @@ -10,7 +10,7 @@ from . import setup_mock_myenergi_config_entry TEST_ZAPPI_SELECT_CHARGE_MODE = "select.myenergi_test_zappi_1_charge_mode" -TEST_ZAPPI_SELECT_PHASE_SETTING = "select.myenergi_test_zappi_1_phase_setting_select" +TEST_ZAPPI_SELECT_PHASE_SETTING = "select.myenergi_test_zappi_1_phase_setting" TEST_EDDI_SELECT_OP_MODE = "select.myenergi_test_eddi_1_operating_mode" From 28d34e381eba6a9b6d623535743483a45e22231e Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Mon, 3 Jun 2024 14:19:51 +0200 Subject: [PATCH 6/6] Precommit * tests/conftest.py: --- tests/conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/conftest.py b/tests/conftest.py index 1cf20d6..42b8c3c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -97,6 +97,7 @@ def mock_zappi_set_phase_setting(): with patch("pymyenergi.client.Zappi.set_phase_setting") as phase_setting: yield phase_setting + @pytest.fixture def mock_eddi_set_operating_mode(): """Return a mocked Eddi object."""