core/homeassistant/components/hive/__init__.py

179 lines
5.3 KiB
Python

"""Support for the Hive devices and services."""
from functools import wraps
import logging
from pyhiveapi import Hive
import voluptuous as vol
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_TEMPERATURE,
CONF_PASSWORD,
CONF_SCAN_INTERVAL,
CONF_USERNAME,
)
import homeassistant.helpers.config_validation as cv
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"
DOMAIN = "hive"
DATA_HIVE = "data_hive"
SERVICES = ["Heating", "HotWater", "TRV"]
SERVICE_BOOST_HOT_WATER = "boost_hot_water"
SERVICE_BOOST_HEATING = "boost_heating"
ATTR_TIME_PERIOD = "time_period"
ATTR_MODE = "on_off"
DEVICETYPES = {
"binary_sensor": "device_list_binary_sensor",
"climate": "device_list_climate",
"water_heater": "device_list_water_heater",
"light": "device_list_light",
"switch": "device_list_plug",
"sensor": "device_list_sensor",
}
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Optional(CONF_SCAN_INTERVAL, default=2): cv.positive_int,
}
)
},
extra=vol.ALLOW_EXTRA,
)
BOOST_HEATING_SCHEMA = vol.Schema(
{
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
vol.Required(ATTR_TIME_PERIOD): vol.All(
cv.time_period, cv.positive_timedelta, lambda td: td.total_seconds() // 60
),
vol.Optional(ATTR_TEMPERATURE, default="25.0"): vol.Coerce(float),
}
)
BOOST_HOT_WATER_SCHEMA = vol.Schema(
{
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
vol.Optional(ATTR_TIME_PERIOD, default="00:30:00"): vol.All(
cv.time_period, cv.positive_timedelta, lambda td: td.total_seconds() // 60
),
vol.Required(ATTR_MODE): cv.string,
}
)
async def async_setup(hass, config):
"""Set up the Hive Component."""
async def heating_boost(service):
"""Handle the service call."""
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
minutes = service.data[ATTR_TIME_PERIOD]
temperature = service.data[ATTR_TEMPERATURE]
hive.heating.turn_boost_on(hive_id, minutes, temperature)
async def hot_water_boost(service):
"""Handle the service call."""
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
minutes = service.data[ATTR_TIME_PERIOD]
mode = service.data[ATTR_MODE]
if mode == "on":
hive.hotwater.turn_boost_on(hive_id, minutes)
elif mode == "off":
hive.hotwater.turn_boost_off(hive_id)
hive = Hive()
config = {}
config["username"] = config[DOMAIN][CONF_USERNAME]
config["password"] = config[DOMAIN][CONF_PASSWORD]
config["update_interval"] = config[DOMAIN][CONF_SCAN_INTERVAL]
devices = await hive.session.startSession(config)
if devices is None:
_LOGGER.error("Hive API initialization failed")
return False
hass.data[DOMAIN][DATA_HIVE] = hive
hass.data[DOMAIN]["entity_lookup"] = {}
for ha_type in DEVICETYPES:
devicelist = devices.get(DEVICETYPES[ha_type])
if devicelist:
hass.async_create_task(
async_load_platform(hass, ha_type, DOMAIN, devicelist, config)
)
if ha_type == "climate":
hass.services.async_register(
DOMAIN,
SERVICE_BOOST_HEATING,
heating_boost,
schema=BOOST_HEATING_SCHEMA,
)
if ha_type == "water_heater":
hass.services.async_register(
DOMAIN,
SERVICE_BOOST_HOT_WATER,
hot_water_boost,
schema=BOOST_HOT_WATER_SCHEMA,
)
return True
def refresh_system(func):
"""Force update all entities after state change."""
@wraps(func)
async def wrapper(self, *args, **kwargs):
await func(self, *args, **kwargs)
async_dispatcher_send(self.hass, DOMAIN)
return wrapper
class HiveEntity(Entity):
"""Initiate Hive Base Class."""
def __init__(self, hive, hive_device):
"""Initialize the instance."""
self.hive = hive
self.device = hive_device
self.attributes = {}
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["hiveType"] in SERVICES:
entity_lookup = self.hass.data[DOMAIN]["entity_lookup"]
entity_lookup[self.entity_id] = self.device["hiveID"]