139 lines
3.8 KiB
Python
139 lines
3.8 KiB
Python
"""
|
|
Platform for the Daikin AC.
|
|
|
|
For more details about this component, please refer to the documentation
|
|
https://home-assistant.io/components/daikin/
|
|
"""
|
|
import logging
|
|
from datetime import timedelta
|
|
from socket import timeout
|
|
|
|
import voluptuous as vol
|
|
|
|
import homeassistant.helpers.config_validation as cv
|
|
from homeassistant.components.discovery import SERVICE_DAIKIN
|
|
from homeassistant.const import (
|
|
CONF_HOSTS, CONF_ICON, CONF_MONITORED_CONDITIONS, CONF_NAME, CONF_TYPE
|
|
)
|
|
from homeassistant.helpers import discovery
|
|
from homeassistant.helpers.discovery import load_platform
|
|
from homeassistant.util import Throttle
|
|
|
|
REQUIREMENTS = ['pydaikin==0.4']
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
DOMAIN = 'daikin'
|
|
HTTP_RESOURCES = ['aircon/get_sensor_info', 'aircon/get_control_info']
|
|
|
|
ATTR_TARGET_TEMPERATURE = 'target_temperature'
|
|
ATTR_INSIDE_TEMPERATURE = 'inside_temperature'
|
|
ATTR_OUTSIDE_TEMPERATURE = 'outside_temperature'
|
|
|
|
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60)
|
|
|
|
COMPONENT_TYPES = ['climate', 'sensor']
|
|
|
|
SENSOR_TYPE_TEMPERATURE = 'temperature'
|
|
|
|
SENSOR_TYPES = {
|
|
ATTR_INSIDE_TEMPERATURE: {
|
|
CONF_NAME: 'Inside Temperature',
|
|
CONF_ICON: 'mdi:thermometer',
|
|
CONF_TYPE: SENSOR_TYPE_TEMPERATURE
|
|
},
|
|
ATTR_OUTSIDE_TEMPERATURE: {
|
|
CONF_NAME: 'Outside Temperature',
|
|
CONF_ICON: 'mdi:thermometer',
|
|
CONF_TYPE: SENSOR_TYPE_TEMPERATURE
|
|
}
|
|
|
|
}
|
|
|
|
CONFIG_SCHEMA = vol.Schema({
|
|
DOMAIN: vol.Schema({
|
|
vol.Optional(
|
|
CONF_HOSTS, default=[]
|
|
): vol.All(cv.ensure_list, [cv.string]),
|
|
vol.Optional(
|
|
CONF_MONITORED_CONDITIONS,
|
|
default=list(SENSOR_TYPES.keys())
|
|
): vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)])
|
|
})
|
|
}, extra=vol.ALLOW_EXTRA)
|
|
|
|
|
|
def setup(hass, config):
|
|
"""Establish connection with Daikin."""
|
|
def discovery_dispatch(service, discovery_info):
|
|
"""Dispatcher for Daikin discovery events."""
|
|
host = discovery_info.get('ip')
|
|
|
|
if daikin_api_setup(hass, host) is None:
|
|
return
|
|
|
|
for component in COMPONENT_TYPES:
|
|
load_platform(hass, component, DOMAIN, discovery_info,
|
|
config)
|
|
|
|
discovery.listen(hass, SERVICE_DAIKIN, discovery_dispatch)
|
|
|
|
for host in config.get(DOMAIN, {}).get(CONF_HOSTS, []):
|
|
if daikin_api_setup(hass, host) is None:
|
|
continue
|
|
|
|
discovery_info = {
|
|
'ip': host,
|
|
CONF_MONITORED_CONDITIONS:
|
|
config[DOMAIN][CONF_MONITORED_CONDITIONS]
|
|
}
|
|
load_platform(hass, 'sensor', DOMAIN, discovery_info, config)
|
|
|
|
return True
|
|
|
|
|
|
def daikin_api_setup(hass, host, name=None):
|
|
"""Create a Daikin instance only once."""
|
|
if DOMAIN not in hass.data:
|
|
hass.data[DOMAIN] = {}
|
|
|
|
api = hass.data[DOMAIN].get(host)
|
|
if api is None:
|
|
from pydaikin import appliance
|
|
|
|
try:
|
|
device = appliance.Appliance(host)
|
|
except timeout:
|
|
_LOGGER.error("Connection to Daikin could not be established")
|
|
return False
|
|
|
|
if name is None:
|
|
name = device.values['name']
|
|
|
|
api = DaikinApi(device, name)
|
|
|
|
return api
|
|
|
|
|
|
class DaikinApi(object):
|
|
"""Keep the Daikin instance in one place and centralize the update."""
|
|
|
|
def __init__(self, device, name):
|
|
"""Initialize the Daikin Handle."""
|
|
self.device = device
|
|
self.name = name
|
|
self.ip_address = device.ip
|
|
|
|
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
|
def update(self, **kwargs):
|
|
"""Pull the latest data from Daikin."""
|
|
try:
|
|
for resource in HTTP_RESOURCES:
|
|
self.device.values.update(
|
|
self.device.get_resource(resource)
|
|
)
|
|
except timeout:
|
|
_LOGGER.warning(
|
|
"Connection failed for %s", self.ip_address
|
|
)
|