1
0
mirror of https://github.com/home-assistant/core.git synced 2026-02-15 07:36:16 +00:00

Fix duplicate HVACMode in Tuya climate (#160918)

This commit is contained in:
epenet
2026-01-15 22:12:24 +01:00
committed by GitHub
parent e2e7485e30
commit 67e676df4f
2 changed files with 53 additions and 31 deletions

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
import collections
from dataclasses import dataclass
from typing import Any, Self
@@ -140,6 +141,22 @@ class _SwingModeWrapper(DeviceWrapper):
return commands
def _filter_hvac_mode_mappings(tuya_range: list[str]) -> dict[str, HVACMode | None]:
"""Filter TUYA_HVAC_TO_HA modes that are not in the range.
If multiple Tuya modes map to the same HA mode, set the mapping to None to avoid
ambiguity when converting back from HA to Tuya modes.
"""
modes_in_range = {
tuya_mode: TUYA_HVAC_TO_HA.get(tuya_mode) for tuya_mode in tuya_range
}
modes_occurrences = collections.Counter(modes_in_range.values())
for key, value in modes_in_range.items():
if value is not None and modes_occurrences[value] > 1:
modes_in_range[key] = None
return modes_in_range
class _HvacModeWrapper(DPCodeEnumWrapper):
"""Wrapper for managing climate HVACMode."""
@@ -148,10 +165,9 @@ class _HvacModeWrapper(DPCodeEnumWrapper):
def __init__(self, dpcode: str, type_information: EnumTypeInformation) -> None:
"""Init _HvacModeWrapper."""
super().__init__(dpcode, type_information)
self._mappings = _filter_hvac_mode_mappings(type_information.range)
self.options = [
TUYA_HVAC_TO_HA[tuya_mode]
for tuya_mode in type_information.range
if tuya_mode in TUYA_HVAC_TO_HA
ha_mode for ha_mode in self._mappings.values() if ha_mode is not None
]
def read_device_status(self, device: CustomerDevice) -> HVACMode | None:
@@ -166,7 +182,7 @@ class _HvacModeWrapper(DPCodeEnumWrapper):
"""Convert value to raw value."""
return next(
tuya_mode
for tuya_mode, ha_mode in TUYA_HVAC_TO_HA.items()
for tuya_mode, ha_mode in self._mappings.items()
if ha_mode == value
)
@@ -179,10 +195,9 @@ class _PresetWrapper(DPCodeEnumWrapper):
def __init__(self, dpcode: str, type_information: EnumTypeInformation) -> None:
"""Init _PresetWrapper."""
super().__init__(dpcode, type_information)
mappings = _filter_hvac_mode_mappings(type_information.range)
self.options = [
tuya_mode
for tuya_mode in type_information.range
if tuya_mode not in TUYA_HVAC_TO_HA
tuya_mode for tuya_mode, ha_mode in mappings.items() if ha_mode is None
]
def read_device_status(self, device: CustomerDevice) -> str | None:

View File

@@ -83,13 +83,13 @@
'capabilities': dict({
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT: 'heat'>,
]),
'max_temp': 35.0,
'min_temp': 5.0,
'preset_modes': list([
'auto',
'manual',
'off',
]),
'target_temp_step': 1.0,
@@ -130,13 +130,13 @@
'friendly_name': 'Anbau',
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT: 'heat'>,
]),
'max_temp': 35.0,
'min_temp': 5.0,
'preset_modes': list([
'auto',
'manual',
'off',
]),
'supported_features': <ClimateEntityFeature: 17>,
@@ -159,13 +159,13 @@
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
]),
'max_temp': 70.0,
'min_temp': 1.0,
'preset_modes': list([
'holiday',
'auto',
'manual',
'eco',
]),
'target_temp_step': 0.5,
@@ -208,14 +208,14 @@
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
]),
'max_temp': 70.0,
'min_temp': 1.0,
'preset_mode': None,
'preset_modes': list([
'holiday',
'auto',
'manual',
'eco',
]),
'supported_features': <ClimateEntityFeature: 17>,
@@ -453,13 +453,13 @@
'capabilities': dict({
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT: 'heat'>,
]),
'max_temp': 35.0,
'min_temp': 5.0,
'preset_modes': list([
'auto',
'manual',
'off',
]),
'target_temp_step': 1.0,
@@ -501,14 +501,14 @@
'friendly_name': 'Empore',
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT: 'heat'>,
]),
'max_temp': 35.0,
'min_temp': 5.0,
'preset_mode': None,
'preset_modes': list([
'auto',
'manual',
'off',
]),
'supported_features': <ClimateEntityFeature: 17>,
@@ -532,12 +532,12 @@
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
]),
'max_temp': 35.0,
'min_temp': 5.0,
'preset_modes': list([
'auto',
'manual',
'off',
]),
'target_temp_step': 1.0,
@@ -580,13 +580,13 @@
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
]),
'max_temp': 35.0,
'min_temp': 5.0,
'preset_mode': None,
'preset_modes': list([
'auto',
'manual',
'off',
]),
'supported_features': <ClimateEntityFeature: 401>,
@@ -1107,12 +1107,12 @@
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
]),
'max_temp': 5.9,
'min_temp': 0.1,
'preset_modes': list([
'auto',
'manual',
'holiday',
]),
'target_temp_step': 0.5,
@@ -1155,13 +1155,13 @@
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
]),
'max_temp': 5.9,
'min_temp': 0.1,
'preset_mode': None,
'preset_modes': list([
'auto',
'manual',
'holiday',
]),
'supported_features': <ClimateEntityFeature: 17>,
@@ -1185,10 +1185,13 @@
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
]),
'max_temp': 90.0,
'min_temp': 5.0,
'preset_modes': list([
'auto',
'manual',
]),
'target_temp_step': 1.0,
}),
'config_entry_id': <ANY>,
@@ -1215,7 +1218,7 @@
'platform': 'tuya',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': <ClimateEntityFeature: 385>,
'supported_features': <ClimateEntityFeature: 401>,
'translation_key': None,
'unique_id': 'tuya.sb3zdertrw50bgogkw',
'unit_of_measurement': None,
@@ -1229,11 +1232,15 @@
'hvac_modes': list([
<HVACMode.OFF: 'off'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
<HVACMode.HEAT_COOL: 'heat_cool'>,
]),
'max_temp': 90.0,
'min_temp': 5.0,
'supported_features': <ClimateEntityFeature: 385>,
'preset_mode': None,
'preset_modes': list([
'auto',
'manual',
]),
'supported_features': <ClimateEntityFeature: 401>,
'target_temp_step': 1.0,
'temperature': 12.0,
}),