core/homeassistant/components/hive/__init__.py

193 lines
5.7 KiB
Python

"""Support for the Hive devices and services."""
from functools import wraps
import logging
from pyhiveapi import Pyhiveapi
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 load_platform
from homeassistant.helpers.dispatcher import async_dispatcher_connect, dispatcher_send
from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
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,
}
)
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):
"""Set up the Hive Component."""
def heating_boost(service):
"""Handle the service call."""
node_id = HiveSession.entity_lookup.get(service.data[ATTR_ENTITY_ID])
if not node_id:
# log or raise error
_LOGGER.error("Cannot boost entity id entered")
return
minutes = service.data[ATTR_TIME_PERIOD]
temperature = service.data[ATTR_TEMPERATURE]
session.heating.turn_boost_on(node_id, minutes, temperature)
def hot_water_boost(service):
"""Handle the service call."""
node_id = HiveSession.entity_lookup.get(service.data[ATTR_ENTITY_ID])
if not node_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":
session.hotwater.turn_boost_on(node_id, minutes)
elif mode == "off":
session.hotwater.turn_boost_off(node_id)
session = HiveSession()
session.core = Pyhiveapi()
username = config[DOMAIN][CONF_USERNAME]
password = config[DOMAIN][CONF_PASSWORD]
update_interval = config[DOMAIN][CONF_SCAN_INTERVAL]
devices = session.core.initialise_api(username, password, update_interval)
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
for ha_type in DEVICETYPES:
devicelist = devices.get(DEVICETYPES[ha_type])
if devicelist:
load_platform(hass, ha_type, DOMAIN, devicelist, config)
if ha_type == "climate":
hass.services.register(
DOMAIN,
SERVICE_BOOST_HEATING,
heating_boost,
schema=BOOST_HEATING_SCHEMA,
)
if ha_type == "water_heater":
hass.services.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)
def wrapper(self, *args, **kwargs):
func(self, *args, **kwargs)
dispatcher_send(self.hass, DOMAIN)
return wrapper
class HiveEntity(Entity):
"""Initiate Hive Base Class."""
def __init__(self, session, 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.attributes = {}
self._unique_id = f"{self.node_id}-{self.device_type}"
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