diff --git a/homeassistant/components/hive/__init__.py b/homeassistant/components/hive/__init__.py index 98d625cbb1d..6245db5ea7e 100644 --- a/homeassistant/components/hive/__init__.py +++ b/homeassistant/components/hive/__init__.py @@ -2,7 +2,7 @@ from functools import wraps import logging -from pyhiveapi import Pyhiveapi +from pyhiveapi import Hive import voluptuous as vol from homeassistant.const import ( @@ -13,12 +13,17 @@ from homeassistant.const import ( CONF_USERNAME, ) import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.discovery import load_platform -from homeassistant.helpers.dispatcher import async_dispatcher_connect, dispatcher_send +from homeassistant.helpers.discovery import async_load_platform +from homeassistant.helpers.dispatcher import ( + async_dispatcher_connect, + async_dispatcher_send, +) from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) +ATTR_AVAILABLE = "available" +ATTR_MODE = "mode" DOMAIN = "hive" DATA_HIVE = "data_hive" SERVICES = ["Heating", "HotWater", "TRV"] @@ -69,28 +74,15 @@ BOOST_HOT_WATER_SCHEMA = vol.Schema( ) -class HiveSession: - """Initiate Hive Session Class.""" - - entity_lookup = {} - core = None - heating = None - hotwater = None - light = None - sensor = None - switch = None - weather = None - attributes = None - trv = None - - -def setup(hass, config): +async def async_setup(hass, config): """Set up the Hive Component.""" - def heating_boost(service): + async def heating_boost(service): """Handle the service call.""" - node_id = HiveSession.entity_lookup.get(service.data[ATTR_ENTITY_ID]) - if not node_id: + + entity_lookup = hass.data[DOMAIN]["entity_lookup"] + hive_id = entity_lookup.get(service.data[ATTR_ENTITY_ID]) + if not hive_id: # log or raise error _LOGGER.error("Cannot boost entity id entered") return @@ -98,12 +90,13 @@ def setup(hass, config): minutes = service.data[ATTR_TIME_PERIOD] temperature = service.data[ATTR_TEMPERATURE] - session.heating.turn_boost_on(node_id, minutes, temperature) + hive.heating.turn_boost_on(hive_id, minutes, temperature) - def hot_water_boost(service): + async def hot_water_boost(service): """Handle the service call.""" - node_id = HiveSession.entity_lookup.get(service.data[ATTR_ENTITY_ID]) - if not node_id: + entity_lookup = hass.data[DOMAIN]["entity_lookup"] + hive_id = entity_lookup.get(service.data[ATTR_ENTITY_ID]) + if not hive_id: # log or raise error _LOGGER.error("Cannot boost entity id entered") return @@ -111,45 +104,41 @@ def setup(hass, config): mode = service.data[ATTR_MODE] if mode == "on": - session.hotwater.turn_boost_on(node_id, minutes) + hive.hotwater.turn_boost_on(hive_id, minutes) elif mode == "off": - session.hotwater.turn_boost_off(node_id) + hive.hotwater.turn_boost_off(hive_id) - session = HiveSession() - session.core = Pyhiveapi() + hive = Hive() - username = config[DOMAIN][CONF_USERNAME] - password = config[DOMAIN][CONF_PASSWORD] - update_interval = config[DOMAIN][CONF_SCAN_INTERVAL] + config = {} + config["username"] = config[DOMAIN][CONF_USERNAME] + config["password"] = config[DOMAIN][CONF_PASSWORD] + config["update_interval"] = config[DOMAIN][CONF_SCAN_INTERVAL] - devices = session.core.initialise_api(username, password, update_interval) + devices = await hive.session.startSession(config) if devices is None: _LOGGER.error("Hive API initialization failed") return False - session.sensor = Pyhiveapi.Sensor() - session.heating = Pyhiveapi.Heating() - session.hotwater = Pyhiveapi.Hotwater() - session.light = Pyhiveapi.Light() - session.switch = Pyhiveapi.Switch() - session.weather = Pyhiveapi.Weather() - session.attributes = Pyhiveapi.Attributes() - hass.data[DATA_HIVE] = session + hass.data[DOMAIN][DATA_HIVE] = hive + hass.data[DOMAIN]["entity_lookup"] = {} for ha_type in DEVICETYPES: devicelist = devices.get(DEVICETYPES[ha_type]) if devicelist: - load_platform(hass, ha_type, DOMAIN, devicelist, config) + hass.async_create_task( + async_load_platform(hass, ha_type, DOMAIN, devicelist, config) + ) if ha_type == "climate": - hass.services.register( + hass.services.async_register( DOMAIN, SERVICE_BOOST_HEATING, heating_boost, schema=BOOST_HEATING_SCHEMA, ) if ha_type == "water_heater": - hass.services.register( + hass.services.async_register( DOMAIN, SERVICE_BOOST_HOT_WATER, hot_water_boost, @@ -163,9 +152,9 @@ def refresh_system(func): """Force update all entities after state change.""" @wraps(func) - def wrapper(self, *args, **kwargs): - func(self, *args, **kwargs) - dispatcher_send(self.hass, DOMAIN) + async def wrapper(self, *args, **kwargs): + await func(self, *args, **kwargs) + async_dispatcher_send(self.hass, DOMAIN) return wrapper @@ -173,20 +162,18 @@ def refresh_system(func): class HiveEntity(Entity): """Initiate Hive Base Class.""" - def __init__(self, session, hive_device): + def __init__(self, hive, hive_device): """Initialize the instance.""" - self.node_id = hive_device["Hive_NodeID"] - self.node_name = hive_device["Hive_NodeName"] - self.device_type = hive_device["HA_DeviceType"] - self.node_device_type = hive_device["Hive_DeviceType"] - self.session = session + self.hive = hive + self.device = hive_device self.attributes = {} - self._unique_id = f"{self.node_id}-{self.device_type}" + self._unique_id = f'{self.device["hiveID"]}-{self.device["hiveType"]}' async def async_added_to_hass(self): """When entity is added to Home Assistant.""" self.async_on_remove( async_dispatcher_connect(self.hass, DOMAIN, self.async_write_ha_state) ) - if self.device_type in SERVICES: - self.session.entity_lookup[self.entity_id] = self.node_id + if self.device["hiveType"] in SERVICES: + entity_lookup = self.hass.data[DOMAIN]["entity_lookup"] + entity_lookup[self.entity_id] = self.device["hiveID"] diff --git a/homeassistant/components/hive/binary_sensor.py b/homeassistant/components/hive/binary_sensor.py index 120148a8f81..30e5ae049f0 100644 --- a/homeassistant/components/hive/binary_sensor.py +++ b/homeassistant/components/hive/binary_sensor.py @@ -1,28 +1,36 @@ """Support for the Hive binary sensors.""" +from datetime import timedelta + from homeassistant.components.binary_sensor import ( + DEVICE_CLASS_CONNECTIVITY, DEVICE_CLASS_MOTION, DEVICE_CLASS_OPENING, BinarySensorEntity, ) -from . import DATA_HIVE, DOMAIN, HiveEntity +from . import ATTR_AVAILABLE, ATTR_MODE, DATA_HIVE, DOMAIN, HiveEntity -DEVICETYPE_DEVICE_CLASS = { - "motionsensor": DEVICE_CLASS_MOTION, +DEVICETYPE = { "contactsensor": DEVICE_CLASS_OPENING, + "motionsensor": DEVICE_CLASS_MOTION, + "Connectivity": DEVICE_CLASS_CONNECTIVITY, } +PARALLEL_UPDATES = 0 +SCAN_INTERVAL = timedelta(seconds=15) -def setup_platform(hass, config, add_entities, discovery_info=None): - """Set up Hive sensor devices.""" +async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): + """Set up the Hive Binary Sensor.""" if discovery_info is None: return - session = hass.data.get(DATA_HIVE) - devs = [] - for dev in discovery_info: - devs.append(HiveBinarySensorEntity(session, dev)) - add_entities(devs) + hive = hass.data[DOMAIN].get(DATA_HIVE) + devices = hive.devices.get("binary_sensor") + entities = [] + if devices: + for dev in devices: + entities.append(HiveBinarySensorEntity(hive, dev)) + async_add_entities(entities, True) class HiveBinarySensorEntity(HiveEntity, BinarySensorEntity): @@ -41,24 +49,35 @@ class HiveBinarySensorEntity(HiveEntity, BinarySensorEntity): @property def device_class(self): """Return the class of this sensor.""" - return DEVICETYPE_DEVICE_CLASS.get(self.node_device_type) + return DEVICETYPE.get(self.device["hiveType"]) @property def name(self): """Return the name of the binary sensor.""" - return self.node_name + return self.device["haName"] + + @property + def available(self): + """Return if the device is available.""" + if self.device["hiveType"] != "Connectivity": + return self.device["deviceData"]["online"] + return True @property def device_state_attributes(self): """Show Device Attributes.""" - return self.attributes + return { + ATTR_AVAILABLE: self.attributes.get(ATTR_AVAILABLE), + ATTR_MODE: self.attributes.get(ATTR_MODE), + } @property def is_on(self): """Return true if the binary sensor is on.""" - return self.session.sensor.get_state(self.node_id, self.node_device_type) + return self.device["status"]["state"] - def update(self): + async def async_update(self): """Update all Node data from Hive.""" - self.session.core.update_data(self.node_id) - self.attributes = self.session.attributes.state_attributes(self.node_id) + await self.hive.session.updateData(self.device) + self.device = await self.hive.sensor.get_sensor(self.device) + self.attributes = self.device.get("attributes", {}) diff --git a/homeassistant/components/hive/climate.py b/homeassistant/components/hive/climate.py index 33c8fed4eca..f1901147f17 100644 --- a/homeassistant/components/hive/climate.py +++ b/homeassistant/components/hive/climate.py @@ -1,4 +1,6 @@ """Support for the Hive climate devices.""" +from datetime import timedelta + from homeassistant.components.climate import ClimateEntity from homeassistant.components.climate.const import ( CURRENT_HVAC_HEAT, @@ -12,9 +14,9 @@ from homeassistant.components.climate.const import ( SUPPORT_PRESET_MODE, SUPPORT_TARGET_TEMPERATURE, ) -from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS +from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT -from . import DATA_HIVE, DOMAIN, HiveEntity, refresh_system +from . import ATTR_AVAILABLE, DATA_HIVE, DOMAIN, HiveEntity, refresh_system HIVE_TO_HASS_STATE = { "SCHEDULE": HVAC_MODE_AUTO, @@ -34,21 +36,27 @@ HIVE_TO_HASS_HVAC_ACTION = { True: CURRENT_HVAC_HEAT, } +TEMP_UNIT = {"C": TEMP_CELSIUS, "F": TEMP_FAHRENHEIT} + SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE SUPPORT_HVAC = [HVAC_MODE_AUTO, HVAC_MODE_HEAT, HVAC_MODE_OFF] SUPPORT_PRESET = [PRESET_NONE, PRESET_BOOST] +PARALLEL_UPDATES = 0 +SCAN_INTERVAL = timedelta(seconds=15) -def setup_platform(hass, config, add_entities, discovery_info=None): - """Set up Hive climate devices.""" +async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): + """Set up the Hive thermostat.""" if discovery_info is None: return - session = hass.data.get(DATA_HIVE) - devs = [] - for dev in discovery_info: - devs.append(HiveClimateEntity(session, dev)) - add_entities(devs) + hive = hass.data[DOMAIN].get(DATA_HIVE) + devices = hive.devices.get("climate") + entities = [] + if devices: + for dev in devices: + entities.append(HiveClimateEntity(hive, dev)) + async_add_entities(entities, True) class HiveClimateEntity(HiveEntity, ClimateEntity): @@ -57,7 +65,8 @@ class HiveClimateEntity(HiveEntity, ClimateEntity): def __init__(self, hive_session, hive_device): """Initialize the Climate device.""" super().__init__(hive_session, hive_device) - self.thermostat_node_id = hive_device["Thermostat_NodeID"] + self.thermostat_node_id = hive_device["device_id"] + self.temperature_type = TEMP_UNIT.get(hive_device["temperatureunit"]) @property def unique_id(self): @@ -77,19 +86,17 @@ class HiveClimateEntity(HiveEntity, ClimateEntity): @property def name(self): """Return the name of the Climate device.""" - friendly_name = "Heating" - if self.node_name is not None: - if self.device_type == "TRV": - friendly_name = self.node_name - else: - friendly_name = f"{self.node_name} {friendly_name}" + return self.device["haName"] - return friendly_name + @property + def available(self): + """Return if the device is available.""" + return self.device["deviceData"]["online"] @property def device_state_attributes(self): """Show Device Attributes.""" - return self.attributes + return {ATTR_AVAILABLE: self.attributes.get(ATTR_AVAILABLE)} @property def hvac_modes(self): @@ -105,47 +112,42 @@ class HiveClimateEntity(HiveEntity, ClimateEntity): Need to be one of HVAC_MODE_*. """ - return HIVE_TO_HASS_STATE[self.session.heating.get_mode(self.node_id)] + return HIVE_TO_HASS_STATE[self.device["status"]["mode"]] @property def hvac_action(self): """Return current HVAC action.""" - return HIVE_TO_HASS_HVAC_ACTION[ - self.session.heating.operational_status(self.node_id, self.device_type) - ] + return HIVE_TO_HASS_HVAC_ACTION[self.device["status"]["action"]] @property def temperature_unit(self): """Return the unit of measurement.""" - return TEMP_CELSIUS + return self.temperature_type @property def current_temperature(self): """Return the current temperature.""" - return self.session.heating.current_temperature(self.node_id) + return self.device["status"]["current_temperature"] @property def target_temperature(self): """Return the target temperature.""" - return self.session.heating.get_target_temperature(self.node_id) + return self.device["status"]["target_temperature"] @property def min_temp(self): """Return minimum temperature.""" - return self.session.heating.min_temperature(self.node_id) + return self.device["min_temp"] @property def max_temp(self): """Return the maximum temperature.""" - return self.session.heating.max_temperature(self.node_id) + return self.device["max_temp"] @property def preset_mode(self): """Return the current preset mode, e.g., home, away, temp.""" - if ( - self.device_type == "Heating" - and self.session.heating.get_boost(self.node_id) == "ON" - ): + if self.device["status"]["boost"] == "ON": return PRESET_BOOST return None @@ -155,31 +157,30 @@ class HiveClimateEntity(HiveEntity, ClimateEntity): return SUPPORT_PRESET @refresh_system - def set_hvac_mode(self, hvac_mode): + async def async_set_hvac_mode(self, hvac_mode): """Set new target hvac mode.""" new_mode = HASS_TO_HIVE_STATE[hvac_mode] - self.session.heating.set_mode(self.node_id, new_mode) + await self.hive.heating.set_mode(self.device, new_mode) @refresh_system - def set_temperature(self, **kwargs): + async def async_set_temperature(self, **kwargs): """Set new target temperature.""" new_temperature = kwargs.get(ATTR_TEMPERATURE) if new_temperature is not None: - self.session.heating.set_target_temperature(self.node_id, new_temperature) + await self.hive.heating.set_target_temperature(self.device, new_temperature) @refresh_system - def set_preset_mode(self, preset_mode): + async def async_set_preset_mode(self, preset_mode): """Set new preset mode.""" if preset_mode == PRESET_NONE and self.preset_mode == PRESET_BOOST: - self.session.heating.turn_boost_off(self.node_id) + await self.hive.heating.turn_boost_off(self.device) elif preset_mode == PRESET_BOOST: curtemp = round(self.current_temperature * 2) / 2 temperature = curtemp + 0.5 - self.session.heating.turn_boost_on(self.node_id, 30, temperature) + await self.hive.heating.turn_boost_on(self.device, 30, temperature) - def update(self): + async def async_update(self): """Update all Node data from Hive.""" - self.session.core.update_data(self.node_id) - self.attributes = self.session.attributes.state_attributes( - self.thermostat_node_id - ) + await self.hive.session.updateData(self.device) + self.device = await self.hive.heating.get_heating(self.device) + self.attributes.update(self.device.get("attributes", {})) diff --git a/homeassistant/components/hive/light.py b/homeassistant/components/hive/light.py index 7659d43aeba..f458c27d019 100644 --- a/homeassistant/components/hive/light.py +++ b/homeassistant/components/hive/light.py @@ -1,4 +1,6 @@ -"""Support for the Hive lights.""" +"""Support for Hive light devices.""" +from datetime import timedelta + from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, @@ -10,29 +12,29 @@ from homeassistant.components.light import ( ) import homeassistant.util.color as color_util -from . import DATA_HIVE, DOMAIN, HiveEntity, refresh_system +from . import ATTR_AVAILABLE, ATTR_MODE, DATA_HIVE, DOMAIN, HiveEntity, refresh_system + +PARALLEL_UPDATES = 0 +SCAN_INTERVAL = timedelta(seconds=15) -def setup_platform(hass, config, add_entities, discovery_info=None): - """Set up Hive light devices.""" +async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): + """Set up the Hive Light.""" if discovery_info is None: return - session = hass.data.get(DATA_HIVE) - devs = [] - for dev in discovery_info: - devs.append(HiveDeviceLight(session, dev)) - add_entities(devs) + hive = hass.data[DOMAIN].get(DATA_HIVE) + devices = hive.devices.get("light") + entities = [] + if devices: + for dev in devices: + entities.append(HiveDeviceLight(hive, dev)) + async_add_entities(entities, True) class HiveDeviceLight(HiveEntity, LightEntity): """Hive Active Light Device.""" - def __init__(self, hive_session, hive_device): - """Initialize the Light device.""" - super().__init__(hive_session, hive_device) - self.light_device_type = hive_device["Hive_Light_DeviceType"] - @property def unique_id(self): """Return unique ID of entity.""" @@ -46,59 +48,56 @@ class HiveDeviceLight(HiveEntity, LightEntity): @property def name(self): """Return the display name of this light.""" - return self.node_name + return self.device["haName"] + + @property + def available(self): + """Return if the device is available.""" + return self.device["deviceData"]["online"] @property def device_state_attributes(self): """Show Device Attributes.""" - return self.attributes + return { + ATTR_AVAILABLE: self.attributes.get(ATTR_AVAILABLE), + ATTR_MODE: self.attributes.get(ATTR_MODE), + } @property def brightness(self): """Brightness of the light (an integer in the range 1-255).""" - return self.session.light.get_brightness(self.node_id) + return self.device["status"]["brightness"] @property def min_mireds(self): """Return the coldest color_temp that this light supports.""" - if ( - self.light_device_type == "tuneablelight" - or self.light_device_type == "colourtuneablelight" - ): - return self.session.light.get_min_color_temp(self.node_id) + return self.device.get("min_mireds") @property def max_mireds(self): """Return the warmest color_temp that this light supports.""" - if ( - self.light_device_type == "tuneablelight" - or self.light_device_type == "colourtuneablelight" - ): - return self.session.light.get_max_color_temp(self.node_id) + return self.device.get("max_mireds") @property def color_temp(self): """Return the CT color value in mireds.""" - if ( - self.light_device_type == "tuneablelight" - or self.light_device_type == "colourtuneablelight" - ): - return self.session.light.get_color_temp(self.node_id) + return self.device["status"].get("color_temp") @property - def hs_color(self) -> tuple: + def hs_color(self): """Return the hs color value.""" - if self.light_device_type == "colourtuneablelight": - rgb = self.session.light.get_color(self.node_id) + if self.device["status"]["mode"] == "COLOUR": + rgb = self.device["status"].get("hs_color") return color_util.color_RGB_to_hs(*rgb) + return None @property def is_on(self): """Return true if light is on.""" - return self.session.light.get_state(self.node_id) + return self.device["status"]["state"] @refresh_system - def turn_on(self, **kwargs): + async def async_turn_on(self, **kwargs): """Instruct the light to turn on.""" new_brightness = None new_color_temp = None @@ -116,35 +115,32 @@ class HiveDeviceLight(HiveEntity, LightEntity): get_new_color = kwargs.get(ATTR_HS_COLOR) hue = int(get_new_color[0]) saturation = int(get_new_color[1]) - new_color = (hue, saturation, self.brightness) + new_color = (hue, saturation, 100) - self.session.light.turn_on( - self.node_id, - self.light_device_type, - new_brightness, - new_color_temp, - new_color, + await self.hive.light.turn_on( + self.device, new_brightness, new_color_temp, new_color ) @refresh_system - def turn_off(self, **kwargs): + async def async_turn_off(self, **kwargs): """Instruct the light to turn off.""" - self.session.light.turn_off(self.node_id) + await self.hive.light.turn_off(self.device) @property def supported_features(self): """Flag supported features.""" supported_features = None - if self.light_device_type == "warmwhitelight": + if self.device["hiveType"] == "warmwhitelight": supported_features = SUPPORT_BRIGHTNESS - elif self.light_device_type == "tuneablelight": + elif self.device["hiveType"] == "tuneablelight": supported_features = SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP - elif self.light_device_type == "colourtuneablelight": + elif self.device["hiveType"] == "colourtuneablelight": supported_features = SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | SUPPORT_COLOR return supported_features - def update(self): + async def async_update(self): """Update all Node data from Hive.""" - self.session.core.update_data(self.node_id) - self.attributes = self.session.attributes.state_attributes(self.node_id) + await self.hive.session.updateData(self.device) + self.device = await self.hive.light.get_light(self.device) + self.attributes.update(self.device.get("attributes", {})) diff --git a/homeassistant/components/hive/manifest.json b/homeassistant/components/hive/manifest.json index f8fb9bc8c2a..27f235949bf 100644 --- a/homeassistant/components/hive/manifest.json +++ b/homeassistant/components/hive/manifest.json @@ -2,6 +2,11 @@ "domain": "hive", "name": "Hive", "documentation": "https://www.home-assistant.io/integrations/hive", - "requirements": ["pyhiveapi==0.2.20.2"], - "codeowners": ["@Rendili", "@KJonline"] -} + "requirements": [ + "pyhiveapi==0.3.4.4" + ], + "codeowners": [ + "@Rendili", + "@KJonline" + ] +} \ No newline at end of file diff --git a/homeassistant/components/hive/sensor.py b/homeassistant/components/hive/sensor.py index 360fb61bfbe..e828dff9b4e 100644 --- a/homeassistant/components/hive/sensor.py +++ b/homeassistant/components/hive/sensor.py @@ -1,31 +1,32 @@ -"""Support for the Hive sensors.""" -from homeassistant.const import TEMP_CELSIUS +"""Support for the Hive sesnors.""" + +from datetime import timedelta + +from homeassistant.components.sensor import DEVICE_CLASS_BATTERY from homeassistant.helpers.entity import Entity -from . import DATA_HIVE, DOMAIN, HiveEntity +from . import ATTR_AVAILABLE, DATA_HIVE, DOMAIN, HiveEntity -FRIENDLY_NAMES = { - "Hub_OnlineStatus": "Hive Hub Status", - "Hive_OutsideTemperature": "Outside Temperature", -} - -DEVICETYPE_ICONS = { - "Hub_OnlineStatus": "mdi:switch", - "Hive_OutsideTemperature": "mdi:thermometer", +PARALLEL_UPDATES = 0 +SCAN_INTERVAL = timedelta(seconds=15) +DEVICETYPE = { + "Battery": {"unit": " % ", "type": DEVICE_CLASS_BATTERY}, } -def setup_platform(hass, config, add_entities, discovery_info=None): - """Set up Hive sensor devices.""" +async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): + """Set up the Hive Sensor.""" if discovery_info is None: return - session = hass.data.get(DATA_HIVE) - devs = [] - for dev in discovery_info: - if dev["HA_DeviceType"] in FRIENDLY_NAMES: - devs.append(HiveSensorEntity(session, dev)) - add_entities(devs) + hive = hass.data[DOMAIN].get(DATA_HIVE) + devices = hive.devices.get("sensor") + entities = [] + if devices: + for dev in devices: + if dev["hiveType"] in DEVICETYPE: + entities.append(HiveSensorEntity(hive, dev)) + async_add_entities(entities, True) class HiveSensorEntity(HiveEntity, Entity): @@ -42,29 +43,36 @@ class HiveSensorEntity(HiveEntity, Entity): return {"identifiers": {(DOMAIN, self.unique_id)}, "name": self.name} @property - def name(self): - """Return the name of the sensor.""" - return FRIENDLY_NAMES.get(self.device_type) + def available(self): + """Return if sensor is available.""" + return self.device.get("deviceData", {}).get("online") @property - def state(self): - """Return the state of the sensor.""" - if self.device_type == "Hub_OnlineStatus": - return self.session.sensor.hub_online_status(self.node_id) - if self.device_type == "Hive_OutsideTemperature": - return self.session.weather.temperature() + def device_class(self): + """Device class of the entity.""" + return DEVICETYPE[self.device["hiveType"]].get("type") @property def unit_of_measurement(self): """Return the unit of measurement.""" - if self.device_type == "Hive_OutsideTemperature": - return TEMP_CELSIUS + return DEVICETYPE[self.device["hiveType"]].get("unit") @property - def icon(self): - """Return the icon to use.""" - return DEVICETYPE_ICONS.get(self.device_type) + def name(self): + """Return the name of the sensor.""" + return self.device["haName"] - def update(self): + @property + def state(self): + """Return the state of the sensor.""" + return self.device["status"]["state"] + + @property + def device_state_attributes(self): + """Return the state attributes.""" + return {ATTR_AVAILABLE: self.attributes.get(ATTR_AVAILABLE)} + + async def async_update(self): """Update all Node data from Hive.""" - self.session.core.update_data(self.node_id) + await self.hive.session.updateData(self.device) + self.device = await self.hive.sensor.get_sensor(self.device) diff --git a/homeassistant/components/hive/switch.py b/homeassistant/components/hive/switch.py index 734581b0db3..8ab820589cf 100644 --- a/homeassistant/components/hive/switch.py +++ b/homeassistant/components/hive/switch.py @@ -1,19 +1,26 @@ """Support for the Hive switches.""" +from datetime import timedelta + from homeassistant.components.switch import SwitchEntity -from . import DATA_HIVE, DOMAIN, HiveEntity, refresh_system +from . import ATTR_AVAILABLE, ATTR_MODE, DATA_HIVE, DOMAIN, HiveEntity, refresh_system + +PARALLEL_UPDATES = 0 +SCAN_INTERVAL = timedelta(seconds=15) -def setup_platform(hass, config, add_entities, discovery_info=None): - """Set up Hive switches.""" +async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): + """Set up the Hive Switch.""" if discovery_info is None: return - session = hass.data.get(DATA_HIVE) - devs = [] - for dev in discovery_info: - devs.append(HiveDevicePlug(session, dev)) - add_entities(devs) + hive = hass.data[DOMAIN].get(DATA_HIVE) + devices = hive.devices.get("switch") + entities = [] + if devices: + for dev in devices: + entities.append(HiveDevicePlug(hive, dev)) + async_add_entities(entities, True) class HiveDevicePlug(HiveEntity, SwitchEntity): @@ -32,34 +39,44 @@ class HiveDevicePlug(HiveEntity, SwitchEntity): @property def name(self): """Return the name of this Switch device if any.""" - return self.node_name + return self.device["haName"] + + @property + def available(self): + """Return if the device is available.""" + return self.device["deviceData"].get("online") @property def device_state_attributes(self): """Show Device Attributes.""" - return self.attributes + return { + ATTR_AVAILABLE: self.attributes.get(ATTR_AVAILABLE), + ATTR_MODE: self.attributes.get(ATTR_MODE), + } @property def current_power_w(self): """Return the current power usage in W.""" - return self.session.switch.get_power_usage(self.node_id) + return self.device["status"]["power_usage"] @property def is_on(self): """Return true if switch is on.""" - return self.session.switch.get_state(self.node_id) + return self.device["status"]["state"] @refresh_system - def turn_on(self, **kwargs): + async def async_turn_on(self, **kwargs): """Turn the switch on.""" - self.session.switch.turn_on(self.node_id) + if self.device["hiveType"] == "activeplug": + await self.hive.switch.turn_on(self.device) @refresh_system - def turn_off(self, **kwargs): + async def async_turn_off(self, **kwargs): """Turn the device off.""" - self.session.switch.turn_off(self.node_id) + if self.device["hiveType"] == "activeplug": + await self.hive.switch.turn_off(self.device) - def update(self): + async def async_update(self): """Update all Node data from Hive.""" - self.session.core.update_data(self.node_id) - self.attributes = self.session.attributes.state_attributes(self.node_id) + await self.hive.session.updateData(self.device) + self.device = await self.hive.switch.get_plug(self.device) diff --git a/homeassistant/components/hive/water_heater.py b/homeassistant/components/hive/water_heater.py index 693fd6f322b..56e98a690b8 100644 --- a/homeassistant/components/hive/water_heater.py +++ b/homeassistant/components/hive/water_heater.py @@ -1,4 +1,7 @@ """Support for hive water heaters.""" + +from datetime import timedelta + from homeassistant.components.water_heater import ( STATE_ECO, STATE_OFF, @@ -11,22 +14,36 @@ from homeassistant.const import TEMP_CELSIUS from . import DATA_HIVE, DOMAIN, HiveEntity, refresh_system SUPPORT_FLAGS_HEATER = SUPPORT_OPERATION_MODE +HOTWATER_NAME = "Hot Water" +PARALLEL_UPDATES = 0 +SCAN_INTERVAL = timedelta(seconds=15) +HIVE_TO_HASS_STATE = { + "SCHEDULE": STATE_ECO, + "ON": STATE_ON, + "OFF": STATE_OFF, +} + +HASS_TO_HIVE_STATE = { + STATE_ECO: "SCHEDULE", + STATE_ON: "MANUAL", + STATE_OFF: "OFF", +} -HIVE_TO_HASS_STATE = {"SCHEDULE": STATE_ECO, "ON": STATE_ON, "OFF": STATE_OFF} -HASS_TO_HIVE_STATE = {STATE_ECO: "SCHEDULE", STATE_ON: "ON", STATE_OFF: "OFF"} SUPPORT_WATER_HEATER = [STATE_ECO, STATE_ON, STATE_OFF] -def setup_platform(hass, config, add_entities, discovery_info=None): - """Set up the Hive water heater devices.""" +async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): + """Set up the Hive Hotwater.""" if discovery_info is None: return - session = hass.data.get(DATA_HIVE) - devs = [] - for dev in discovery_info: - devs.append(HiveWaterHeater(session, dev)) - add_entities(devs) + hive = hass.data[DOMAIN].get(DATA_HIVE) + devices = hive.devices.get("water_heater") + entities = [] + if devices: + for dev in devices: + entities.append(HiveWaterHeater(hive, dev)) + async_add_entities(entities, True) class HiveWaterHeater(HiveEntity, WaterHeaterEntity): @@ -50,9 +67,12 @@ class HiveWaterHeater(HiveEntity, WaterHeaterEntity): @property def name(self): """Return the name of the water heater.""" - if self.node_name is None: - self.node_name = "Hot Water" - return self.node_name + return HOTWATER_NAME + + @property + def available(self): + """Return if the device is available.""" + return self.device["deviceData"]["online"] @property def temperature_unit(self): @@ -62,7 +82,7 @@ class HiveWaterHeater(HiveEntity, WaterHeaterEntity): @property def current_operation(self): """Return current operation.""" - return HIVE_TO_HASS_STATE[self.session.hotwater.get_mode(self.node_id)] + return HIVE_TO_HASS_STATE[self.device["status"]["current_operation"]] @property def operation_list(self): @@ -70,11 +90,22 @@ class HiveWaterHeater(HiveEntity, WaterHeaterEntity): return SUPPORT_WATER_HEATER @refresh_system - def set_operation_mode(self, operation_mode): + async def async_turn_on(self, **kwargs): + """Turn on hotwater.""" + await self.hive.hotwater.set_mode(self.device, "MANUAL") + + @refresh_system + async def async_turn_off(self, **kwargs): + """Turn on hotwater.""" + await self.hive.hotwater.set_mode(self.device, "OFF") + + @refresh_system + async def async_set_operation_mode(self, operation_mode): """Set operation mode.""" new_mode = HASS_TO_HIVE_STATE[operation_mode] - self.session.hotwater.set_mode(self.node_id, new_mode) + await self.hive.hotwater.set_mode(self.device, new_mode) - def update(self): + async def async_update(self): """Update all Node data from Hive.""" - self.session.core.update_data(self.node_id) + await self.hive.session.updateData(self.device) + self.device = await self.hive.hotwater.get_hotwater(self.device) diff --git a/requirements_all.txt b/requirements_all.txt index 608887a8bde..63c8b98f73d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1434,7 +1434,7 @@ pyheos==0.7.2 pyhik==0.2.8 # homeassistant.components.hive -pyhiveapi==0.2.20.2 +pyhiveapi==0.3.4.4 # homeassistant.components.homematic pyhomematic==0.1.71