mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 14:17:45 +00:00
Correctly support humidification and dehumidification in Nexia Thermostats (#139792)
* Add set_dehumidify_setpoint service. Refactor set_humidify_setpoint. * Add closest_value function in utils * Refactor target humidity * Update tests for util.py * Refactor target humidity. Update tests. * Remove duplicate constant * Add humidify and dehumidfy sensors * Update sensor names * Remove clamping and commented code * Iplement suggestions from review * Switch order check order * remove closest_value() * Update strings for clarity/grammar * Update strings for grammar/clarity * tweaks --------- Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
2876e5d0cd
commit
691cb378a0
@ -53,13 +53,18 @@ PARALLEL_UPDATES = 1 # keep data in sync with only one connection at a time
|
||||
|
||||
SERVICE_SET_AIRCLEANER_MODE = "set_aircleaner_mode"
|
||||
SERVICE_SET_HUMIDIFY_SETPOINT = "set_humidify_setpoint"
|
||||
SERVICE_SET_DEHUMIDIFY_SETPOINT = "set_dehumidify_setpoint"
|
||||
SERVICE_SET_HVAC_RUN_MODE = "set_hvac_run_mode"
|
||||
|
||||
SET_AIRCLEANER_SCHEMA: VolDictType = {
|
||||
vol.Required(ATTR_AIRCLEANER_MODE): cv.string,
|
||||
}
|
||||
|
||||
SET_HUMIDITY_SCHEMA: VolDictType = {
|
||||
SET_HUMIDIFY_SCHEMA: VolDictType = {
|
||||
vol.Required(ATTR_HUMIDITY): vol.All(vol.Coerce(int), vol.Range(min=10, max=45)),
|
||||
}
|
||||
|
||||
SET_DEHUMIDIFY_SCHEMA: VolDictType = {
|
||||
vol.Required(ATTR_HUMIDITY): vol.All(vol.Coerce(int), vol.Range(min=35, max=65)),
|
||||
}
|
||||
|
||||
@ -126,9 +131,14 @@ async def async_setup_entry(
|
||||
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_SET_HUMIDIFY_SETPOINT,
|
||||
SET_HUMIDITY_SCHEMA,
|
||||
SET_HUMIDIFY_SCHEMA,
|
||||
f"async_{SERVICE_SET_HUMIDIFY_SETPOINT}",
|
||||
)
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_SET_DEHUMIDIFY_SETPOINT,
|
||||
SET_DEHUMIDIFY_SCHEMA,
|
||||
f"async_{SERVICE_SET_DEHUMIDIFY_SETPOINT}",
|
||||
)
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_SET_AIRCLEANER_MODE,
|
||||
SET_AIRCLEANER_SCHEMA,
|
||||
@ -224,20 +234,48 @@ class NexiaZone(NexiaThermostatZoneEntity, ClimateEntity):
|
||||
return self._zone.get_preset()
|
||||
|
||||
async def async_set_humidity(self, humidity: int) -> None:
|
||||
"""Dehumidify target."""
|
||||
if self._thermostat.has_dehumidify_support():
|
||||
await self.async_set_dehumidify_setpoint(humidity)
|
||||
"""Set humidity targets.
|
||||
|
||||
HA doesn't support separate humidify and dehumidify targets.
|
||||
Set the target for the current mode if in [heat, cool]
|
||||
otherwise set both targets to the clamped values.
|
||||
"""
|
||||
zone_current_mode = self._zone.get_current_mode()
|
||||
if zone_current_mode == OPERATION_MODE_HEAT:
|
||||
if self._thermostat.has_humidify_support():
|
||||
await self.async_set_humidify_setpoint(humidity)
|
||||
elif zone_current_mode == OPERATION_MODE_COOL:
|
||||
if self._thermostat.has_dehumidify_support():
|
||||
await self.async_set_dehumidify_setpoint(humidity)
|
||||
else:
|
||||
await self.async_set_humidify_setpoint(humidity)
|
||||
if self._thermostat.has_humidify_support():
|
||||
await self.async_set_humidify_setpoint(humidity)
|
||||
if self._thermostat.has_dehumidify_support():
|
||||
await self.async_set_dehumidify_setpoint(humidity)
|
||||
self._signal_thermostat_update()
|
||||
|
||||
@property
|
||||
def target_humidity(self):
|
||||
"""Humidity indoors setpoint."""
|
||||
def target_humidity(self) -> float | None:
|
||||
"""Humidity indoors setpoint.
|
||||
|
||||
In systems that support both humidification and dehumidification,
|
||||
two values for target exist. We must choose one to return.
|
||||
|
||||
:return: The target humidity setpoint.
|
||||
"""
|
||||
|
||||
# If heat is on, always return humidify value first
|
||||
if (
|
||||
self._has_humidify_support
|
||||
and self._zone.get_current_mode() == OPERATION_MODE_HEAT
|
||||
):
|
||||
return percent_conv(self._thermostat.get_humidify_setpoint())
|
||||
# Fall back to previous behavior of returning dehumidify value then humidify
|
||||
if self._has_dehumidify_support:
|
||||
return percent_conv(self._thermostat.get_dehumidify_setpoint())
|
||||
if self._has_humidify_support:
|
||||
return percent_conv(self._thermostat.get_humidify_setpoint())
|
||||
|
||||
return None
|
||||
|
||||
@property
|
||||
|
@ -26,6 +26,9 @@
|
||||
"set_humidify_setpoint": {
|
||||
"service": "mdi:water-percent"
|
||||
},
|
||||
"set_dehumidify_setpoint": {
|
||||
"service": "mdi:water-percent"
|
||||
},
|
||||
"set_hvac_run_mode": {
|
||||
"service": "mdi:hvac"
|
||||
}
|
||||
|
@ -114,6 +114,35 @@ async def async_setup_entry(
|
||||
percent_conv,
|
||||
)
|
||||
)
|
||||
# Heating Humidification Setpoint
|
||||
if thermostat.has_humidify_support():
|
||||
entities.append(
|
||||
NexiaThermostatSensor(
|
||||
coordinator,
|
||||
thermostat,
|
||||
"get_humidify_setpoint",
|
||||
"get_humidify_setpoint",
|
||||
SensorDeviceClass.HUMIDITY,
|
||||
PERCENTAGE,
|
||||
SensorStateClass.MEASUREMENT,
|
||||
percent_conv,
|
||||
)
|
||||
)
|
||||
|
||||
# Cooling Dehumidification Setpoint
|
||||
if thermostat.has_dehumidify_support():
|
||||
entities.append(
|
||||
NexiaThermostatSensor(
|
||||
coordinator,
|
||||
thermostat,
|
||||
"get_dehumidify_setpoint",
|
||||
"get_dehumidify_setpoint",
|
||||
SensorDeviceClass.HUMIDITY,
|
||||
PERCENTAGE,
|
||||
SensorStateClass.MEASUREMENT,
|
||||
percent_conv,
|
||||
)
|
||||
)
|
||||
|
||||
# Zone Sensors
|
||||
for zone_id in thermostat.get_zone_ids():
|
||||
|
@ -14,6 +14,20 @@ set_aircleaner_mode:
|
||||
- "quick"
|
||||
|
||||
set_humidify_setpoint:
|
||||
target:
|
||||
entity:
|
||||
integration: nexia
|
||||
domain: climate
|
||||
fields:
|
||||
humidity:
|
||||
required: true
|
||||
selector:
|
||||
number:
|
||||
min: 10
|
||||
max: 45
|
||||
unit_of_measurement: "%"
|
||||
|
||||
set_dehumidify_setpoint:
|
||||
target:
|
||||
entity:
|
||||
integration: nexia
|
||||
|
@ -53,6 +53,12 @@
|
||||
},
|
||||
"zone_setpoint_status": {
|
||||
"name": "Zone setpoint status"
|
||||
},
|
||||
"get_humidify_setpoint": {
|
||||
"name": "Heating humidify setpoint"
|
||||
},
|
||||
"get_dehumidify_setpoint": {
|
||||
"name": "Cooling dehumidify setpoint"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
@ -76,12 +82,22 @@
|
||||
}
|
||||
},
|
||||
"set_humidify_setpoint": {
|
||||
"name": "Set humidify set point",
|
||||
"description": "Sets the target humidity.",
|
||||
"name": "Set humidify setpoint",
|
||||
"description": "Sets the target humidity for heating.",
|
||||
"fields": {
|
||||
"humidity": {
|
||||
"name": "Humidity",
|
||||
"description": "The humidification setpoint."
|
||||
"description": "The setpoint for humidification when heating."
|
||||
}
|
||||
}
|
||||
},
|
||||
"set_dehumidify_setpoint": {
|
||||
"name": "Set dehumidify setpoint",
|
||||
"description": "Sets the target humidity for cooling.",
|
||||
"fields": {
|
||||
"humidity": {
|
||||
"name": "Humidity",
|
||||
"description": "The setpoint for dehumidification when cooling."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user