Add humidity and aux heat support to climate (#631)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Stefan Rado 2023-11-28 23:54:14 +01:00 committed by GitHub
parent 63d5928cba
commit 0f14c82efa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 211 additions and 175 deletions

View File

@ -842,6 +842,11 @@ message ListEntitiesClimateResponse {
string icon = 19; string icon = 19;
EntityCategory entity_category = 20; EntityCategory entity_category = 20;
float visual_current_temperature_step = 21; float visual_current_temperature_step = 21;
bool supports_current_humidity = 22;
bool supports_target_humidity = 23;
float visual_min_humidity = 24;
float visual_max_humidity = 25;
bool supports_aux_heat = 26;
} }
message ClimateStateResponse { message ClimateStateResponse {
option (id) = 47; option (id) = 47;
@ -863,6 +868,9 @@ message ClimateStateResponse {
string custom_fan_mode = 11; string custom_fan_mode = 11;
ClimatePreset preset = 12; ClimatePreset preset = 12;
string custom_preset = 13; string custom_preset = 13;
float current_humidity = 14;
float target_humidity = 15;
bool aux_heat = 16;
} }
message ClimateCommandRequest { message ClimateCommandRequest {
option (id) = 48; option (id) = 48;
@ -892,6 +900,10 @@ message ClimateCommandRequest {
ClimatePreset preset = 19; ClimatePreset preset = 19;
bool has_custom_preset = 20; bool has_custom_preset = 20;
string custom_preset = 21; string custom_preset = 21;
bool has_target_humidity = 22;
float target_humidity = 23;
bool has_aux_heat = 24;
bool aux_heat = 25;
} }
// ==================== NUMBER ==================== // ==================== NUMBER ====================

File diff suppressed because one or more lines are too long

View File

@ -1035,7 +1035,7 @@ class APIClient:
async def switch_command(self, key: int, state: bool) -> None: async def switch_command(self, key: int, state: bool) -> None:
self._get_connection().send_message(SwitchCommandRequest(key=key, state=state)) self._get_connection().send_message(SwitchCommandRequest(key=key, state=state))
async def climate_command( async def climate_command( # pylint: disable=too-many-branches
self, self,
key: int, key: int,
mode: ClimateMode | None = None, mode: ClimateMode | None = None,
@ -1047,6 +1047,8 @@ class APIClient:
custom_fan_mode: str | None = None, custom_fan_mode: str | None = None,
preset: ClimatePreset | None = None, preset: ClimatePreset | None = None,
custom_preset: str | None = None, custom_preset: str | None = None,
target_humidity: float | None = None,
aux_heat: bool | None = None,
) -> None: ) -> None:
req = ClimateCommandRequest(key=key) req = ClimateCommandRequest(key=key)
if mode is not None: if mode is not None:
@ -1083,6 +1085,12 @@ class APIClient:
if custom_preset is not None: if custom_preset is not None:
req.has_custom_preset = True req.has_custom_preset = True
req.custom_preset = custom_preset req.custom_preset = custom_preset
if target_humidity is not None:
req.has_target_humidity = True
req.target_humidity = target_humidity
if aux_heat is not None:
req.has_aux_heat = True
req.aux_heat = aux_heat
self._get_connection().send_message(req) self._get_connection().send_message(req)
async def number_command(self, key: int, state: float) -> None: async def number_command(self, key: int, state: float) -> None:

View File

@ -544,6 +544,11 @@ class ClimateInfo(EntityInfo):
supported_custom_presets: list[str] = converter_field( supported_custom_presets: list[str] = converter_field(
default_factory=list, converter=list default_factory=list, converter=list
) )
supports_current_humidity: bool = False
supports_target_humidity: bool = False
visual_min_humidity: float = 0
visual_max_humidity: float = 0
supports_aux_heat: bool = False
def supported_presets_compat(self, api_version: APIVersion) -> list[ClimatePreset]: def supported_presets_compat(self, api_version: APIVersion) -> list[ClimatePreset]:
if api_version < APIVersion(1, 5): if api_version < APIVersion(1, 5):
@ -587,6 +592,9 @@ class ClimateState(EntityState):
default=ClimatePreset.NONE, converter=ClimatePreset.convert default=ClimatePreset.NONE, converter=ClimatePreset.convert
) )
custom_preset: str = "" custom_preset: str = ""
current_humidity: float = 0
target_humidity: float = 0
aux_heat: bool = False
def preset_compat(self, api_version: APIVersion) -> ClimatePreset | None: def preset_compat(self, api_version: APIVersion) -> ClimatePreset | None:
if api_version < APIVersion(1, 5): if api_version < APIVersion(1, 5):

View File

@ -524,6 +524,14 @@ async def test_climate_command_legacy(
dict(key=1, custom_preset="asdf"), dict(key=1, custom_preset="asdf"),
dict(key=1, has_custom_preset=True, custom_preset="asdf"), dict(key=1, has_custom_preset=True, custom_preset="asdf"),
), ),
(
dict(key=1, target_humidity=60.0),
dict(key=1, has_target_humidity=True, target_humidity=60.0),
),
(
dict(key=1, aux_heat=True),
dict(key=1, has_aux_heat=True, aux_heat=True),
),
], ],
) )
async def test_climate_command( async def test_climate_command(