mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 12:47:08 +00:00
Bump geniushub client (#26084)
* bump geniushub client * delint * remove unsused lint hints
This commit is contained in:
parent
97d3f49bb8
commit
33c35a6c3c
@ -1,17 +1,23 @@
|
||||
"""Support for a Genius Hub system."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import Awaitable
|
||||
|
||||
import aiohttp
|
||||
import voluptuous as vol
|
||||
|
||||
from geniushubclient import GeniusHubClient
|
||||
from geniushubclient import GeniusHub
|
||||
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_TOKEN, CONF_USERNAME
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.discovery import async_load_platform
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.helpers.dispatcher import (
|
||||
async_dispatcher_send,
|
||||
async_dispatcher_connect,
|
||||
)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.event import async_track_time_interval
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -45,7 +51,7 @@ async def async_setup(hass, hass_config):
|
||||
broker = GeniusBroker(hass, args, kwargs)
|
||||
|
||||
try:
|
||||
await broker._client.hub.update() # pylint: disable=protected-access
|
||||
await broker.client.update()
|
||||
except aiohttp.ClientResponseError as err:
|
||||
_LOGGER.error("Setup failed, check your configuration, %s", err)
|
||||
return False
|
||||
@ -58,7 +64,7 @@ async def async_setup(hass, hass_config):
|
||||
async_load_platform(hass, platform, DOMAIN, {}, hass_config)
|
||||
)
|
||||
|
||||
if broker._client.api_version == 3: # pylint: disable=protected-access
|
||||
if broker.client.api_version == 3: # pylint: disable=no-member
|
||||
for platform in ["sensor", "binary_sensor"]:
|
||||
hass.async_create_task(
|
||||
async_load_platform(hass, platform, DOMAIN, {}, hass_config)
|
||||
@ -72,27 +78,53 @@ class GeniusBroker:
|
||||
|
||||
def __init__(self, hass, args, kwargs):
|
||||
"""Initialize the geniushub client."""
|
||||
self._hass = hass
|
||||
self._client = hass.data[DOMAIN]["client"] = GeniusHubClient(
|
||||
self.hass = hass
|
||||
self.client = hass.data[DOMAIN]["client"] = GeniusHub(
|
||||
*args, **kwargs, session=async_get_clientsession(hass)
|
||||
)
|
||||
|
||||
async def async_update(self, now, **kwargs):
|
||||
"""Update the geniushub client's data."""
|
||||
try:
|
||||
await self._client.hub.update()
|
||||
await self.client.update()
|
||||
except aiohttp.ClientResponseError as err:
|
||||
_LOGGER.warning("Update failed, %s", err)
|
||||
return
|
||||
self.make_debug_log_entries()
|
||||
|
||||
async_dispatcher_send(self._hass, DOMAIN)
|
||||
async_dispatcher_send(self.hass, DOMAIN)
|
||||
|
||||
def make_debug_log_entries(self):
|
||||
"""Make any useful debug log entries."""
|
||||
# pylint: disable=protected-access
|
||||
_LOGGER.debug(
|
||||
"Raw JSON: \n\nhub._raw_zones = %s \n\nhub._raw_devices = %s",
|
||||
self._client.hub._raw_zones,
|
||||
self._client.hub._raw_devices,
|
||||
"Raw JSON: \n\nclient._zones = %s \n\nclient._devices = %s",
|
||||
self.client._zones,
|
||||
self.client._devices,
|
||||
)
|
||||
|
||||
|
||||
class GeniusEntity(Entity):
|
||||
"""Base for all Genius Hub endtities."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the entity."""
|
||||
self._name = None
|
||||
|
||||
async def async_added_to_hass(self) -> Awaitable[None]:
|
||||
"""Set up a listener when this entity is added to HA."""
|
||||
async_dispatcher_connect(self.hass, DOMAIN, self._refresh)
|
||||
|
||||
@callback
|
||||
def _refresh(self) -> None:
|
||||
self.async_schedule_update_ha_state(force_refresh=True)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Return the name of the geniushub entity."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def should_poll(self) -> bool:
|
||||
"""Return False as geniushub entities should not be polled."""
|
||||
return False
|
||||
|
@ -1,10 +1,10 @@
|
||||
"""Support for Genius Hub binary_sensor devices."""
|
||||
from typing import Any, Dict
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.util.dt import utc_from_timestamp
|
||||
|
||||
from . import DOMAIN
|
||||
from . import DOMAIN, GeniusEntity
|
||||
|
||||
GH_IS_SWITCH = ["Dual Channel Receiver", "Electric Switch", "Smart Plug"]
|
||||
|
||||
@ -14,58 +14,38 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
||||
client = hass.data[DOMAIN]["client"]
|
||||
|
||||
switches = [
|
||||
GeniusBinarySensor(client, d)
|
||||
for d in client.hub.device_objs
|
||||
if d.type[:21] in GH_IS_SWITCH
|
||||
GeniusBinarySensor(d) for d in client.device_objs if d.type[:21] in GH_IS_SWITCH
|
||||
]
|
||||
|
||||
async_add_entities(switches)
|
||||
|
||||
|
||||
class GeniusBinarySensor(BinarySensorDevice):
|
||||
class GeniusBinarySensor(GeniusEntity, BinarySensorDevice):
|
||||
"""Representation of a Genius Hub binary_sensor."""
|
||||
|
||||
def __init__(self, client, device):
|
||||
def __init__(self, device) -> None:
|
||||
"""Initialize the binary sensor."""
|
||||
self._client = client
|
||||
self._device = device
|
||||
super().__init__()
|
||||
|
||||
self._device = device
|
||||
if device.type[:21] == "Dual Channel Receiver":
|
||||
self._name = "Dual Channel Receiver {}".format(device.id)
|
||||
else:
|
||||
self._name = "{} {}".format(device.type, device.id)
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Set up a listener when this entity is added to HA."""
|
||||
async_dispatcher_connect(self.hass, DOMAIN, self._refresh)
|
||||
|
||||
@callback
|
||||
def _refresh(self):
|
||||
self.async_schedule_update_ha_state(force_refresh=True)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def should_poll(self) -> bool:
|
||||
"""Return False as the geniushub devices should not be polled."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
def is_on(self) -> bool:
|
||||
"""Return the status of the sensor."""
|
||||
return self._device.data["state"]["outputOnOff"]
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
def device_state_attributes(self) -> Dict[str, Any]:
|
||||
"""Return the device state attributes."""
|
||||
attrs = {}
|
||||
attrs["assigned_zone"] = self._device.data["assignedZones"][0]["name"]
|
||||
|
||||
# noqa; pylint: disable=protected-access
|
||||
last_comms = self._device._raw_data["childValues"]["lastComms"]["val"]
|
||||
# pylint: disable=protected-access
|
||||
last_comms = self._device._raw["childValues"]["lastComms"]["val"]
|
||||
if last_comms != 0:
|
||||
attrs["last_comms"] = utc_from_timestamp(last_comms).isoformat()
|
||||
|
||||
|
@ -11,10 +11,8 @@ from homeassistant.components.climate.const import (
|
||||
SUPPORT_PRESET_MODE,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
from . import DOMAIN
|
||||
from . import DOMAIN, GeniusEntity
|
||||
|
||||
ATTR_DURATION = "duration"
|
||||
|
||||
@ -38,32 +36,24 @@ async def async_setup_platform(
|
||||
client = hass.data[DOMAIN]["client"]
|
||||
|
||||
entities = [
|
||||
GeniusClimateZone(client, z) for z in client.hub.zone_objs if z.type in GH_ZONES
|
||||
GeniusClimateZone(z) for z in client.zone_objs if z.data["type"] in GH_ZONES
|
||||
]
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class GeniusClimateZone(ClimateDevice):
|
||||
class GeniusClimateZone(GeniusEntity, ClimateDevice):
|
||||
"""Representation of a Genius Hub climate device."""
|
||||
|
||||
def __init__(self, client, zone):
|
||||
def __init__(self, zone) -> None:
|
||||
"""Initialize the climate device."""
|
||||
self._client = client
|
||||
self._zone = zone
|
||||
super().__init__()
|
||||
|
||||
self._zone = zone
|
||||
if hasattr(self._zone, "occupied"): # has a movement sensor
|
||||
self._preset_modes = list(HA_PRESET_TO_GH)
|
||||
else:
|
||||
self._preset_modes = [PRESET_BOOST]
|
||||
|
||||
async def async_added_to_hass(self) -> Awaitable[None]:
|
||||
"""Run when entity about to be added."""
|
||||
async_dispatcher_connect(self.hass, DOMAIN, self._refresh)
|
||||
|
||||
@callback
|
||||
def _refresh(self) -> None:
|
||||
self.async_schedule_update_ha_state(force_refresh=True)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Return the name of the climate device."""
|
||||
@ -75,11 +65,6 @@ class GeniusClimateZone(ClimateDevice):
|
||||
tmp = self._zone.data.items()
|
||||
return {"status": {k: v for k, v in tmp if k in GH_STATE_ATTRS}}
|
||||
|
||||
@property
|
||||
def should_poll(self) -> bool:
|
||||
"""Return False as the geniushub devices should not be polled."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def icon(self) -> str:
|
||||
"""Return the icon to use in the frontend UI."""
|
||||
@ -91,7 +76,7 @@ class GeniusClimateZone(ClimateDevice):
|
||||
return self._zone.data["temperature"]
|
||||
|
||||
@property
|
||||
def target_temperature(self) -> Optional[float]:
|
||||
def target_temperature(self) -> float:
|
||||
"""Return the temperature we try to reach."""
|
||||
return self._zone.data["setpoint"]
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
"name": "Genius Hub",
|
||||
"documentation": "https://www.home-assistant.io/components/geniushub",
|
||||
"requirements": [
|
||||
"geniushub-client==0.5.8"
|
||||
"geniushub-client==0.6.5"
|
||||
],
|
||||
"dependencies": [],
|
||||
"codeowners": ["@zxdavb"]
|
||||
|
@ -1,13 +1,11 @@
|
||||
"""Support for Genius Hub sensor devices."""
|
||||
from datetime import timedelta
|
||||
from typing import Any, Awaitable, Dict
|
||||
|
||||
from homeassistant.const import DEVICE_CLASS_BATTERY
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util.dt import utc_from_timestamp, utcnow
|
||||
|
||||
from . import DOMAIN
|
||||
from . import DOMAIN, GeniusEntity
|
||||
|
||||
GH_HAS_BATTERY = ["Room Thermostat", "Genius Valve", "Room Sensor", "Radiator Valve"]
|
||||
|
||||
@ -22,44 +20,27 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
||||
"""Set up the Genius Hub sensor entities."""
|
||||
client = hass.data[DOMAIN]["client"]
|
||||
|
||||
sensors = [
|
||||
GeniusBattery(client, d)
|
||||
for d in client.hub.device_objs
|
||||
if d.type in GH_HAS_BATTERY
|
||||
]
|
||||
sensors = [GeniusBattery(d) for d in client.device_objs if d.type in GH_HAS_BATTERY]
|
||||
issues = [GeniusIssue(client, i) for i in list(GH_LEVEL_MAPPING)]
|
||||
|
||||
async_add_entities(sensors + issues, update_before_add=True)
|
||||
|
||||
|
||||
class GeniusBattery(Entity):
|
||||
class GeniusBattery(GeniusEntity):
|
||||
"""Representation of a Genius Hub sensor."""
|
||||
|
||||
def __init__(self, client, device):
|
||||
def __init__(self, device) -> None:
|
||||
"""Initialize the sensor."""
|
||||
self._client = client
|
||||
self._device = device
|
||||
super().__init__()
|
||||
|
||||
self._device = device
|
||||
self._name = "{} {}".format(device.type, device.id)
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Set up a listener when this entity is added to HA."""
|
||||
async_dispatcher_connect(self.hass, DOMAIN, self._refresh)
|
||||
|
||||
@callback
|
||||
def _refresh(self):
|
||||
self.async_schedule_update_ha_state(force_refresh=True)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
def icon(self) -> str:
|
||||
"""Return the icon of the sensor."""
|
||||
# noqa; pylint: disable=protected-access
|
||||
values = self._device._raw_data["childValues"]
|
||||
|
||||
values = self._device._raw["childValues"] # pylint: disable=protected-access
|
||||
|
||||
last_comms = utc_from_timestamp(values["lastComms"]["val"])
|
||||
if "WakeUp_Interval" in values:
|
||||
@ -83,78 +64,57 @@ class GeniusBattery(Entity):
|
||||
return icon
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
def device_class(self) -> str:
|
||||
"""Return the device class of the sensor."""
|
||||
return DEVICE_CLASS_BATTERY
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def unit_of_measurement(self) -> str:
|
||||
"""Return the unit of measurement of the sensor."""
|
||||
return "%"
|
||||
|
||||
@property
|
||||
def should_poll(self) -> bool:
|
||||
"""Return False as the geniushub devices should not be polled."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def state(self) -> str:
|
||||
"""Return the state of the sensor."""
|
||||
level = self._device.data["state"].get("batteryLevel", 255)
|
||||
return level if level != 255 else 0
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
def device_state_attributes(self) -> Dict[str, Any]:
|
||||
"""Return the device state attributes."""
|
||||
attrs = {}
|
||||
attrs["assigned_zone"] = self._device.data["assignedZones"][0]["name"]
|
||||
|
||||
# noqa; pylint: disable=protected-access
|
||||
last_comms = self._device._raw_data["childValues"]["lastComms"]["val"]
|
||||
# pylint: disable=protected-access
|
||||
last_comms = self._device._raw["childValues"]["lastComms"]["val"]
|
||||
attrs["last_comms"] = utc_from_timestamp(last_comms).isoformat()
|
||||
|
||||
return {**attrs}
|
||||
|
||||
|
||||
class GeniusIssue(Entity):
|
||||
class GeniusIssue(GeniusEntity):
|
||||
"""Representation of a Genius Hub sensor."""
|
||||
|
||||
def __init__(self, client, level):
|
||||
def __init__(self, hub, level) -> None:
|
||||
"""Initialize the sensor."""
|
||||
self._hub = client.hub
|
||||
super().__init__()
|
||||
|
||||
self._hub = hub
|
||||
self._name = GH_LEVEL_MAPPING[level]
|
||||
self._level = level
|
||||
self._issues = []
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Set up a listener when this entity is added to HA."""
|
||||
async_dispatcher_connect(self.hass, DOMAIN, self._refresh)
|
||||
|
||||
@callback
|
||||
def _refresh(self):
|
||||
self.async_schedule_update_ha_state(force_refresh=True)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def should_poll(self) -> bool:
|
||||
"""Return False as the geniushub devices should not be polled."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def state(self) -> str:
|
||||
"""Return the number of issues."""
|
||||
return len(self._issues)
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
def device_state_attributes(self) -> Dict[str, Any]:
|
||||
"""Return the device state attributes."""
|
||||
return {"{}_list".format(self._level): self._issues}
|
||||
|
||||
async def async_update(self):
|
||||
async def async_update(self) -> Awaitable[None]:
|
||||
"""Process the sensor's state data."""
|
||||
self._issues = [
|
||||
i["description"] for i in self._hub.issues if i["level"] == self._level
|
||||
|
@ -1,14 +1,14 @@
|
||||
"""Support for Genius Hub water_heater devices."""
|
||||
from typing import Any, Awaitable, Dict, Optional, List
|
||||
|
||||
from homeassistant.components.water_heater import (
|
||||
WaterHeaterDevice,
|
||||
SUPPORT_TARGET_TEMPERATURE,
|
||||
SUPPORT_OPERATION_MODE,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF, TEMP_CELSIUS
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
from . import DOMAIN
|
||||
from . import DOMAIN, GeniusEntity
|
||||
|
||||
STATE_AUTO = "auto"
|
||||
STATE_MANUAL = "manual"
|
||||
@ -44,93 +44,81 @@ async def async_setup_platform(
|
||||
client = hass.data[DOMAIN]["client"]
|
||||
|
||||
entities = [
|
||||
GeniusWaterHeater(client, z)
|
||||
for z in client.hub.zone_objs
|
||||
if z.type in GH_HEATERS
|
||||
GeniusWaterHeater(z) for z in client.zone_objs if z.data["type"] in GH_HEATERS
|
||||
]
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class GeniusWaterHeater(WaterHeaterDevice):
|
||||
class GeniusWaterHeater(GeniusEntity, WaterHeaterDevice):
|
||||
"""Representation of a Genius Hub water_heater device."""
|
||||
|
||||
def __init__(self, client, boiler):
|
||||
def __init__(self, boiler) -> None:
|
||||
"""Initialize the water_heater device."""
|
||||
self._client = client
|
||||
self._boiler = boiler
|
||||
super().__init__()
|
||||
|
||||
self._boiler = boiler
|
||||
self._operation_list = list(HA_OPMODE_TO_GH)
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Run when entity about to be added."""
|
||||
async_dispatcher_connect(self.hass, DOMAIN, self._refresh)
|
||||
|
||||
@callback
|
||||
def _refresh(self):
|
||||
self.async_schedule_update_ha_state(force_refresh=True)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
def name(self) -> str:
|
||||
"""Return the name of the water_heater device."""
|
||||
return self._boiler.name
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
def device_state_attributes(self) -> Dict[str, Any]:
|
||||
"""Return the device state attributes."""
|
||||
tmp = self._boiler.data.items()
|
||||
return {"status": {k: v for k, v in tmp if k in GH_STATE_ATTRS}}
|
||||
return {
|
||||
"status": {
|
||||
k: v for k, v in self._boiler.data.items() if k in GH_STATE_ATTRS
|
||||
}
|
||||
}
|
||||
|
||||
@property
|
||||
def should_poll(self) -> bool:
|
||||
"""Return False as the geniushub devices should not be polled."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def current_temperature(self):
|
||||
def current_temperature(self) -> Optional[float]:
|
||||
"""Return the current temperature."""
|
||||
return self._boiler.data.get("temperature")
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
def target_temperature(self) -> float:
|
||||
"""Return the temperature we try to reach."""
|
||||
return self._boiler.data["setpoint"]
|
||||
|
||||
@property
|
||||
def min_temp(self):
|
||||
def min_temp(self) -> float:
|
||||
"""Return max valid temperature that can be set."""
|
||||
return GH_MIN_TEMP
|
||||
|
||||
@property
|
||||
def max_temp(self):
|
||||
def max_temp(self) -> float:
|
||||
"""Return max valid temperature that can be set."""
|
||||
return GH_MAX_TEMP
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
def temperature_unit(self) -> str:
|
||||
"""Return the unit of measurement."""
|
||||
return TEMP_CELSIUS
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
def supported_features(self) -> int:
|
||||
"""Return the list of supported features."""
|
||||
return GH_SUPPORT_FLAGS
|
||||
|
||||
@property
|
||||
def operation_list(self):
|
||||
def operation_list(self) -> List[str]:
|
||||
"""Return the list of available operation modes."""
|
||||
return self._operation_list
|
||||
|
||||
@property
|
||||
def current_operation(self):
|
||||
def current_operation(self) -> str:
|
||||
"""Return the current operation mode."""
|
||||
return GH_STATE_TO_HA[self._boiler.data["mode"]]
|
||||
|
||||
async def async_set_operation_mode(self, operation_mode):
|
||||
async def async_set_operation_mode(self, operation_mode) -> Awaitable[None]:
|
||||
"""Set a new operation mode for this boiler."""
|
||||
await self._boiler.set_mode(HA_OPMODE_TO_GH[operation_mode])
|
||||
|
||||
async def async_set_temperature(self, **kwargs):
|
||||
async def async_set_temperature(self, **kwargs) -> Awaitable[None]:
|
||||
"""Set a new target temperature for this boiler."""
|
||||
temperature = kwargs[ATTR_TEMPERATURE]
|
||||
await self._boiler.set_override(temperature, 3600) # 1 hour
|
||||
|
@ -518,7 +518,7 @@ gearbest_parser==1.0.7
|
||||
geizhals==0.0.9
|
||||
|
||||
# homeassistant.components.geniushub
|
||||
geniushub-client==0.5.8
|
||||
geniushub-client==0.6.5
|
||||
|
||||
# homeassistant.components.geo_json_events
|
||||
# homeassistant.components.nsw_rural_fire_service_feed
|
||||
|
Loading…
x
Reference in New Issue
Block a user