Skip to content

Commit

Permalink
Merge pull request #533 from jwillemsen/jwi-phaseselect
Browse files Browse the repository at this point in the history
Add zappi phase setting select
  • Loading branch information
CJNE authored Aug 18, 2024
2 parents 9c4d6ca + 28d34e3 commit c6ecd6c
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 16 deletions.
45 changes: 29 additions & 16 deletions custom_components/myenergi/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,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"
Expand Down Expand Up @@ -67,6 +69,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",
Expand Down Expand Up @@ -114,26 +117,40 @@ 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):
Expand All @@ -145,10 +162,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."""
Expand Down
11 changes: 11 additions & 0 deletions custom_components/myenergi/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,16 @@
}
}
}
},
"entity": {
"select": {
"phase_setting": {
"state": {
"1": "1",
"3": "3",
"auto": "Automatic"
}
}
}
}
}
7 changes: 7 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ 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."""
Expand Down
23 changes: 23 additions & 0 deletions tests/test_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,33 @@
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"
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."""
Expand Down

0 comments on commit c6ecd6c

Please sign in to comment.