hass-core/homeassistant/components/nexia/sensor.py
J. Nick Koston b8fdebd05c
Add aircleaner and humidify service to nexia climate (#33078)
* Add aircleaner and humidify service to nexia climate

* These were removed from the original merge to reduce review scope

* Additional tests for binary_sensor, sensor, and climate states

* Switch to signals for services

Get rid of everywhere we call device and change to zone or thermostat
as it was too confusing

Renames to make it clear that zone and thermostat are tightly coupled

* Make scene activation responsive

* no need to use update for only one key/value

* stray comma

* use async_call_later

* its async, need ()s

* cleaner

* merge entity platform services testing branch
2020-03-23 11:01:48 -05:00

239 lines
6.8 KiB
Python

"""Support for Nexia / Trane XL Thermostats."""
from nexia.const import UNIT_CELSIUS
from homeassistant.const import (
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_TEMPERATURE,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
UNIT_PERCENTAGE,
)
from .const import DOMAIN, NEXIA_DEVICE, UPDATE_COORDINATOR
from .entity import NexiaThermostatEntity, NexiaThermostatZoneEntity
from .util import percent_conv
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up sensors for a Nexia device."""
nexia_data = hass.data[DOMAIN][config_entry.entry_id]
nexia_home = nexia_data[NEXIA_DEVICE]
coordinator = nexia_data[UPDATE_COORDINATOR]
entities = []
# Thermostat / System Sensors
for thermostat_id in nexia_home.get_thermostat_ids():
thermostat = nexia_home.get_thermostat_by_id(thermostat_id)
entities.append(
NexiaThermostatSensor(
coordinator,
thermostat,
"get_system_status",
"System Status",
None,
None,
)
)
# Air cleaner
entities.append(
NexiaThermostatSensor(
coordinator,
thermostat,
"get_air_cleaner_mode",
"Air Cleaner Mode",
None,
None,
)
)
# Compressor Speed
if thermostat.has_variable_speed_compressor():
entities.append(
NexiaThermostatSensor(
coordinator,
thermostat,
"get_current_compressor_speed",
"Current Compressor Speed",
None,
UNIT_PERCENTAGE,
percent_conv,
)
)
entities.append(
NexiaThermostatSensor(
coordinator,
thermostat,
"get_requested_compressor_speed",
"Requested Compressor Speed",
None,
UNIT_PERCENTAGE,
percent_conv,
)
)
# Outdoor Temperature
if thermostat.has_outdoor_temperature():
unit = (
TEMP_CELSIUS
if thermostat.get_unit() == UNIT_CELSIUS
else TEMP_FAHRENHEIT
)
entities.append(
NexiaThermostatSensor(
coordinator,
thermostat,
"get_outdoor_temperature",
"Outdoor Temperature",
DEVICE_CLASS_TEMPERATURE,
unit,
)
)
# Relative Humidity
if thermostat.has_relative_humidity():
entities.append(
NexiaThermostatSensor(
coordinator,
thermostat,
"get_relative_humidity",
"Relative Humidity",
DEVICE_CLASS_HUMIDITY,
UNIT_PERCENTAGE,
percent_conv,
)
)
# Zone Sensors
for zone_id in thermostat.get_zone_ids():
zone = thermostat.get_zone_by_id(zone_id)
unit = (
TEMP_CELSIUS
if thermostat.get_unit() == UNIT_CELSIUS
else TEMP_FAHRENHEIT
)
# Temperature
entities.append(
NexiaThermostatZoneSensor(
coordinator,
zone,
"get_temperature",
"Temperature",
DEVICE_CLASS_TEMPERATURE,
unit,
None,
)
)
# Zone Status
entities.append(
NexiaThermostatZoneSensor(
coordinator, zone, "get_status", "Zone Status", None, None,
)
)
# Setpoint Status
entities.append(
NexiaThermostatZoneSensor(
coordinator,
zone,
"get_setpoint_status",
"Zone Setpoint Status",
None,
None,
)
)
async_add_entities(entities, True)
class NexiaThermostatSensor(NexiaThermostatEntity):
"""Provides Nexia thermostat sensor support."""
def __init__(
self,
coordinator,
thermostat,
sensor_call,
sensor_name,
sensor_class,
sensor_unit,
modifier=None,
):
"""Initialize the sensor."""
super().__init__(
coordinator,
thermostat,
name=f"{thermostat.get_name()} {sensor_name}",
unique_id=f"{thermostat.thermostat_id}_{sensor_call}",
)
self._call = sensor_call
self._class = sensor_class
self._state = None
self._unit_of_measurement = sensor_unit
self._modifier = modifier
@property
def device_class(self):
"""Return the device class of the sensor."""
return self._class
@property
def state(self):
"""Return the state of the sensor."""
val = getattr(self._thermostat, self._call)()
if self._modifier:
val = self._modifier(val)
if isinstance(val, float):
val = round(val, 1)
return val
@property
def unit_of_measurement(self):
"""Return the unit of measurement this sensor expresses itself in."""
return self._unit_of_measurement
class NexiaThermostatZoneSensor(NexiaThermostatZoneEntity):
"""Nexia Zone Sensor Support."""
def __init__(
self,
coordinator,
zone,
sensor_call,
sensor_name,
sensor_class,
sensor_unit,
modifier=None,
):
"""Create a zone sensor."""
super().__init__(
coordinator,
zone,
name=f"{zone.get_name()} {sensor_name}",
unique_id=f"{zone.zone_id}_{sensor_call}",
)
self._call = sensor_call
self._class = sensor_class
self._state = None
self._unit_of_measurement = sensor_unit
self._modifier = modifier
@property
def device_class(self):
"""Return the device class of the sensor."""
return self._class
@property
def state(self):
"""Return the state of the sensor."""
val = getattr(self._zone, self._call)()
if self._modifier:
val = self._modifier(val)
if isinstance(val, float):
val = round(val, 1)
return val
@property
def unit_of_measurement(self):
"""Return the unit of measurement this sensor expresses itself in."""
return self._unit_of_measurement