From 6c0151eca65e558601874d697a0d4214b1429a0b Mon Sep 17 00:00:00 2001 From: Gazoodle Date: Wed, 5 Feb 2025 13:56:45 +0000 Subject: [PATCH] Support external heat sources --- README.md | 21 ++------ custom_components/gecko/const.py | 3 +- custom_components/gecko/manifest.json | 2 +- custom_components/gecko/select.py | 73 +++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 custom_components/gecko/select.py diff --git a/README.md b/README.md index 5975638..8e836f5 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ v0.1.16 - Reconnect button available after full connection, or connection failure allowing retry without having to restart HA. - Added "Spa In Use" sensor that is ON if any pumps, blowers or lights are on. + - Added support for external heat sources + - This is a big change, so I'm releasing it now while I'm still available to fix issues quickly v0.1.15 - During the tidy and delint phase, constants were imported from HA 2025 locations, so this @@ -59,6 +61,7 @@ Platform | Description `fan` | Spa pumps, fans. `light` | Spa lights `climate` | Spa water heater +`select` | External heating support ## Example screen shot @@ -80,24 +83,6 @@ If you don't have/want HACS installed, you will need to manually install the int 6. Restart Home Assistant 7. In the HA UI go to "Configuration" -> "Integrations" click "+" and search for "Gecko" -Using your HA configuration directory (folder) as a starting point you should now also have this: - -```text -custom_components/gecko/.translations/en.json -custom_components/gecko/__init__.py -custom_components/gecko/binary_sensor.py -custom_components/gecko/button.py -custom_components/gecko/climate.py -custom_components/gecko/config_flow.py -custom_components/gecko/const.py -custom_components/gecko/fan.py -custom_components/gecko/light.py -custom_components/gecko/manifest.json -custom_components/gecko/sensor.py -custom_components/gecko/spa_manager.py -custom_components/gecko/switch.py -``` - ## Using the snapshot functionality The snapshot function allows you to generate a datablock that can be used during development and testing diff --git a/custom_components/gecko/const.py b/custom_components/gecko/const.py index 04f9601..4c71806 100644 --- a/custom_components/gecko/const.py +++ b/custom_components/gecko/const.py @@ -30,7 +30,8 @@ SWITCH = "switch" CLIMATE = "climate" LIGHT = "light" -PLATFORMS = [BINARY_SENSOR, BUTTON, FAN, SENSOR, SWITCH, CLIMATE, LIGHT] +SELECT = "select" +PLATFORMS = [BINARY_SENSOR, BUTTON, FAN, SENSOR, SWITCH, CLIMATE, LIGHT, SELECT] # Option keys SHOW_PING_KEY = "show_ping" diff --git a/custom_components/gecko/manifest.json b/custom_components/gecko/manifest.json index a931544..2785213 100644 --- a/custom_components/gecko/manifest.json +++ b/custom_components/gecko/manifest.json @@ -10,7 +10,7 @@ "iot_class": "local_push", "issue_tracker": "https://github.com/gazoodle/gecko-home-assistant/issues", "requirements": [ - "geckolib==0.4.19" + "geckolib==1.0.0" ], "version": "0.1.16" } \ No newline at end of file diff --git a/custom_components/gecko/select.py b/custom_components/gecko/select.py new file mode 100644 index 0000000..115e927 --- /dev/null +++ b/custom_components/gecko/select.py @@ -0,0 +1,73 @@ +"""Switch platform for Gecko.""" # noqa: A005 + +import logging + +from geckolib import GeckoAutomationFacadeBase +from homeassistant.components.select import SelectEntity +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .entity import GeckoEntity +from .spa_manager import GeckoSpaManager + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: + """Set up select platform.""" + spaman: GeckoSpaManager = hass.data[DOMAIN][entry.entry_id] + if spaman.facade is not None: + if spaman.facade.heatpump is not None: + async_add_entities([GeckoHeatPump(spaman, entry, spaman.facade.heatpump)]) + if spaman.facade.ingrid is not None: + async_add_entities([GeckoInGrid(spaman, entry, spaman.facade.ingrid)]) + + +class GeckoSelect(GeckoEntity, SelectEntity): + """Gecko select class.""" + + def __init__( + self, + spaman: GeckoSpaManager, + entry: ConfigEntry, + select: GeckoAutomationFacadeBase, + ) -> None: + """Initialize the select.""" + super().__init__(spaman, entry, select) + _LOGGER.debug("%r loaded. Options are %s", select, select.states) + + @property + def current_option(self) -> str: + """Get the current option.""" + return self._automation_entity.state + + @property + def options(self) -> list[str]: + """Get the option list.""" + return self._automation_entity.states + + async def async_select_option(self, option: str) -> None: + """Change the selected option.""" + await self._automation_entity.async_set_state(option) + + +class GeckoHeatPump(GeckoSelect): + """Heat Pump class.""" + + @property + def icon(self) -> str: + """Get the icon for the heatpump.""" + return "mdi:heat-pump-outline" + + +class GeckoInGrid(GeckoSelect): + """InGrid class.""" + + @property + def icon(self) -> str: + """Get the icon for the heatpump.""" + return "mdi:heat-wave"