Skip to content

Commit fc9313f

Browse files
farmioCopilot
andauthored
Support KNX climate entity configuration from UI (home-assistant#154162)
Co-authored-by: Copilot <[email protected]>
1 parent 278f322 commit fc9313f

File tree

9 files changed

+1530
-95
lines changed

9 files changed

+1530
-95
lines changed

homeassistant/components/knx/climate.py

Lines changed: 278 additions & 55 deletions
Large diffs are not rendered by default.

homeassistant/components/knx/const.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class FanZeroMode(StrEnum):
160160

161161
SUPPORTED_PLATFORMS_UI: Final = {
162162
Platform.BINARY_SENSOR,
163+
Platform.CLIMATE,
163164
Platform.COVER,
164165
Platform.LIGHT,
165166
Platform.SWITCH,
@@ -193,3 +194,23 @@ class CoverConf:
193194
INVERT_UPDOWN: Final = "invert_updown"
194195
INVERT_POSITION: Final = "invert_position"
195196
INVERT_ANGLE: Final = "invert_angle"
197+
198+
199+
class ClimateConf:
200+
"""Common config keys for climate."""
201+
202+
MIN_TEMP: Final = "min_temp"
203+
MAX_TEMP: Final = "max_temp"
204+
TEMPERATURE_STEP: Final = "temperature_step"
205+
SETPOINT_SHIFT_MAX: Final = "setpoint_shift_max"
206+
SETPOINT_SHIFT_MIN: Final = "setpoint_shift_min"
207+
208+
ON_OFF_INVERT: Final = "on_off_invert"
209+
210+
OPERATION_MODES: Final = "operation_modes"
211+
CONTROLLER_MODES: Final = "controller_modes"
212+
DEFAULT_CONTROLLER_MODE: Final = "default_controller_mode"
213+
214+
FAN_MAX_STEP: Final = "fan_max_step"
215+
FAN_SPEED_MODE: Final = "fan_speed_mode"
216+
FAN_ZERO_MODE: Final = "fan_zero_mode"

homeassistant/components/knx/schema.py

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
CONF_STATE_ADDRESS,
5757
CONF_SYNC_STATE,
5858
KNX_ADDRESS,
59+
ClimateConf,
5960
ColorTempModes,
6061
CoverConf,
6162
FanZeroMode,
@@ -306,10 +307,7 @@ class ClimateSchema(KNXPlatformSchema):
306307
CONF_SETPOINT_SHIFT_ADDRESS = "setpoint_shift_address"
307308
CONF_SETPOINT_SHIFT_STATE_ADDRESS = "setpoint_shift_state_address"
308309
CONF_SETPOINT_SHIFT_MODE = "setpoint_shift_mode"
309-
CONF_SETPOINT_SHIFT_MAX = "setpoint_shift_max"
310-
CONF_SETPOINT_SHIFT_MIN = "setpoint_shift_min"
311310
CONF_TEMPERATURE_ADDRESS = "temperature_address"
312-
CONF_TEMPERATURE_STEP = "temperature_step"
313311
CONF_TARGET_TEMPERATURE_ADDRESS = "target_temperature_address"
314312
CONF_TARGET_TEMPERATURE_STATE_ADDRESS = "target_temperature_state_address"
315313
CONF_OPERATION_MODE_ADDRESS = "operation_mode_address"
@@ -327,19 +325,10 @@ class ClimateSchema(KNXPlatformSchema):
327325
CONF_OPERATION_MODE_NIGHT_ADDRESS = "operation_mode_night_address"
328326
CONF_OPERATION_MODE_COMFORT_ADDRESS = "operation_mode_comfort_address"
329327
CONF_OPERATION_MODE_STANDBY_ADDRESS = "operation_mode_standby_address"
330-
CONF_OPERATION_MODES = "operation_modes"
331-
CONF_CONTROLLER_MODES = "controller_modes"
332-
CONF_DEFAULT_CONTROLLER_MODE = "default_controller_mode"
333328
CONF_ON_OFF_ADDRESS = "on_off_address"
334329
CONF_ON_OFF_STATE_ADDRESS = "on_off_state_address"
335-
CONF_ON_OFF_INVERT = "on_off_invert"
336-
CONF_MIN_TEMP = "min_temp"
337-
CONF_MAX_TEMP = "max_temp"
338330
CONF_FAN_SPEED_ADDRESS = "fan_speed_address"
339331
CONF_FAN_SPEED_STATE_ADDRESS = "fan_speed_state_address"
340-
CONF_FAN_MAX_STEP = "fan_max_step"
341-
CONF_FAN_SPEED_MODE = "fan_speed_mode"
342-
CONF_FAN_ZERO_MODE = "fan_zero_mode"
343332
CONF_HUMIDITY_STATE_ADDRESS = "humidity_state_address"
344333
CONF_SWING_ADDRESS = "swing_address"
345334
CONF_SWING_STATE_ADDRESS = "swing_state_address"
@@ -359,13 +348,13 @@ class ClimateSchema(KNXPlatformSchema):
359348
{
360349
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
361350
vol.Optional(
362-
CONF_SETPOINT_SHIFT_MAX, default=DEFAULT_SETPOINT_SHIFT_MAX
351+
ClimateConf.SETPOINT_SHIFT_MAX, default=DEFAULT_SETPOINT_SHIFT_MAX
363352
): vol.All(int, vol.Range(min=0, max=32)),
364353
vol.Optional(
365-
CONF_SETPOINT_SHIFT_MIN, default=DEFAULT_SETPOINT_SHIFT_MIN
354+
ClimateConf.SETPOINT_SHIFT_MIN, default=DEFAULT_SETPOINT_SHIFT_MIN
366355
): vol.All(int, vol.Range(min=-32, max=0)),
367356
vol.Optional(
368-
CONF_TEMPERATURE_STEP, default=DEFAULT_TEMPERATURE_STEP
357+
ClimateConf.TEMPERATURE_STEP, default=DEFAULT_TEMPERATURE_STEP
369358
): vol.All(float, vol.Range(min=0, max=2)),
370359
vol.Required(CONF_TEMPERATURE_ADDRESS): ga_list_validator,
371360
vol.Required(CONF_TARGET_TEMPERATURE_STATE_ADDRESS): ga_list_validator,
@@ -408,29 +397,29 @@ class ClimateSchema(KNXPlatformSchema):
408397
vol.Optional(CONF_ON_OFF_ADDRESS): ga_list_validator,
409398
vol.Optional(CONF_ON_OFF_STATE_ADDRESS): ga_list_validator,
410399
vol.Optional(
411-
CONF_ON_OFF_INVERT, default=DEFAULT_ON_OFF_INVERT
400+
ClimateConf.ON_OFF_INVERT, default=DEFAULT_ON_OFF_INVERT
412401
): cv.boolean,
413-
vol.Optional(CONF_OPERATION_MODES): vol.All(
402+
vol.Optional(ClimateConf.OPERATION_MODES): vol.All(
414403
cv.ensure_list,
415404
[backwards_compatible_xknx_climate_enum_member(HVACOperationMode)],
416405
),
417-
vol.Optional(CONF_CONTROLLER_MODES): vol.All(
406+
vol.Optional(ClimateConf.CONTROLLER_MODES): vol.All(
418407
cv.ensure_list,
419408
[backwards_compatible_xknx_climate_enum_member(HVACControllerMode)],
420409
),
421410
vol.Optional(
422-
CONF_DEFAULT_CONTROLLER_MODE, default=HVACMode.HEAT
411+
ClimateConf.DEFAULT_CONTROLLER_MODE, default=HVACMode.HEAT
423412
): vol.Coerce(HVACMode),
424-
vol.Optional(CONF_MIN_TEMP): vol.Coerce(float),
425-
vol.Optional(CONF_MAX_TEMP): vol.Coerce(float),
413+
vol.Optional(ClimateConf.MIN_TEMP): vol.Coerce(float),
414+
vol.Optional(ClimateConf.MAX_TEMP): vol.Coerce(float),
426415
vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
427416
vol.Optional(CONF_FAN_SPEED_ADDRESS): ga_list_validator,
428417
vol.Optional(CONF_FAN_SPEED_STATE_ADDRESS): ga_list_validator,
429-
vol.Optional(CONF_FAN_MAX_STEP, default=3): cv.byte,
418+
vol.Optional(ClimateConf.FAN_MAX_STEP, default=3): cv.byte,
430419
vol.Optional(
431-
CONF_FAN_SPEED_MODE, default=DEFAULT_FAN_SPEED_MODE
420+
ClimateConf.FAN_SPEED_MODE, default=DEFAULT_FAN_SPEED_MODE
432421
): vol.All(vol.Upper, cv.enum(FanSpeedMode)),
433-
vol.Optional(CONF_FAN_ZERO_MODE, default=FAN_OFF): vol.Coerce(
422+
vol.Optional(ClimateConf.FAN_ZERO_MODE, default=FAN_OFF): vol.Coerce(
434423
FanZeroMode
435424
),
436425
vol.Optional(CONF_SWING_ADDRESS): ga_list_validator,

homeassistant/components/knx/storage/const.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,28 @@
1414
CONF_GA_SENSOR: Final = "ga_sensor"
1515
CONF_GA_SWITCH: Final = "ga_switch"
1616

17+
# Climate
18+
CONF_GA_TEMPERATURE_CURRENT: Final = "ga_temperature_current"
19+
CONF_GA_HUMIDITY_CURRENT: Final = "ga_humidity_current"
20+
CONF_TARGET_TEMPERATURE: Final = "target_temperature"
21+
CONF_GA_TEMPERATURE_TARGET: Final = "ga_temperature_target"
22+
CONF_GA_SETPOINT_SHIFT: Final = "ga_setpoint_shift"
23+
CONF_GA_ACTIVE: Final = "ga_active"
24+
CONF_GA_VALVE: Final = "ga_valve"
25+
CONF_GA_OPERATION_MODE: Final = "ga_operation_mode"
26+
CONF_IGNORE_AUTO_MODE: Final = "ignore_auto_mode"
27+
CONF_GA_OP_MODE_COMFORT: Final = "ga_operation_mode_comfort"
28+
CONF_GA_OP_MODE_ECO: Final = "ga_operation_mode_economy"
29+
CONF_GA_OP_MODE_STANDBY: Final = "ga_operation_mode_standby"
30+
CONF_GA_OP_MODE_PROTECTION: Final = "ga_operation_mode_protection"
31+
CONF_GA_HEAT_COOL: Final = "ga_heat_cool"
32+
CONF_GA_ON_OFF: Final = "ga_on_off"
33+
CONF_GA_CONTROLLER_MODE: Final = "ga_controller_mode"
34+
CONF_GA_CONTROLLER_STATUS: Final = "ga_controller_status"
35+
CONF_GA_FAN_SPEED: Final = "ga_fan_speed"
36+
CONF_GA_FAN_SWING: Final = "ga_fan_swing"
37+
CONF_GA_FAN_SWING_HORIZONTAL: Final = "ga_fan_swing_horizontal"
38+
1739
# Cover
1840
CONF_GA_UP_DOWN: Final = "ga_up_down"
1941
CONF_GA_STOP: Final = "ga_stop"

homeassistant/components/knx/storage/entity_store_schema.py

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import voluptuous as vol
66

7+
from homeassistant.components.climate import HVACMode
78
from homeassistant.const import (
89
CONF_ENTITY_CATEGORY,
910
CONF_ENTITY_ID,
@@ -24,8 +25,10 @@
2425
CONF_SYNC_STATE,
2526
DOMAIN,
2627
SUPPORTED_PLATFORMS_UI,
28+
ClimateConf,
2729
ColorTempModes,
2830
CoverConf,
31+
FanZeroMode,
2932
)
3033
from .const import (
3134
CONF_COLOR,
@@ -34,27 +37,47 @@
3437
CONF_DATA,
3538
CONF_DEVICE_INFO,
3639
CONF_ENTITY,
40+
CONF_GA_ACTIVE,
3741
CONF_GA_ANGLE,
3842
CONF_GA_BLUE_BRIGHTNESS,
3943
CONF_GA_BLUE_SWITCH,
4044
CONF_GA_BRIGHTNESS,
4145
CONF_GA_COLOR,
4246
CONF_GA_COLOR_TEMP,
47+
CONF_GA_CONTROLLER_MODE,
48+
CONF_GA_CONTROLLER_STATUS,
49+
CONF_GA_FAN_SPEED,
50+
CONF_GA_FAN_SWING,
51+
CONF_GA_FAN_SWING_HORIZONTAL,
4352
CONF_GA_GREEN_BRIGHTNESS,
4453
CONF_GA_GREEN_SWITCH,
54+
CONF_GA_HEAT_COOL,
4555
CONF_GA_HUE,
56+
CONF_GA_HUMIDITY_CURRENT,
57+
CONF_GA_ON_OFF,
58+
CONF_GA_OP_MODE_COMFORT,
59+
CONF_GA_OP_MODE_ECO,
60+
CONF_GA_OP_MODE_PROTECTION,
61+
CONF_GA_OP_MODE_STANDBY,
62+
CONF_GA_OPERATION_MODE,
4663
CONF_GA_POSITION_SET,
4764
CONF_GA_POSITION_STATE,
4865
CONF_GA_RED_BRIGHTNESS,
4966
CONF_GA_RED_SWITCH,
5067
CONF_GA_SATURATION,
5168
CONF_GA_SENSOR,
69+
CONF_GA_SETPOINT_SHIFT,
5270
CONF_GA_STEP,
5371
CONF_GA_STOP,
5472
CONF_GA_SWITCH,
73+
CONF_GA_TEMPERATURE_CURRENT,
74+
CONF_GA_TEMPERATURE_TARGET,
5575
CONF_GA_UP_DOWN,
76+
CONF_GA_VALVE,
5677
CONF_GA_WHITE_BRIGHTNESS,
5778
CONF_GA_WHITE_SWITCH,
79+
CONF_IGNORE_AUTO_MODE,
80+
CONF_TARGET_TEMPERATURE,
5881
)
5982
from .knx_selector import (
6083
AllSerializeFirst,
@@ -313,8 +336,151 @@ class LightColorMode(StrEnum):
313336
},
314337
)
315338

339+
340+
@unique
341+
class ConfSetpointShiftMode(StrEnum):
342+
"""Enum for setpoint shift mode."""
343+
344+
COUNT = "6.010"
345+
FLOAT = "9.002"
346+
347+
348+
@unique
349+
class ConfClimateFanSpeedMode(StrEnum):
350+
"""Enum for climate fan speed mode."""
351+
352+
PERCENTAGE = "5.001"
353+
STEPS = "5.010"
354+
355+
356+
CLIMATE_KNX_SCHEMA = vol.Schema(
357+
{
358+
vol.Required(CONF_GA_TEMPERATURE_CURRENT): GASelector(
359+
write=False, state_required=True, valid_dpt="9.001"
360+
),
361+
vol.Optional(CONF_GA_HUMIDITY_CURRENT): GASelector(
362+
write=False, valid_dpt="9.002"
363+
),
364+
vol.Required(CONF_TARGET_TEMPERATURE): GroupSelect(
365+
GroupSelectOption(
366+
translation_key="group_direct_temp",
367+
schema={
368+
vol.Required(CONF_GA_TEMPERATURE_TARGET): GASelector(
369+
write_required=True, valid_dpt="9.001"
370+
),
371+
vol.Required(
372+
ClimateConf.MIN_TEMP, default=7
373+
): selector.NumberSelector(
374+
selector.NumberSelectorConfig(
375+
min=-20, max=80, step=1, unit_of_measurement="°C"
376+
)
377+
),
378+
vol.Required(
379+
ClimateConf.MAX_TEMP, default=28
380+
): selector.NumberSelector(
381+
selector.NumberSelectorConfig(
382+
min=0, max=100, step=1, unit_of_measurement="°C"
383+
)
384+
),
385+
vol.Required(
386+
ClimateConf.TEMPERATURE_STEP, default=0.1
387+
): selector.NumberSelector(
388+
selector.NumberSelectorConfig(
389+
min=0.1, max=2, step=0.1, unit_of_measurement="K"
390+
),
391+
),
392+
},
393+
),
394+
GroupSelectOption(
395+
translation_key="group_setpoint_shift",
396+
schema={
397+
vol.Required(CONF_GA_TEMPERATURE_TARGET): GASelector(
398+
write=False, state_required=True, valid_dpt="9.001"
399+
),
400+
vol.Required(CONF_GA_SETPOINT_SHIFT): GASelector(
401+
write_required=True,
402+
state_required=True,
403+
dpt=ConfSetpointShiftMode,
404+
),
405+
vol.Required(
406+
ClimateConf.SETPOINT_SHIFT_MIN, default=-6
407+
): selector.NumberSelector(
408+
selector.NumberSelectorConfig(
409+
min=-32, max=0, step=1, unit_of_measurement="K"
410+
)
411+
),
412+
vol.Required(
413+
ClimateConf.SETPOINT_SHIFT_MAX, default=6
414+
): selector.NumberSelector(
415+
selector.NumberSelectorConfig(
416+
min=0, max=32, step=1, unit_of_measurement="K"
417+
)
418+
),
419+
vol.Required(
420+
ClimateConf.TEMPERATURE_STEP, default=0.1
421+
): selector.NumberSelector(
422+
selector.NumberSelectorConfig(
423+
min=0.1, max=2, step=0.1, unit_of_measurement="K"
424+
),
425+
),
426+
},
427+
),
428+
collapsible=False,
429+
),
430+
"section_activity": KNXSectionFlat(collapsible=True),
431+
vol.Optional(CONF_GA_ACTIVE): GASelector(write=False, valid_dpt="1"),
432+
vol.Optional(CONF_GA_VALVE): GASelector(write=False, valid_dpt="5.001"),
433+
"section_operation_mode": KNXSectionFlat(collapsible=True),
434+
vol.Optional(CONF_GA_OPERATION_MODE): GASelector(valid_dpt="20.102"),
435+
vol.Optional(CONF_IGNORE_AUTO_MODE): selector.BooleanSelector(),
436+
"section_operation_mode_individual": KNXSectionFlat(collapsible=True),
437+
vol.Optional(CONF_GA_OP_MODE_COMFORT): GASelector(state=False, valid_dpt="1"),
438+
vol.Optional(CONF_GA_OP_MODE_ECO): GASelector(state=False, valid_dpt="1"),
439+
vol.Optional(CONF_GA_OP_MODE_STANDBY): GASelector(state=False, valid_dpt="1"),
440+
vol.Optional(CONF_GA_OP_MODE_PROTECTION): GASelector(
441+
state=False, valid_dpt="1"
442+
),
443+
"section_heat_cool": KNXSectionFlat(collapsible=True),
444+
vol.Optional(CONF_GA_HEAT_COOL): GASelector(valid_dpt="1.100"),
445+
"section_on_off": KNXSectionFlat(collapsible=True),
446+
vol.Optional(CONF_GA_ON_OFF): GASelector(valid_dpt="1"),
447+
vol.Optional(ClimateConf.ON_OFF_INVERT): selector.BooleanSelector(),
448+
"section_controller_mode": KNXSectionFlat(collapsible=True),
449+
vol.Optional(CONF_GA_CONTROLLER_MODE): GASelector(valid_dpt="20.105"),
450+
vol.Optional(CONF_GA_CONTROLLER_STATUS): GASelector(write=False),
451+
vol.Required(
452+
ClimateConf.DEFAULT_CONTROLLER_MODE, default=HVACMode.HEAT
453+
): selector.SelectSelector(
454+
selector.SelectSelectorConfig(
455+
options=list(HVACMode),
456+
translation_key="component.climate.selector.hvac_mode",
457+
)
458+
),
459+
"section_fan": KNXSectionFlat(collapsible=True),
460+
vol.Optional(CONF_GA_FAN_SPEED): GASelector(dpt=ConfClimateFanSpeedMode),
461+
vol.Required(ClimateConf.FAN_MAX_STEP, default=3): AllSerializeFirst(
462+
selector.NumberSelector(
463+
selector.NumberSelectorConfig(min=1, max=100, step=1)
464+
),
465+
vol.Coerce(int),
466+
),
467+
vol.Required(
468+
ClimateConf.FAN_ZERO_MODE, default=FanZeroMode.OFF
469+
): selector.SelectSelector(
470+
selector.SelectSelectorConfig(
471+
options=list(FanZeroMode),
472+
translation_key="component.knx.config_panel.entities.create.climate.knx.fan_zero_mode",
473+
)
474+
),
475+
vol.Optional(CONF_GA_FAN_SWING): GASelector(valid_dpt="1"),
476+
vol.Optional(CONF_GA_FAN_SWING_HORIZONTAL): GASelector(valid_dpt="1"),
477+
vol.Optional(CONF_SYNC_STATE, default=True): SyncStateSelector(),
478+
},
479+
)
480+
316481
KNX_SCHEMA_FOR_PLATFORM = {
317482
Platform.BINARY_SENSOR: BINARY_SENSOR_KNX_SCHEMA,
483+
Platform.CLIMATE: CLIMATE_KNX_SCHEMA,
318484
Platform.COVER: COVER_KNX_SCHEMA,
319485
Platform.LIGHT: LIGHT_KNX_SCHEMA,
320486
Platform.SWITCH: SWITCH_KNX_SCHEMA,

0 commit comments

Comments
 (0)