diff --git a/homeassistant/components/geniushub/__init__.py b/homeassistant/components/geniushub/__init__.py index b34c46a9f26..977656149c5 100644 --- a/homeassistant/components/geniushub/__init__.py +++ b/homeassistant/components/geniushub/__init__.py @@ -93,7 +93,7 @@ async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool: async_track_time_interval(hass, broker.async_update, SCAN_INTERVAL) - for platform in ["climate", "water_heater", "sensor", "binary_sensor"]: + for platform in ["climate", "water_heater", "sensor", "binary_sensor", "switch"]: hass.async_create_task(async_load_platform(hass, platform, DOMAIN, {}, config)) return True @@ -215,8 +215,6 @@ class GeniusZone(GeniusEntity): self._zone = zone self._unique_id = f"{broker.hub_uid}_zone_{zone.id}" - self._max_temp = self._min_temp = self._supported_features = None - @property def name(self) -> str: """Return the name of the climate device.""" @@ -228,6 +226,16 @@ class GeniusZone(GeniusEntity): status = {k: v for k, v in self._zone.data.items() if k in GH_ZONE_ATTRS} return {"status": status} + +class GeniusHeatingZone(GeniusZone): + """Base for Genius Heating Zones.""" + + def __init__(self, broker, zone) -> None: + """Initialize the Zone.""" + super().__init__(broker, zone) + + self._max_temp = self._min_temp = self._supported_features = None + @property def current_temperature(self) -> Optional[float]: """Return the current temperature.""" diff --git a/homeassistant/components/geniushub/climate.py b/homeassistant/components/geniushub/climate.py index 9a19edd9f8b..2221b8706c8 100644 --- a/homeassistant/components/geniushub/climate.py +++ b/homeassistant/components/geniushub/climate.py @@ -15,7 +15,7 @@ from homeassistant.components.climate.const import ( ) from homeassistant.helpers.typing import ConfigType, HomeAssistantType -from . import DOMAIN, GeniusZone +from . import DOMAIN, GeniusHeatingZone # GeniusHub Zones support: Off, Timer, Override/Boost, Footprint & Linked modes HA_HVAC_TO_GH = {HVAC_MODE_OFF: "off", HVAC_MODE_HEAT: "timer"} @@ -45,7 +45,7 @@ async def async_setup_platform( ) -class GeniusClimateZone(GeniusZone, ClimateDevice): +class GeniusClimateZone(GeniusHeatingZone, ClimateDevice): """Representation of a Genius Hub climate device.""" def __init__(self, broker, zone) -> None: diff --git a/homeassistant/components/geniushub/manifest.json b/homeassistant/components/geniushub/manifest.json index f9e8e6eb4f0..6aa0d792c77 100644 --- a/homeassistant/components/geniushub/manifest.json +++ b/homeassistant/components/geniushub/manifest.json @@ -3,7 +3,7 @@ "name": "Genius Hub", "documentation": "https://www.home-assistant.io/integrations/geniushub", "requirements": [ - "geniushub-client==0.6.28" + "geniushub-client==0.6.30" ], "dependencies": [], "codeowners": ["@zxdavb"] diff --git a/homeassistant/components/geniushub/switch.py b/homeassistant/components/geniushub/switch.py new file mode 100644 index 00000000000..79d14417dd4 --- /dev/null +++ b/homeassistant/components/geniushub/switch.py @@ -0,0 +1,55 @@ +"""Support for Genius Hub switch/outlet devices.""" +from homeassistant.components.switch import SwitchDevice, DEVICE_CLASS_OUTLET +from homeassistant.helpers.typing import ConfigType, HomeAssistantType + +from . import DOMAIN, GeniusZone + +ATTR_DURATION = "duration" + +GH_ON_OFF_ZONE = "on / off" + + +async def async_setup_platform( + hass: HomeAssistantType, config: ConfigType, async_add_entities, discovery_info=None +) -> None: + """Set up the Genius Hub switch entities.""" + if discovery_info is None: + return + + broker = hass.data[DOMAIN]["broker"] + + async_add_entities( + [ + GeniusSwitch(broker, z) + for z in broker.client.zone_objs + if z.data["type"] == GH_ON_OFF_ZONE + ] + ) + + +class GeniusSwitch(GeniusZone, SwitchDevice): + """Representation of a Genius Hub switch.""" + + @property + def device_class(self): + """Return the class of this device, from component DEVICE_CLASSES.""" + return DEVICE_CLASS_OUTLET + + @property + def is_on(self) -> bool: + """Return the current state of the on/off zone. + + The zone is considered 'on' if & only if it is override/on (e.g. timer/on is 'off'). + """ + return self._zone.data["mode"] == "override" and self._zone.data["setpoint"] + + async def async_turn_off(self, **kwargs) -> None: + """Send the zone to Timer mode. + + The zone is deemed 'off' in this mode, although the plugs may actually be on. + """ + await self._zone.set_mode("timer") + + async def async_turn_on(self, **kwargs) -> None: + """Set the zone to override/on ({'setpoint': true}) for x seconds.""" + await self._zone.set_override(1, kwargs.get(ATTR_DURATION, 3600)) diff --git a/homeassistant/components/geniushub/water_heater.py b/homeassistant/components/geniushub/water_heater.py index 4141e9f8c04..e7e3278eaf6 100644 --- a/homeassistant/components/geniushub/water_heater.py +++ b/homeassistant/components/geniushub/water_heater.py @@ -9,7 +9,7 @@ from homeassistant.components.water_heater import ( from homeassistant.const import STATE_OFF from homeassistant.helpers.typing import ConfigType, HomeAssistantType -from . import DOMAIN, GeniusZone +from . import DOMAIN, GeniusHeatingZone STATE_AUTO = "auto" STATE_MANUAL = "manual" @@ -49,7 +49,7 @@ async def async_setup_platform( ) -class GeniusWaterHeater(GeniusZone, WaterHeaterDevice): +class GeniusWaterHeater(GeniusHeatingZone, WaterHeaterDevice): """Representation of a Genius Hub water_heater device.""" def __init__(self, broker, zone) -> None: diff --git a/requirements_all.txt b/requirements_all.txt index b831ec7af89..64cc58eeb23 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -540,7 +540,7 @@ gearbest_parser==1.0.7 geizhals==0.0.9 # homeassistant.components.geniushub -geniushub-client==0.6.28 +geniushub-client==0.6.30 # homeassistant.components.geo_json_events # homeassistant.components.nsw_rural_fire_service_feed