mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Update HVAC action handling in ZHA climate devices (#61460)
* Update HVAC action handling in ZHA climate devices * fix class name * align with class name changes * get the correct sensor entity for state assertions
This commit is contained in:
parent
7711f9a391
commit
94324cebea
@ -7,10 +7,11 @@ at https://home-assistant.io/components/zha.climate/
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import enum
|
|
||||||
import functools
|
import functools
|
||||||
from random import randint
|
from random import randint
|
||||||
|
|
||||||
|
from zigpy.zcl.clusters.hvac import Fan as F, Thermostat as T
|
||||||
|
|
||||||
from homeassistant.components.climate import ClimateEntity
|
from homeassistant.components.climate import ClimateEntity
|
||||||
from homeassistant.components.climate.const import (
|
from homeassistant.components.climate.const import (
|
||||||
ATTR_HVAC_MODE,
|
ATTR_HVAC_MODE,
|
||||||
@ -82,27 +83,6 @@ STRICT_MATCH = functools.partial(ZHA_ENTITIES.strict_match, Platform.CLIMATE)
|
|||||||
MULTI_MATCH = functools.partial(ZHA_ENTITIES.multipass_match, Platform.CLIMATE)
|
MULTI_MATCH = functools.partial(ZHA_ENTITIES.multipass_match, Platform.CLIMATE)
|
||||||
RUNNING_MODE = {0x00: HVAC_MODE_OFF, 0x03: HVAC_MODE_COOL, 0x04: HVAC_MODE_HEAT}
|
RUNNING_MODE = {0x00: HVAC_MODE_OFF, 0x03: HVAC_MODE_COOL, 0x04: HVAC_MODE_HEAT}
|
||||||
|
|
||||||
|
|
||||||
class ThermostatFanMode(enum.IntEnum):
|
|
||||||
"""Fan channel enum for thermostat Fans."""
|
|
||||||
|
|
||||||
OFF = 0x00
|
|
||||||
ON = 0x04
|
|
||||||
AUTO = 0x05
|
|
||||||
|
|
||||||
|
|
||||||
class RunningState(enum.IntFlag):
|
|
||||||
"""ZCL Running state enum."""
|
|
||||||
|
|
||||||
HEAT = 0x0001
|
|
||||||
COOL = 0x0002
|
|
||||||
FAN = 0x0004
|
|
||||||
HEAT_STAGE_2 = 0x0008
|
|
||||||
COOL_STAGE_2 = 0x0010
|
|
||||||
FAN_STAGE_2 = 0x0020
|
|
||||||
FAN_STAGE_3 = 0x0040
|
|
||||||
|
|
||||||
|
|
||||||
SEQ_OF_OPERATION = {
|
SEQ_OF_OPERATION = {
|
||||||
0x00: (HVAC_MODE_OFF, HVAC_MODE_COOL), # cooling only
|
0x00: (HVAC_MODE_OFF, HVAC_MODE_COOL), # cooling only
|
||||||
0x01: (HVAC_MODE_OFF, HVAC_MODE_COOL), # cooling with reheat
|
0x01: (HVAC_MODE_OFF, HVAC_MODE_COOL), # cooling with reheat
|
||||||
@ -116,40 +96,25 @@ SEQ_OF_OPERATION = {
|
|||||||
0x07: (HVAC_MODE_HEAT_COOL, HVAC_MODE_OFF), # centralite specific
|
0x07: (HVAC_MODE_HEAT_COOL, HVAC_MODE_OFF), # centralite specific
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SystemMode(enum.IntEnum):
|
|
||||||
"""ZCL System Mode attribute enum."""
|
|
||||||
|
|
||||||
OFF = 0x00
|
|
||||||
HEAT_COOL = 0x01
|
|
||||||
COOL = 0x03
|
|
||||||
HEAT = 0x04
|
|
||||||
AUX_HEAT = 0x05
|
|
||||||
PRE_COOL = 0x06
|
|
||||||
FAN_ONLY = 0x07
|
|
||||||
DRY = 0x08
|
|
||||||
SLEEP = 0x09
|
|
||||||
|
|
||||||
|
|
||||||
HVAC_MODE_2_SYSTEM = {
|
HVAC_MODE_2_SYSTEM = {
|
||||||
HVAC_MODE_OFF: SystemMode.OFF,
|
HVAC_MODE_OFF: T.SystemMode.Off,
|
||||||
HVAC_MODE_HEAT_COOL: SystemMode.HEAT_COOL,
|
HVAC_MODE_HEAT_COOL: T.SystemMode.Auto,
|
||||||
HVAC_MODE_COOL: SystemMode.COOL,
|
HVAC_MODE_COOL: T.SystemMode.Cool,
|
||||||
HVAC_MODE_HEAT: SystemMode.HEAT,
|
HVAC_MODE_HEAT: T.SystemMode.Heat,
|
||||||
HVAC_MODE_FAN_ONLY: SystemMode.FAN_ONLY,
|
HVAC_MODE_FAN_ONLY: T.SystemMode.Fan_only,
|
||||||
HVAC_MODE_DRY: SystemMode.DRY,
|
HVAC_MODE_DRY: T.SystemMode.Dry,
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSTEM_MODE_2_HVAC = {
|
SYSTEM_MODE_2_HVAC = {
|
||||||
SystemMode.OFF: HVAC_MODE_OFF,
|
T.SystemMode.Off: HVAC_MODE_OFF,
|
||||||
SystemMode.HEAT_COOL: HVAC_MODE_HEAT_COOL,
|
T.SystemMode.Auto: HVAC_MODE_HEAT_COOL,
|
||||||
SystemMode.COOL: HVAC_MODE_COOL,
|
T.SystemMode.Cool: HVAC_MODE_COOL,
|
||||||
SystemMode.HEAT: HVAC_MODE_HEAT,
|
T.SystemMode.Heat: HVAC_MODE_HEAT,
|
||||||
SystemMode.AUX_HEAT: HVAC_MODE_HEAT,
|
T.SystemMode.Emergency_Heating: HVAC_MODE_HEAT,
|
||||||
SystemMode.PRE_COOL: HVAC_MODE_COOL, # this is 'precooling'. is it the same?
|
T.SystemMode.Pre_cooling: HVAC_MODE_COOL, # this is 'precooling'. is it the same?
|
||||||
SystemMode.FAN_ONLY: HVAC_MODE_FAN_ONLY,
|
T.SystemMode.Fan_only: HVAC_MODE_FAN_ONLY,
|
||||||
SystemMode.DRY: HVAC_MODE_DRY,
|
T.SystemMode.Dry: HVAC_MODE_DRY,
|
||||||
SystemMode.SLEEP: HVAC_MODE_OFF,
|
T.SystemMode.Sleep: HVAC_MODE_OFF,
|
||||||
}
|
}
|
||||||
|
|
||||||
ZCL_TEMP = 100
|
ZCL_TEMP = 100
|
||||||
@ -233,7 +198,9 @@ class Thermostat(ZhaEntity, ClimateEntity):
|
|||||||
return FAN_AUTO
|
return FAN_AUTO
|
||||||
|
|
||||||
if self._thrm.running_state & (
|
if self._thrm.running_state & (
|
||||||
RunningState.FAN | RunningState.FAN_STAGE_2 | RunningState.FAN_STAGE_3
|
T.RunningState.Fan_State_On
|
||||||
|
| T.RunningState.Fan_2nd_Stage_On
|
||||||
|
| T.RunningState.Fan_3rd_Stage_On
|
||||||
):
|
):
|
||||||
return FAN_ON
|
return FAN_ON
|
||||||
return FAN_AUTO
|
return FAN_AUTO
|
||||||
@ -259,18 +226,25 @@ class Thermostat(ZhaEntity, ClimateEntity):
|
|||||||
def _rm_rs_action(self) -> str | None:
|
def _rm_rs_action(self) -> str | None:
|
||||||
"""Return the current HVAC action based on running mode and running state."""
|
"""Return the current HVAC action based on running mode and running state."""
|
||||||
|
|
||||||
running_mode = self._thrm.running_mode
|
if (running_state := self._thrm.running_state) is None:
|
||||||
if running_mode == SystemMode.HEAT:
|
return None
|
||||||
|
if running_state & (
|
||||||
|
T.RunningState.Heat_State_On | T.RunningState.Heat_2nd_Stage_On
|
||||||
|
):
|
||||||
return CURRENT_HVAC_HEAT
|
return CURRENT_HVAC_HEAT
|
||||||
if running_mode == SystemMode.COOL:
|
if running_state & (
|
||||||
|
T.RunningState.Cool_State_On | T.RunningState.Cool_2nd_Stage_On
|
||||||
|
):
|
||||||
return CURRENT_HVAC_COOL
|
return CURRENT_HVAC_COOL
|
||||||
|
if running_state & (
|
||||||
running_state = self._thrm.running_state
|
T.RunningState.Fan_State_On
|
||||||
if running_state and running_state & (
|
| T.RunningState.Fan_2nd_Stage_On
|
||||||
RunningState.FAN | RunningState.FAN_STAGE_2 | RunningState.FAN_STAGE_3
|
| T.RunningState.Fan_3rd_Stage_On
|
||||||
):
|
):
|
||||||
return CURRENT_HVAC_FAN
|
return CURRENT_HVAC_FAN
|
||||||
if self.hvac_mode != HVAC_MODE_OFF and running_mode == SystemMode.OFF:
|
if running_state & T.RunningState.Idle:
|
||||||
|
return CURRENT_HVAC_IDLE
|
||||||
|
if self.hvac_mode != HVAC_MODE_OFF:
|
||||||
return CURRENT_HVAC_IDLE
|
return CURRENT_HVAC_IDLE
|
||||||
return CURRENT_HVAC_OFF
|
return CURRENT_HVAC_OFF
|
||||||
|
|
||||||
@ -431,9 +405,9 @@ class Thermostat(ZhaEntity, ClimateEntity):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if fan_mode == FAN_ON:
|
if fan_mode == FAN_ON:
|
||||||
mode = ThermostatFanMode.ON
|
mode = F.FanMode.On
|
||||||
else:
|
else:
|
||||||
mode = ThermostatFanMode.AUTO
|
mode = F.FanMode.Auto
|
||||||
|
|
||||||
await self._fan.async_set_speed(mode)
|
await self._fan.async_set_speed(mode)
|
||||||
|
|
||||||
@ -545,6 +519,27 @@ class SinopeTechnologiesThermostat(Thermostat):
|
|||||||
self._supported_flags |= SUPPORT_PRESET_MODE
|
self._supported_flags |= SUPPORT_PRESET_MODE
|
||||||
self._manufacturer_ch = self.cluster_channels["sinope_manufacturer_specific"]
|
self._manufacturer_ch = self.cluster_channels["sinope_manufacturer_specific"]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _rm_rs_action(self) -> str | None:
|
||||||
|
"""Return the current HVAC action based on running mode and running state."""
|
||||||
|
|
||||||
|
running_mode = self._thrm.running_mode
|
||||||
|
if running_mode == T.SystemMode.Heat:
|
||||||
|
return CURRENT_HVAC_HEAT
|
||||||
|
if running_mode == T.SystemMode.Cool:
|
||||||
|
return CURRENT_HVAC_COOL
|
||||||
|
|
||||||
|
running_state = self._thrm.running_state
|
||||||
|
if running_state and running_state & (
|
||||||
|
T.RunningState.Fan_State_On
|
||||||
|
| T.RunningState.Fan_2nd_Stage_On
|
||||||
|
| T.RunningState.Fan_3rd_Stage_On
|
||||||
|
):
|
||||||
|
return CURRENT_HVAC_FAN
|
||||||
|
if self.hvac_mode != HVAC_MODE_OFF and running_mode == T.SystemMode.Off:
|
||||||
|
return CURRENT_HVAC_IDLE
|
||||||
|
return CURRENT_HVAC_OFF
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _async_update_time(self, timestamp=None) -> None:
|
def _async_update_time(self, timestamp=None) -> None:
|
||||||
"""Update thermostat's time display."""
|
"""Update thermostat's time display."""
|
||||||
@ -588,25 +583,6 @@ class SinopeTechnologiesThermostat(Thermostat):
|
|||||||
class ZenWithinThermostat(Thermostat):
|
class ZenWithinThermostat(Thermostat):
|
||||||
"""Zen Within Thermostat implementation."""
|
"""Zen Within Thermostat implementation."""
|
||||||
|
|
||||||
@property
|
|
||||||
def _rm_rs_action(self) -> str | None:
|
|
||||||
"""Return the current HVAC action based on running mode and running state."""
|
|
||||||
|
|
||||||
if (running_state := self._thrm.running_state) is None:
|
|
||||||
return None
|
|
||||||
if running_state & (RunningState.HEAT | RunningState.HEAT_STAGE_2):
|
|
||||||
return CURRENT_HVAC_HEAT
|
|
||||||
if running_state & (RunningState.COOL | RunningState.COOL_STAGE_2):
|
|
||||||
return CURRENT_HVAC_COOL
|
|
||||||
if running_state & (
|
|
||||||
RunningState.FAN | RunningState.FAN_STAGE_2 | RunningState.FAN_STAGE_3
|
|
||||||
):
|
|
||||||
return CURRENT_HVAC_FAN
|
|
||||||
|
|
||||||
if self.hvac_mode != HVAC_MODE_OFF:
|
|
||||||
return CURRENT_HVAC_IDLE
|
|
||||||
return CURRENT_HVAC_OFF
|
|
||||||
|
|
||||||
|
|
||||||
@MULTI_MATCH(
|
@MULTI_MATCH(
|
||||||
channel_names=CHANNEL_THERMOSTAT,
|
channel_names=CHANNEL_THERMOSTAT,
|
||||||
|
@ -51,7 +51,6 @@ from .core import discovery
|
|||||||
from .core.const import (
|
from .core.const import (
|
||||||
CHANNEL_ANALOG_INPUT,
|
CHANNEL_ANALOG_INPUT,
|
||||||
CHANNEL_ELECTRICAL_MEASUREMENT,
|
CHANNEL_ELECTRICAL_MEASUREMENT,
|
||||||
CHANNEL_FAN,
|
|
||||||
CHANNEL_HUMIDITY,
|
CHANNEL_HUMIDITY,
|
||||||
CHANNEL_ILLUMINANCE,
|
CHANNEL_ILLUMINANCE,
|
||||||
CHANNEL_LEAF_WETNESS,
|
CHANNEL_LEAF_WETNESS,
|
||||||
@ -587,66 +586,6 @@ class ThermostatHVACAction(Sensor, id_suffix="hvac_action"):
|
|||||||
return self._rm_rs_action
|
return self._rm_rs_action
|
||||||
return self._pi_demand_action
|
return self._pi_demand_action
|
||||||
|
|
||||||
@property
|
|
||||||
def _rm_rs_action(self) -> str | None:
|
|
||||||
"""Return the current HVAC action based on running mode and running state."""
|
|
||||||
|
|
||||||
running_mode = self._channel.running_mode
|
|
||||||
if running_mode == self._channel.RunningMode.Heat:
|
|
||||||
return CURRENT_HVAC_HEAT
|
|
||||||
if running_mode == self._channel.RunningMode.Cool:
|
|
||||||
return CURRENT_HVAC_COOL
|
|
||||||
|
|
||||||
running_state = self._channel.running_state
|
|
||||||
if running_state and running_state & (
|
|
||||||
self._channel.RunningState.Fan_State_On
|
|
||||||
| self._channel.RunningState.Fan_2nd_Stage_On
|
|
||||||
| self._channel.RunningState.Fan_3rd_Stage_On
|
|
||||||
):
|
|
||||||
return CURRENT_HVAC_FAN
|
|
||||||
if (
|
|
||||||
self._channel.system_mode != self._channel.SystemMode.Off
|
|
||||||
and running_mode == self._channel.SystemMode.Off
|
|
||||||
):
|
|
||||||
return CURRENT_HVAC_IDLE
|
|
||||||
return CURRENT_HVAC_OFF
|
|
||||||
|
|
||||||
@property
|
|
||||||
def _pi_demand_action(self) -> str | None:
|
|
||||||
"""Return the current HVAC action based on pi_demands."""
|
|
||||||
|
|
||||||
heating_demand = self._channel.pi_heating_demand
|
|
||||||
if heating_demand is not None and heating_demand > 0:
|
|
||||||
return CURRENT_HVAC_HEAT
|
|
||||||
cooling_demand = self._channel.pi_cooling_demand
|
|
||||||
if cooling_demand is not None and cooling_demand > 0:
|
|
||||||
return CURRENT_HVAC_COOL
|
|
||||||
|
|
||||||
if self._channel.system_mode != self._channel.SystemMode.Off:
|
|
||||||
return CURRENT_HVAC_IDLE
|
|
||||||
return CURRENT_HVAC_OFF
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_set_state(self, *args, **kwargs) -> None:
|
|
||||||
"""Handle state update from channel."""
|
|
||||||
self.async_write_ha_state()
|
|
||||||
|
|
||||||
|
|
||||||
@MULTI_MATCH(
|
|
||||||
channel_names=CHANNEL_THERMOSTAT,
|
|
||||||
aux_channels=CHANNEL_FAN,
|
|
||||||
manufacturers="Centralite",
|
|
||||||
models={"3157100", "3157100-E"},
|
|
||||||
stop_on_match_group=CHANNEL_THERMOSTAT,
|
|
||||||
)
|
|
||||||
@MULTI_MATCH(
|
|
||||||
channel_names=CHANNEL_THERMOSTAT,
|
|
||||||
manufacturers="Zen Within",
|
|
||||||
stop_on_match_group=CHANNEL_THERMOSTAT,
|
|
||||||
)
|
|
||||||
class ZenHVACAction(ThermostatHVACAction):
|
|
||||||
"""Zen Within Thermostat HVAC Action."""
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _rm_rs_action(self) -> str | None:
|
def _rm_rs_action(self) -> str | None:
|
||||||
"""Return the current HVAC action based on running mode and running state."""
|
"""Return the current HVAC action based on running mode and running state."""
|
||||||
@ -676,6 +615,63 @@ class ZenHVACAction(ThermostatHVACAction):
|
|||||||
):
|
):
|
||||||
return CURRENT_HVAC_FAN
|
return CURRENT_HVAC_FAN
|
||||||
|
|
||||||
|
running_state = self._channel.running_state
|
||||||
|
if running_state and running_state & self._channel.RunningState.Idle:
|
||||||
|
return CURRENT_HVAC_IDLE
|
||||||
|
|
||||||
if self._channel.system_mode != self._channel.SystemMode.Off:
|
if self._channel.system_mode != self._channel.SystemMode.Off:
|
||||||
return CURRENT_HVAC_IDLE
|
return CURRENT_HVAC_IDLE
|
||||||
return CURRENT_HVAC_OFF
|
return CURRENT_HVAC_OFF
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _pi_demand_action(self) -> str | None:
|
||||||
|
"""Return the current HVAC action based on pi_demands."""
|
||||||
|
|
||||||
|
heating_demand = self._channel.pi_heating_demand
|
||||||
|
if heating_demand is not None and heating_demand > 0:
|
||||||
|
return CURRENT_HVAC_HEAT
|
||||||
|
cooling_demand = self._channel.pi_cooling_demand
|
||||||
|
if cooling_demand is not None and cooling_demand > 0:
|
||||||
|
return CURRENT_HVAC_COOL
|
||||||
|
|
||||||
|
if self._channel.system_mode != self._channel.SystemMode.Off:
|
||||||
|
return CURRENT_HVAC_IDLE
|
||||||
|
return CURRENT_HVAC_OFF
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_set_state(self, *args, **kwargs) -> None:
|
||||||
|
"""Handle state update from channel."""
|
||||||
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
|
||||||
|
@MULTI_MATCH(
|
||||||
|
channel_names={CHANNEL_THERMOSTAT},
|
||||||
|
manufacturers="Sinope Technologies",
|
||||||
|
stop_on_match_group=CHANNEL_THERMOSTAT,
|
||||||
|
)
|
||||||
|
class SinopeHVACAction(ThermostatHVACAction):
|
||||||
|
"""Sinope Thermostat HVAC action sensor."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _rm_rs_action(self) -> str | None:
|
||||||
|
"""Return the current HVAC action based on running mode and running state."""
|
||||||
|
|
||||||
|
running_mode = self._channel.running_mode
|
||||||
|
if running_mode == self._channel.RunningMode.Heat:
|
||||||
|
return CURRENT_HVAC_HEAT
|
||||||
|
if running_mode == self._channel.RunningMode.Cool:
|
||||||
|
return CURRENT_HVAC_COOL
|
||||||
|
|
||||||
|
running_state = self._channel.running_state
|
||||||
|
if running_state and running_state & (
|
||||||
|
self._channel.RunningState.Fan_State_On
|
||||||
|
| self._channel.RunningState.Fan_2nd_Stage_On
|
||||||
|
| self._channel.RunningState.Fan_3rd_Stage_On
|
||||||
|
):
|
||||||
|
return CURRENT_HVAC_FAN
|
||||||
|
if (
|
||||||
|
self._channel.system_mode != self._channel.SystemMode.Off
|
||||||
|
and running_mode == self._channel.SystemMode.Off
|
||||||
|
):
|
||||||
|
return CURRENT_HVAC_IDLE
|
||||||
|
return CURRENT_HVAC_OFF
|
||||||
|
@ -106,7 +106,7 @@ async def send_attributes_report(hass, cluster: zigpy.zcl.Cluster, attributes: d
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
async def find_entity_id(domain, zha_device, hass):
|
async def find_entity_id(domain, zha_device, hass, qualifier=None):
|
||||||
"""Find the entity id under the testing.
|
"""Find the entity id under the testing.
|
||||||
|
|
||||||
This is used to get the entity id in order to get the state from the state
|
This is used to get the entity id in order to get the state from the state
|
||||||
@ -115,7 +115,12 @@ async def find_entity_id(domain, zha_device, hass):
|
|||||||
entities = await find_entity_ids(domain, zha_device, hass)
|
entities = await find_entity_ids(domain, zha_device, hass)
|
||||||
if not entities:
|
if not entities:
|
||||||
return None
|
return None
|
||||||
return entities[0]
|
if qualifier:
|
||||||
|
for entity_id in entities:
|
||||||
|
if qualifier in entity_id:
|
||||||
|
return entity_id
|
||||||
|
else:
|
||||||
|
return entities[0]
|
||||||
|
|
||||||
|
|
||||||
async def find_entity_ids(domain, zha_device, hass):
|
async def find_entity_ids(domain, zha_device, hass):
|
||||||
|
@ -254,12 +254,14 @@ async def test_climate_local_temp(hass, device_climate):
|
|||||||
assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 21.0
|
assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 21.0
|
||||||
|
|
||||||
|
|
||||||
async def test_climate_hvac_action_running_state(hass, device_climate):
|
async def test_climate_hvac_action_running_state(hass, device_climate_sinope):
|
||||||
"""Test hvac action via running state."""
|
"""Test hvac action via running state."""
|
||||||
|
|
||||||
thrm_cluster = device_climate.device.endpoints[1].thermostat
|
thrm_cluster = device_climate_sinope.device.endpoints[1].thermostat
|
||||||
entity_id = await find_entity_id(Platform.CLIMATE, device_climate, hass)
|
entity_id = await find_entity_id(Platform.CLIMATE, device_climate_sinope, hass)
|
||||||
sensor_entity_id = await find_entity_id(Platform.SENSOR, device_climate, hass)
|
sensor_entity_id = await find_entity_id(
|
||||||
|
Platform.SENSOR, device_climate_sinope, hass, "hvac"
|
||||||
|
)
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
|
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
|
||||||
@ -407,7 +409,7 @@ async def test_climate_hvac_action_pi_demand(hass, device_climate):
|
|||||||
entity_id = await find_entity_id(Platform.CLIMATE, device_climate, hass)
|
entity_id = await find_entity_id(Platform.CLIMATE, device_climate, hass)
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
|
assert ATTR_HVAC_ACTION not in state.attributes
|
||||||
|
|
||||||
await send_attributes_report(hass, thrm_cluster, {0x0007: 10})
|
await send_attributes_report(hass, thrm_cluster, {0x0007: 10})
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
|
@ -3267,7 +3267,7 @@ DEVICES = [
|
|||||||
},
|
},
|
||||||
("sensor", "00:11:22:33:44:55:66:77-1-513-hvac_action"): {
|
("sensor", "00:11:22:33:44:55:66:77-1-513-hvac_action"): {
|
||||||
DEV_SIG_CHANNELS: ["thermostat"],
|
DEV_SIG_CHANNELS: ["thermostat"],
|
||||||
DEV_SIG_ENT_MAP_CLASS: "ThermostatHVACAction",
|
DEV_SIG_ENT_MAP_CLASS: "SinopeHVACAction",
|
||||||
DEV_SIG_ENT_MAP_ID: "sensor.sinope_technologies_th1123zb_77665544_thermostat_hvac_action",
|
DEV_SIG_ENT_MAP_ID: "sensor.sinope_technologies_th1123zb_77665544_thermostat_hvac_action",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -3312,7 +3312,7 @@ DEVICES = [
|
|||||||
},
|
},
|
||||||
("sensor", "00:11:22:33:44:55:66:77-1-513-hvac_action"): {
|
("sensor", "00:11:22:33:44:55:66:77-1-513-hvac_action"): {
|
||||||
DEV_SIG_CHANNELS: ["thermostat"],
|
DEV_SIG_CHANNELS: ["thermostat"],
|
||||||
DEV_SIG_ENT_MAP_CLASS: "ThermostatHVACAction",
|
DEV_SIG_ENT_MAP_CLASS: "SinopeHVACAction",
|
||||||
DEV_SIG_ENT_MAP_ID: "sensor.sinope_technologies_th1124zb_77665544_thermostat_hvac_action",
|
DEV_SIG_ENT_MAP_ID: "sensor.sinope_technologies_th1124zb_77665544_thermostat_hvac_action",
|
||||||
},
|
},
|
||||||
("sensor", "00:11:22:33:44:55:66:77-1-1026"): {
|
("sensor", "00:11:22:33:44:55:66:77-1-1026"): {
|
||||||
@ -3557,7 +3557,7 @@ DEVICES = [
|
|||||||
},
|
},
|
||||||
("sensor", "00:11:22:33:44:55:66:77-1-513-hvac_action"): {
|
("sensor", "00:11:22:33:44:55:66:77-1-513-hvac_action"): {
|
||||||
DEV_SIG_CHANNELS: ["thermostat"],
|
DEV_SIG_CHANNELS: ["thermostat"],
|
||||||
DEV_SIG_ENT_MAP_CLASS: "ZenHVACAction",
|
DEV_SIG_ENT_MAP_CLASS: "ThermostatHVACAction",
|
||||||
DEV_SIG_ENT_MAP_ID: "sensor.zen_within_zen_01_77665544_thermostat_hvac_action",
|
DEV_SIG_ENT_MAP_ID: "sensor.zen_within_zen_01_77665544_thermostat_hvac_action",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user