mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Added new climate component from Daikin (#10983)
* Added Daikin climate component * Fixed tox & hound * Place up the REQUIREMENTS var * Update .coveragerc * Removed unused customization * Prevent setting invalid operation state * Fixed hound * Small refactor according to code review * Fixed latest code review comments * Used host instead of ip_address * No real change * No real change * Fixed lint errors * More pylint fixes * Shush Hound * Applied suggested changes for temperature & humidity settings * Fixed hound * Fixed upper case texts * Fixed hound * Fixed hound * Fixed hound * Removed humidity since even the device has the feature it cant be set from API * Code review requested changes * Fixed hound * Fixed hound * Trigger update after adding device * Added Daikin sensors * Fixed hound * Fixed hound * Fixed travis * Fixed hound * Fixed hound * Fixed travis * Fixed coverage decrease issue * Do less API calls and fixed Travis failures * Distributed code from platform to climate and sensor componenets * Rename sensor state to device_attribute * Fixed hound * Updated requirements * Simplified code * Implemented requested changes * Forgot one change * Don't allow customizing temperature unit and take it from hass (FOR NOW) * Additional code review changes applied * Condensed import even more * Simplify condition check * Reordered imports * Disabled autodiscovery FOR NOW :( * Give more suggestive names to sensors
This commit is contained in:
parent
2cf5acdfd2
commit
04de22613c
@ -266,6 +266,9 @@ omit =
|
|||||||
homeassistant/components/zoneminder.py
|
homeassistant/components/zoneminder.py
|
||||||
homeassistant/components/*/zoneminder.py
|
homeassistant/components/*/zoneminder.py
|
||||||
|
|
||||||
|
homeassistant/components/daikin.py
|
||||||
|
homeassistant/components/*/daikin.py
|
||||||
|
|
||||||
homeassistant/components/alarm_control_panel/alarmdotcom.py
|
homeassistant/components/alarm_control_panel/alarmdotcom.py
|
||||||
homeassistant/components/alarm_control_panel/canary.py
|
homeassistant/components/alarm_control_panel/canary.py
|
||||||
homeassistant/components/alarm_control_panel/concord232.py
|
homeassistant/components/alarm_control_panel/concord232.py
|
||||||
|
257
homeassistant/components/climate/daikin.py
Normal file
257
homeassistant/components/climate/daikin.py
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
"""
|
||||||
|
Support for the Daikin HVAC.
|
||||||
|
|
||||||
|
For more details about this platform, please refer to the documentation at
|
||||||
|
https://home-assistant.io/components/climate.daikin/
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.components.climate import (
|
||||||
|
ATTR_OPERATION_MODE, ATTR_FAN_MODE, ATTR_SWING_MODE,
|
||||||
|
ATTR_CURRENT_TEMPERATURE, ClimateDevice, PLATFORM_SCHEMA,
|
||||||
|
SUPPORT_TARGET_TEMPERATURE, SUPPORT_FAN_MODE, SUPPORT_OPERATION_MODE,
|
||||||
|
SUPPORT_SWING_MODE, STATE_OFF, STATE_AUTO, STATE_HEAT, STATE_COOL,
|
||||||
|
STATE_DRY, STATE_FAN_ONLY
|
||||||
|
)
|
||||||
|
from homeassistant.components.daikin import (
|
||||||
|
daikin_api_setup,
|
||||||
|
ATTR_TARGET_TEMPERATURE,
|
||||||
|
ATTR_INSIDE_TEMPERATURE,
|
||||||
|
ATTR_OUTSIDE_TEMPERATURE
|
||||||
|
)
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONF_HOST, CONF_NAME,
|
||||||
|
TEMP_CELSIUS,
|
||||||
|
ATTR_TEMPERATURE
|
||||||
|
)
|
||||||
|
|
||||||
|
REQUIREMENTS = ['pydaikin==0.4']
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE |
|
||||||
|
SUPPORT_FAN_MODE |
|
||||||
|
SUPPORT_OPERATION_MODE |
|
||||||
|
SUPPORT_SWING_MODE)
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
|
vol.Required(CONF_HOST): cv.string,
|
||||||
|
vol.Optional(CONF_NAME, default=None): cv.string,
|
||||||
|
})
|
||||||
|
|
||||||
|
HA_STATE_TO_DAIKIN = {
|
||||||
|
STATE_FAN_ONLY: 'fan',
|
||||||
|
STATE_DRY: 'dry',
|
||||||
|
STATE_COOL: 'cool',
|
||||||
|
STATE_HEAT: 'hot',
|
||||||
|
STATE_AUTO: 'auto',
|
||||||
|
STATE_OFF: 'off',
|
||||||
|
}
|
||||||
|
|
||||||
|
HA_ATTR_TO_DAIKIN = {
|
||||||
|
ATTR_OPERATION_MODE: 'mode',
|
||||||
|
ATTR_FAN_MODE: 'f_rate',
|
||||||
|
ATTR_SWING_MODE: 'f_dir',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
|
"""Setup the Daikin HVAC platform."""
|
||||||
|
if discovery_info is not None:
|
||||||
|
host = discovery_info.get('ip')
|
||||||
|
name = None
|
||||||
|
_LOGGER.info("Discovered a Daikin AC on %s", host)
|
||||||
|
else:
|
||||||
|
host = config.get(CONF_HOST)
|
||||||
|
name = config.get(CONF_NAME)
|
||||||
|
_LOGGER.info("Added Daikin AC on %s", host)
|
||||||
|
|
||||||
|
api = daikin_api_setup(hass, host, name)
|
||||||
|
add_devices([DaikinClimate(api)], True)
|
||||||
|
|
||||||
|
|
||||||
|
class DaikinClimate(ClimateDevice):
|
||||||
|
"""Representation of a Daikin HVAC."""
|
||||||
|
|
||||||
|
def __init__(self, api):
|
||||||
|
"""Initialize the climate device."""
|
||||||
|
from pydaikin import appliance
|
||||||
|
|
||||||
|
self._api = api
|
||||||
|
self._force_refresh = False
|
||||||
|
self._list = {
|
||||||
|
ATTR_OPERATION_MODE: list(
|
||||||
|
map(str.title, set(HA_STATE_TO_DAIKIN.values()))
|
||||||
|
),
|
||||||
|
ATTR_FAN_MODE: list(
|
||||||
|
map(
|
||||||
|
str.title,
|
||||||
|
appliance.daikin_values(HA_ATTR_TO_DAIKIN[ATTR_FAN_MODE])
|
||||||
|
)
|
||||||
|
),
|
||||||
|
ATTR_SWING_MODE: list(
|
||||||
|
map(
|
||||||
|
str.title,
|
||||||
|
appliance.daikin_values(HA_ATTR_TO_DAIKIN[ATTR_SWING_MODE])
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
def get(self, key):
|
||||||
|
"""Retrieve device settings from API library cache."""
|
||||||
|
value = None
|
||||||
|
cast_to_float = False
|
||||||
|
|
||||||
|
if key in [ATTR_TEMPERATURE, ATTR_INSIDE_TEMPERATURE,
|
||||||
|
ATTR_CURRENT_TEMPERATURE]:
|
||||||
|
value = self._api.device.values.get('htemp')
|
||||||
|
cast_to_float = True
|
||||||
|
if key == ATTR_TARGET_TEMPERATURE:
|
||||||
|
value = self._api.device.values.get('stemp')
|
||||||
|
cast_to_float = True
|
||||||
|
elif key == ATTR_OUTSIDE_TEMPERATURE:
|
||||||
|
value = self._api.device.values.get('otemp')
|
||||||
|
cast_to_float = True
|
||||||
|
elif key == ATTR_FAN_MODE:
|
||||||
|
value = self._api.device.represent('f_rate')[1].title()
|
||||||
|
elif key == ATTR_SWING_MODE:
|
||||||
|
value = self._api.device.represent('f_dir')[1].title()
|
||||||
|
elif key == ATTR_OPERATION_MODE:
|
||||||
|
# Daikin can return also internal states auto-1 or auto-7
|
||||||
|
# and we need to translate them as AUTO
|
||||||
|
value = re.sub(
|
||||||
|
'[^a-z]',
|
||||||
|
'',
|
||||||
|
self._api.device.represent('mode')[1]
|
||||||
|
).title()
|
||||||
|
|
||||||
|
if value is None:
|
||||||
|
_LOGGER.warning("Invalid value requested for key %s", key)
|
||||||
|
else:
|
||||||
|
if value == "-" or value == "--":
|
||||||
|
value = None
|
||||||
|
elif cast_to_float:
|
||||||
|
try:
|
||||||
|
value = float(value)
|
||||||
|
except ValueError:
|
||||||
|
value = None
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
def set(self, settings):
|
||||||
|
"""Set device settings using API."""
|
||||||
|
values = {}
|
||||||
|
|
||||||
|
for attr in [ATTR_TEMPERATURE, ATTR_FAN_MODE, ATTR_SWING_MODE,
|
||||||
|
ATTR_OPERATION_MODE]:
|
||||||
|
value = settings.get(attr)
|
||||||
|
if value is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
daikin_attr = HA_ATTR_TO_DAIKIN.get(attr)
|
||||||
|
if daikin_attr is not None:
|
||||||
|
if value.title() in self._list[attr]:
|
||||||
|
values[daikin_attr] = value.lower()
|
||||||
|
else:
|
||||||
|
_LOGGER.error("Invalid value %s for %s", attr, value)
|
||||||
|
|
||||||
|
# temperature
|
||||||
|
elif attr == ATTR_TEMPERATURE:
|
||||||
|
try:
|
||||||
|
values['stemp'] = str(int(value))
|
||||||
|
except ValueError:
|
||||||
|
_LOGGER.error("Invalid temperature %s", value)
|
||||||
|
|
||||||
|
if values:
|
||||||
|
self._force_refresh = True
|
||||||
|
self._api.device.set(values)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self):
|
||||||
|
"""Return the ID of this AC."""
|
||||||
|
return "{}.{}".format(self.__class__, self._api.ip_address)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self):
|
||||||
|
"""Return the list of supported features."""
|
||||||
|
return SUPPORT_FLAGS
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the name of the thermostat, if any."""
|
||||||
|
return self._api.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def temperature_unit(self):
|
||||||
|
"""Return the unit of measurement which this thermostat uses."""
|
||||||
|
return TEMP_CELSIUS
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_temperature(self):
|
||||||
|
"""Return the current temperature."""
|
||||||
|
return self.get(ATTR_CURRENT_TEMPERATURE)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature(self):
|
||||||
|
"""Return the temperature we try to reach."""
|
||||||
|
return self.get(ATTR_TARGET_TEMPERATURE)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature_step(self):
|
||||||
|
"""Return the supported step of target temperature."""
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def set_temperature(self, **kwargs):
|
||||||
|
"""Set new target temperature."""
|
||||||
|
self.set(kwargs)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_operation(self):
|
||||||
|
"""Return current operation ie. heat, cool, idle."""
|
||||||
|
return self.get(ATTR_OPERATION_MODE)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def operation_list(self):
|
||||||
|
"""Return the list of available operation modes."""
|
||||||
|
return self._list.get(ATTR_OPERATION_MODE)
|
||||||
|
|
||||||
|
def set_operation_mode(self, operation_mode):
|
||||||
|
"""Set HVAC mode."""
|
||||||
|
self.set({ATTR_OPERATION_MODE: operation_mode})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_fan_mode(self):
|
||||||
|
"""Return the fan setting."""
|
||||||
|
return self.get(ATTR_FAN_MODE)
|
||||||
|
|
||||||
|
def set_fan_mode(self, fan):
|
||||||
|
"""Set fan mode."""
|
||||||
|
self.set({ATTR_FAN_MODE: fan})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fan_list(self):
|
||||||
|
"""List of available fan modes."""
|
||||||
|
return self._list.get(ATTR_FAN_MODE)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_swing_mode(self):
|
||||||
|
"""Return the fan setting."""
|
||||||
|
return self.get(ATTR_SWING_MODE)
|
||||||
|
|
||||||
|
def set_swing_mode(self, swing_mode):
|
||||||
|
"""Set new target temperature."""
|
||||||
|
self.set({ATTR_SWING_MODE: swing_mode})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def swing_list(self):
|
||||||
|
"""List of available swing modes."""
|
||||||
|
return self._list.get(ATTR_SWING_MODE)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
"""Retrieve latest state."""
|
||||||
|
self._api.update(no_throttle=self._force_refresh)
|
||||||
|
self._force_refresh = False
|
138
homeassistant/components/daikin.py
Normal file
138
homeassistant/components/daikin.py
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
"""
|
||||||
|
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
|
||||||
|
)
|
@ -38,6 +38,7 @@ SERVICE_XIAOMI_GW = 'xiaomi_gw'
|
|||||||
SERVICE_TELLDUSLIVE = 'tellstick'
|
SERVICE_TELLDUSLIVE = 'tellstick'
|
||||||
SERVICE_HUE = 'philips_hue'
|
SERVICE_HUE = 'philips_hue'
|
||||||
SERVICE_DECONZ = 'deconz'
|
SERVICE_DECONZ = 'deconz'
|
||||||
|
SERVICE_DAIKIN = 'daikin'
|
||||||
|
|
||||||
SERVICE_HANDLERS = {
|
SERVICE_HANDLERS = {
|
||||||
SERVICE_HASS_IOS_APP: ('ios', None),
|
SERVICE_HASS_IOS_APP: ('ios', None),
|
||||||
|
124
homeassistant/components/sensor/daikin.py
Normal file
124
homeassistant/components/sensor/daikin.py
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
"""
|
||||||
|
Support for Daikin AC Sensors.
|
||||||
|
|
||||||
|
For more details about this platform, please refer to the documentation at
|
||||||
|
https://home-assistant.io/components/sensor.daikin/
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.components.daikin import (
|
||||||
|
SENSOR_TYPES, SENSOR_TYPE_TEMPERATURE,
|
||||||
|
ATTR_INSIDE_TEMPERATURE, ATTR_OUTSIDE_TEMPERATURE,
|
||||||
|
daikin_api_setup
|
||||||
|
)
|
||||||
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONF_HOST, CONF_ICON, CONF_NAME, CONF_MONITORED_CONDITIONS, CONF_TYPE
|
||||||
|
)
|
||||||
|
from homeassistant.helpers.entity import Entity
|
||||||
|
from homeassistant.util.unit_system import UnitSystem
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
|
vol.Required(CONF_HOST): cv.string,
|
||||||
|
vol.Optional(CONF_NAME, default=None): cv.string,
|
||||||
|
vol.Optional(CONF_MONITORED_CONDITIONS, default=SENSOR_TYPES.keys()):
|
||||||
|
vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
|
||||||
|
})
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
|
"""Set up the Daikin sensors."""
|
||||||
|
if discovery_info is not None:
|
||||||
|
host = discovery_info.get('ip')
|
||||||
|
name = None
|
||||||
|
monitored_conditions = discovery_info.get(
|
||||||
|
CONF_MONITORED_CONDITIONS, list(SENSOR_TYPES.keys())
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
host = config[CONF_HOST]
|
||||||
|
name = config.get(CONF_NAME)
|
||||||
|
monitored_conditions = config[CONF_MONITORED_CONDITIONS]
|
||||||
|
_LOGGER.info("Added Daikin AC sensor on %s", host)
|
||||||
|
|
||||||
|
api = daikin_api_setup(hass, host, name)
|
||||||
|
units = hass.config.units
|
||||||
|
sensors = []
|
||||||
|
for monitored_state in monitored_conditions:
|
||||||
|
sensors.append(DaikinClimateSensor(api, monitored_state, units, name))
|
||||||
|
|
||||||
|
add_devices(sensors, True)
|
||||||
|
|
||||||
|
|
||||||
|
class DaikinClimateSensor(Entity):
|
||||||
|
"""Representation of a Sensor."""
|
||||||
|
|
||||||
|
def __init__(self, api, monitored_state, units: UnitSystem, name=None):
|
||||||
|
"""Initialize the sensor."""
|
||||||
|
self._api = api
|
||||||
|
self._sensor = SENSOR_TYPES.get(monitored_state)
|
||||||
|
if name is None:
|
||||||
|
name = "{} {}".format(self._sensor[CONF_NAME], api.name)
|
||||||
|
|
||||||
|
self._name = "{} {}".format(name, monitored_state.replace("_", " "))
|
||||||
|
self._device_attribute = monitored_state
|
||||||
|
|
||||||
|
if self._sensor[CONF_TYPE] == SENSOR_TYPE_TEMPERATURE:
|
||||||
|
self._unit_of_measurement = units.temperature_unit
|
||||||
|
|
||||||
|
def get(self, key):
|
||||||
|
"""Retrieve device settings from API library cache."""
|
||||||
|
value = None
|
||||||
|
cast_to_float = False
|
||||||
|
|
||||||
|
if key == ATTR_INSIDE_TEMPERATURE:
|
||||||
|
value = self._api.device.values.get('htemp')
|
||||||
|
cast_to_float = True
|
||||||
|
elif key == ATTR_OUTSIDE_TEMPERATURE:
|
||||||
|
value = self._api.device.values.get('otemp')
|
||||||
|
|
||||||
|
if value is None:
|
||||||
|
_LOGGER.warning("Invalid value requested for key %s", key)
|
||||||
|
else:
|
||||||
|
if value == "-" or value == "--":
|
||||||
|
value = None
|
||||||
|
elif cast_to_float:
|
||||||
|
try:
|
||||||
|
value = float(value)
|
||||||
|
except ValueError:
|
||||||
|
value = None
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self):
|
||||||
|
"""Return the ID of this AC."""
|
||||||
|
return "{}.{}".format(self.__class__, self._api.ip_address)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self):
|
||||||
|
"""Icon to use in the frontend, if any."""
|
||||||
|
return self._sensor[CONF_ICON]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the name of the sensor."""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
"""Return the state of the sensor."""
|
||||||
|
return self.get(self._device_attribute)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unit_of_measurement(self):
|
||||||
|
"""Return the unit of measurement."""
|
||||||
|
return self._unit_of_measurement
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
"""Retrieve latest state."""
|
||||||
|
self._api.update()
|
@ -664,6 +664,10 @@ pycsspeechtts==1.0.2
|
|||||||
# homeassistant.components.sensor.cups
|
# homeassistant.components.sensor.cups
|
||||||
# pycups==1.9.73
|
# pycups==1.9.73
|
||||||
|
|
||||||
|
# homeassistant.components.daikin
|
||||||
|
# homeassistant.components.climate.daikin
|
||||||
|
pydaikin==0.4
|
||||||
|
|
||||||
# homeassistant.components.deconz
|
# homeassistant.components.deconz
|
||||||
pydeconz==23
|
pydeconz==23
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user