1 """Voluptuous schemas for the KNX integration."""
3 from __future__
import annotations
6 from collections
import OrderedDict
7 from typing
import ClassVar, Final
9 import voluptuous
as vol
10 from xknx.devices.climate
import FanSpeedMode, SetpointShiftMode
11 from xknx.dpt
import DPTBase, DPTNumeric
12 from xknx.dpt.dpt_20
import HVACControllerMode, HVACOperationMode
13 from xknx.exceptions
import ConversionError, CouldNotParseTelegram
16 DEVICE_CLASSES_SCHEMA
as BINARY_SENSOR_DEVICE_CLASSES_SCHEMA,
20 DEVICE_CLASSES_SCHEMA
as COVER_DEVICE_CLASSES_SCHEMA,
25 DEVICE_CLASSES_SCHEMA
as SENSOR_DEVICE_CLASSES_SCHEMA,
29 DEVICE_CLASSES_SCHEMA
as SWITCH_DEVICE_CLASSES_SCHEMA,
59 from .validation
import (
60 backwards_compatible_xknx_climate_enum_member,
61 dpt_base_type_validator,
64 numeric_type_validator,
65 sensor_type_validator,
66 string_type_validator,
75 """Validate a number entity configurations dependent on configured value type."""
76 value_type = entity_config[CONF_TYPE]
77 min_config: float |
None = entity_config.get(NumberSchema.CONF_MIN)
78 max_config: float |
None = entity_config.get(NumberSchema.CONF_MAX)
79 step_config: float |
None = entity_config.get(NumberSchema.CONF_STEP)
80 dpt_class = DPTNumeric.parse_transcoder(value_type)
83 raise vol.Invalid(f
"'type: {value_type}' is not a valid numeric sensor type.")
86 if min_config
is None and dpt_class.value_min ==
float(
"-inf"):
87 raise vol.Invalid(f
"'min' key required for value type '{value_type}'")
88 if min_config
is not None and min_config < dpt_class.value_min:
90 f
"'min: {min_config}' undercuts possible minimum"
91 f
" of value type '{value_type}': {dpt_class.value_min}"
94 if max_config
is None and dpt_class.value_max ==
float(
"inf"):
95 raise vol.Invalid(f
"'max' key required for value type '{value_type}'")
96 if max_config
is not None and max_config > dpt_class.value_max:
98 f
"'max: {max_config}' exceeds possible maximum"
99 f
" of value type '{value_type}': {dpt_class.value_max}"
102 if step_config
is not None and step_config < dpt_class.resolution:
104 f
"'step: {step_config}' undercuts possible minimum step"
105 f
" of value type '{value_type}': {dpt_class.resolution}"
112 if payload_length == 0:
114 return int(256**payload_length) - 1
118 """Validate a button entity payload configuration."""
119 if _type := entity_config.get(CONF_TYPE):
120 _payload = entity_config[ButtonSchema.CONF_VALUE]
121 if (transcoder := DPTBase.parse_transcoder(_type))
is None:
122 raise vol.Invalid(f
"'type: {_type}' is not a valid sensor type.")
123 entity_config[CONF_PAYLOAD_LENGTH] = transcoder.payload_length
125 _dpt_payload = transcoder.to_knx(_payload)
126 _raw_payload = transcoder.validate_payload(_dpt_payload)
127 except (ConversionError, CouldNotParseTelegram)
as ex:
129 f
"'payload: {_payload}' not valid for 'type: {_type}'"
131 entity_config[CONF_PAYLOAD] = int.from_bytes(_raw_payload, byteorder=
"big")
134 _payload = entity_config[CONF_PAYLOAD]
135 _payload_length = entity_config[CONF_PAYLOAD_LENGTH]
138 f
"'payload: {_payload}' exceeds possible maximum for "
139 f
"payload_length {_payload_length}: {max_payload}"
145 """Validate a select entity options configuration."""
147 payloads_seen = set()
148 payload_length = entity_config[CONF_PAYLOAD_LENGTH]
150 for opt
in entity_config[SelectSchema.CONF_OPTIONS]:
151 option = opt[SelectSchema.CONF_OPTION]
152 payload = opt[CONF_PAYLOAD]
155 f
"'payload: {payload}' for 'option: {option}' exceeds possible"
156 f
" maximum of 'payload_length: {payload_length}': {max_payload}"
158 if option
in options_seen:
159 raise vol.Invalid(f
"duplicate item for 'option' not allowed: {option}")
160 options_seen.add(option)
161 if payload
in payloads_seen:
162 raise vol.Invalid(f
"duplicate item for 'payload' not allowed: {payload}")
163 payloads_seen.add(payload)
173 """Voluptuous schema for KNX events."""
175 KNX_EVENT_FILTER_SCHEMA = vol.Schema(
177 vol.Required(KNX_ADDRESS): vol.All(cv.ensure_list, [cv.string]),
178 vol.Optional(CONF_TYPE): dpt_base_type_validator,
183 vol.Optional(CONF_EVENT, default=[]): vol.All(
184 cv.ensure_list, [KNX_EVENT_FILTER_SCHEMA]
195 """Voluptuous schema for KNX platform entity configuration."""
197 PLATFORM: ClassVar[Platform | str]
198 ENTITY_SCHEMA: ClassVar[vol.Schema | vol.All | vol.Any]
202 """Return a schema node for the platform."""
204 vol.Optional(
str(cls.PLATFORM)): vol.All(
205 cv.ensure_list, [cls.ENTITY_SCHEMA]
211 """Voluptuous schema for KNX binary sensors."""
213 PLATFORM = Platform.BINARY_SENSOR
215 CONF_STATE_ADDRESS = CONF_STATE_ADDRESS
216 CONF_SYNC_STATE = CONF_SYNC_STATE
217 CONF_INVERT = CONF_INVERT
218 CONF_IGNORE_INTERNAL_STATE =
"ignore_internal_state"
219 CONF_CONTEXT_TIMEOUT =
"context_timeout"
220 CONF_RESET_AFTER = CONF_RESET_AFTER
222 DEFAULT_NAME =
"KNX Binary Sensor"
224 ENTITY_SCHEMA = vol.All(
227 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
228 vol.Optional(CONF_SYNC_STATE, default=
True): sync_state_validator,
229 vol.Optional(CONF_IGNORE_INTERNAL_STATE, default=
False): cv.boolean,
230 vol.Optional(CONF_INVERT, default=
False): cv.boolean,
231 vol.Required(CONF_STATE_ADDRESS): ga_list_validator,
232 vol.Optional(CONF_CONTEXT_TIMEOUT): vol.All(
233 vol.Coerce(float), vol.Range(min=0, max=10)
235 vol.Optional(CONF_DEVICE_CLASS): BINARY_SENSOR_DEVICE_CLASSES_SCHEMA,
236 vol.Optional(CONF_RESET_AFTER): cv.positive_float,
237 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
244 """Voluptuous schema for KNX buttons."""
246 PLATFORM = Platform.BUTTON
249 DEFAULT_NAME =
"KNX Button"
251 payload_or_value_msg = f
"Please use only one of `{CONF_PAYLOAD}` or `{CONF_VALUE}`"
252 length_or_type_msg = (
253 f
"Please use only one of `{CONF_PAYLOAD_LENGTH}` or `{CONF_TYPE}`"
256 ENTITY_SCHEMA = vol.All(
259 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
260 vol.Required(KNX_ADDRESS): ga_validator,
262 CONF_PAYLOAD,
"payload_or_value", msg=payload_or_value_msg
265 CONF_VALUE,
"payload_or_value", msg=payload_or_value_msg
268 CONF_PAYLOAD_LENGTH,
"length_or_type", msg=length_or_type_msg
271 CONF_TYPE,
"length_or_type", msg=length_or_type_msg
273 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
280 vol.Required(CONF_VALUE): vol.Any(int, float, str),
281 vol.Required(CONF_TYPE): sensor_type_validator,
283 extra=vol.ALLOW_EXTRA,
288 vol.Optional(CONF_PAYLOAD, default=1): cv.positive_int,
289 vol.Optional(CONF_PAYLOAD_LENGTH, default=0): vol.All(
290 vol.Coerce(int), vol.Range(min=0, max=14)
292 vol.Optional(CONF_VALUE):
None,
293 vol.Optional(CONF_TYPE):
None,
295 extra=vol.ALLOW_EXTRA,
300 button_payload_sub_validator,
305 """Voluptuous schema for KNX climate devices."""
307 PLATFORM = Platform.CLIMATE
309 CONF_ACTIVE_STATE_ADDRESS =
"active_state_address"
310 CONF_SETPOINT_SHIFT_ADDRESS =
"setpoint_shift_address"
311 CONF_SETPOINT_SHIFT_STATE_ADDRESS =
"setpoint_shift_state_address"
312 CONF_SETPOINT_SHIFT_MODE =
"setpoint_shift_mode"
313 CONF_SETPOINT_SHIFT_MAX =
"setpoint_shift_max"
314 CONF_SETPOINT_SHIFT_MIN =
"setpoint_shift_min"
315 CONF_TEMPERATURE_ADDRESS =
"temperature_address"
316 CONF_TEMPERATURE_STEP =
"temperature_step"
317 CONF_TARGET_TEMPERATURE_ADDRESS =
"target_temperature_address"
318 CONF_TARGET_TEMPERATURE_STATE_ADDRESS =
"target_temperature_state_address"
319 CONF_OPERATION_MODE_ADDRESS =
"operation_mode_address"
320 CONF_OPERATION_MODE_STATE_ADDRESS =
"operation_mode_state_address"
321 CONF_CONTROLLER_STATUS_ADDRESS =
"controller_status_address"
322 CONF_CONTROLLER_STATUS_STATE_ADDRESS =
"controller_status_state_address"
323 CONF_CONTROLLER_MODE_ADDRESS =
"controller_mode_address"
324 CONF_CONTROLLER_MODE_STATE_ADDRESS =
"controller_mode_state_address"
325 CONF_COMMAND_VALUE_STATE_ADDRESS =
"command_value_state_address"
326 CONF_HEAT_COOL_ADDRESS =
"heat_cool_address"
327 CONF_HEAT_COOL_STATE_ADDRESS =
"heat_cool_state_address"
328 CONF_OPERATION_MODE_FROST_PROTECTION_ADDRESS = (
329 "operation_mode_frost_protection_address"
331 CONF_OPERATION_MODE_NIGHT_ADDRESS =
"operation_mode_night_address"
332 CONF_OPERATION_MODE_COMFORT_ADDRESS =
"operation_mode_comfort_address"
333 CONF_OPERATION_MODE_STANDBY_ADDRESS =
"operation_mode_standby_address"
334 CONF_OPERATION_MODES =
"operation_modes"
335 CONF_CONTROLLER_MODES =
"controller_modes"
336 CONF_DEFAULT_CONTROLLER_MODE =
"default_controller_mode"
337 CONF_ON_OFF_ADDRESS =
"on_off_address"
338 CONF_ON_OFF_STATE_ADDRESS =
"on_off_state_address"
339 CONF_ON_OFF_INVERT =
"on_off_invert"
340 CONF_MIN_TEMP =
"min_temp"
341 CONF_MAX_TEMP =
"max_temp"
342 CONF_FAN_SPEED_ADDRESS =
"fan_speed_address"
343 CONF_FAN_SPEED_STATE_ADDRESS =
"fan_speed_state_address"
344 CONF_FAN_MAX_STEP =
"fan_max_step"
345 CONF_FAN_SPEED_MODE =
"fan_speed_mode"
346 CONF_FAN_ZERO_MODE =
"fan_zero_mode"
347 CONF_HUMIDITY_STATE_ADDRESS =
"humidity_state_address"
349 DEFAULT_NAME =
"KNX Climate"
350 DEFAULT_SETPOINT_SHIFT_MODE =
"DPT6010"
351 DEFAULT_SETPOINT_SHIFT_MAX = 6
352 DEFAULT_SETPOINT_SHIFT_MIN = -6
353 DEFAULT_TEMPERATURE_STEP = 0.1
354 DEFAULT_ON_OFF_INVERT =
False
355 DEFAULT_FAN_SPEED_MODE =
"percent"
357 ENTITY_SCHEMA = vol.All(
360 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
362 CONF_SETPOINT_SHIFT_MAX, default=DEFAULT_SETPOINT_SHIFT_MAX
363 ): vol.All(int, vol.Range(min=0, max=32)),
365 CONF_SETPOINT_SHIFT_MIN, default=DEFAULT_SETPOINT_SHIFT_MIN
366 ): vol.All(int, vol.Range(min=-32, max=0)),
368 CONF_TEMPERATURE_STEP, default=DEFAULT_TEMPERATURE_STEP
369 ): vol.All(float, vol.Range(min=0, max=2)),
370 vol.Required(CONF_TEMPERATURE_ADDRESS): ga_list_validator,
371 vol.Required(CONF_TARGET_TEMPERATURE_STATE_ADDRESS): ga_list_validator,
372 vol.Optional(CONF_TARGET_TEMPERATURE_ADDRESS): ga_list_validator,
374 CONF_SETPOINT_SHIFT_ADDRESS,
377 "'setpoint_shift_address' and 'setpoint_shift_state_address' "
378 "are required for setpoint_shift configuration"
380 ): ga_list_validator,
382 CONF_SETPOINT_SHIFT_STATE_ADDRESS,
385 "'setpoint_shift_address' and 'setpoint_shift_state_address' "
386 "are required for setpoint_shift configuration"
388 ): ga_list_validator,
389 vol.Optional(CONF_SETPOINT_SHIFT_MODE): vol.Maybe(
390 vol.All(vol.Upper, cv.enum(SetpointShiftMode))
392 vol.Optional(CONF_ACTIVE_STATE_ADDRESS): ga_list_validator,
393 vol.Optional(CONF_COMMAND_VALUE_STATE_ADDRESS): ga_list_validator,
394 vol.Optional(CONF_OPERATION_MODE_ADDRESS): ga_list_validator,
395 vol.Optional(CONF_OPERATION_MODE_STATE_ADDRESS): ga_list_validator,
396 vol.Optional(CONF_CONTROLLER_STATUS_ADDRESS): ga_list_validator,
397 vol.Optional(CONF_CONTROLLER_STATUS_STATE_ADDRESS): ga_list_validator,
398 vol.Optional(CONF_CONTROLLER_MODE_ADDRESS): ga_list_validator,
399 vol.Optional(CONF_CONTROLLER_MODE_STATE_ADDRESS): ga_list_validator,
400 vol.Optional(CONF_HEAT_COOL_ADDRESS): ga_list_validator,
401 vol.Optional(CONF_HEAT_COOL_STATE_ADDRESS): ga_list_validator,
403 CONF_OPERATION_MODE_FROST_PROTECTION_ADDRESS
404 ): ga_list_validator,
405 vol.Optional(CONF_OPERATION_MODE_NIGHT_ADDRESS): ga_list_validator,
406 vol.Optional(CONF_OPERATION_MODE_COMFORT_ADDRESS): ga_list_validator,
407 vol.Optional(CONF_OPERATION_MODE_STANDBY_ADDRESS): ga_list_validator,
408 vol.Optional(CONF_ON_OFF_ADDRESS): ga_list_validator,
409 vol.Optional(CONF_ON_OFF_STATE_ADDRESS): ga_list_validator,
411 CONF_ON_OFF_INVERT, default=DEFAULT_ON_OFF_INVERT
413 vol.Optional(CONF_OPERATION_MODES): vol.All(
417 vol.Optional(CONF_CONTROLLER_MODES): vol.All(
422 CONF_DEFAULT_CONTROLLER_MODE, default=HVACMode.HEAT
423 ): vol.Coerce(HVACMode),
424 vol.Optional(CONF_MIN_TEMP): vol.Coerce(float),
425 vol.Optional(CONF_MAX_TEMP): vol.Coerce(float),
426 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
427 vol.Optional(CONF_FAN_SPEED_ADDRESS): ga_list_validator,
428 vol.Optional(CONF_FAN_SPEED_STATE_ADDRESS): ga_list_validator,
429 vol.Optional(CONF_FAN_MAX_STEP, default=3): cv.byte,
431 CONF_FAN_SPEED_MODE, default=DEFAULT_FAN_SPEED_MODE
432 ): vol.All(vol.Upper, cv.enum(FanSpeedMode)),
433 vol.Optional(CONF_FAN_ZERO_MODE, default=FAN_OFF): vol.Coerce(
436 vol.Optional(CONF_HUMIDITY_STATE_ADDRESS): ga_list_validator,
443 """Voluptuous schema for KNX covers."""
445 PLATFORM = Platform.COVER
447 CONF_MOVE_LONG_ADDRESS =
"move_long_address"
448 CONF_MOVE_SHORT_ADDRESS =
"move_short_address"
449 CONF_STOP_ADDRESS =
"stop_address"
450 CONF_POSITION_ADDRESS =
"position_address"
451 CONF_POSITION_STATE_ADDRESS =
"position_state_address"
452 CONF_ANGLE_ADDRESS =
"angle_address"
453 CONF_ANGLE_STATE_ADDRESS =
"angle_state_address"
454 CONF_TRAVELLING_TIME_DOWN =
"travelling_time_down"
455 CONF_TRAVELLING_TIME_UP =
"travelling_time_up"
456 CONF_INVERT_UPDOWN =
"invert_updown"
457 CONF_INVERT_POSITION =
"invert_position"
458 CONF_INVERT_ANGLE =
"invert_angle"
460 DEFAULT_TRAVEL_TIME = 25
461 DEFAULT_NAME =
"KNX Cover"
463 ENTITY_SCHEMA = vol.All(
466 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
467 vol.Optional(CONF_MOVE_LONG_ADDRESS): ga_list_validator,
468 vol.Optional(CONF_MOVE_SHORT_ADDRESS): ga_list_validator,
469 vol.Optional(CONF_STOP_ADDRESS): ga_list_validator,
470 vol.Optional(CONF_POSITION_ADDRESS): ga_list_validator,
471 vol.Optional(CONF_POSITION_STATE_ADDRESS): ga_list_validator,
472 vol.Optional(CONF_ANGLE_ADDRESS): ga_list_validator,
473 vol.Optional(CONF_ANGLE_STATE_ADDRESS): ga_list_validator,
475 CONF_TRAVELLING_TIME_DOWN, default=DEFAULT_TRAVEL_TIME
476 ): cv.positive_float,
478 CONF_TRAVELLING_TIME_UP, default=DEFAULT_TRAVEL_TIME
479 ): cv.positive_float,
480 vol.Optional(CONF_INVERT_UPDOWN, default=
False): cv.boolean,
481 vol.Optional(CONF_INVERT_POSITION, default=
False): cv.boolean,
482 vol.Optional(CONF_INVERT_ANGLE, default=
False): cv.boolean,
483 vol.Optional(CONF_DEVICE_CLASS): COVER_DEVICE_CLASSES_SCHEMA,
484 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
489 {vol.Required(CONF_MOVE_LONG_ADDRESS): object},
490 extra=vol.ALLOW_EXTRA,
493 {vol.Required(CONF_POSITION_ADDRESS): object},
494 extra=vol.ALLOW_EXTRA,
497 f
"At least one of '{CONF_MOVE_LONG_ADDRESS}' or"
498 f
" '{CONF_POSITION_ADDRESS}' is required."
505 """Voluptuous schema for KNX date."""
507 PLATFORM = Platform.DATE
509 DEFAULT_NAME =
"KNX Date"
511 ENTITY_SCHEMA = vol.Schema(
513 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
514 vol.Optional(CONF_RESPOND_TO_READ, default=
False): cv.boolean,
515 vol.Optional(CONF_SYNC_STATE, default=
True): sync_state_validator,
516 vol.Required(KNX_ADDRESS): ga_list_validator,
517 vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
518 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
524 """Voluptuous schema for KNX date."""
526 PLATFORM = Platform.DATETIME
528 DEFAULT_NAME =
"KNX DateTime"
530 ENTITY_SCHEMA = vol.Schema(
532 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
533 vol.Optional(CONF_RESPOND_TO_READ, default=
False): cv.boolean,
534 vol.Optional(CONF_SYNC_STATE, default=
True): sync_state_validator,
535 vol.Required(KNX_ADDRESS): ga_list_validator,
536 vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
537 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
543 """Voluptuous schema for KNX exposures."""
545 PLATFORM = CONF_KNX_EXPOSE
547 CONF_KNX_EXPOSE_TYPE = CONF_TYPE
548 CONF_KNX_EXPOSE_ATTRIBUTE =
"attribute"
549 CONF_KNX_EXPOSE_BINARY =
"binary"
550 CONF_KNX_EXPOSE_COOLDOWN =
"cooldown"
551 CONF_KNX_EXPOSE_DEFAULT =
"default"
554 CONF_DATETIME =
"datetime"
555 EXPOSE_TIME_TYPES: Final = [CONF_TIME, CONF_DATE, CONF_DATETIME]
557 EXPOSE_TIME_SCHEMA = vol.Schema(
559 vol.Required(CONF_KNX_EXPOSE_TYPE): vol.All(
560 cv.string, str.lower, vol.In(EXPOSE_TIME_TYPES)
562 vol.Required(KNX_ADDRESS): ga_validator,
565 EXPOSE_SENSOR_SCHEMA = vol.Schema(
567 vol.Optional(CONF_KNX_EXPOSE_COOLDOWN, default=0): cv.positive_float,
568 vol.Optional(CONF_RESPOND_TO_READ, default=
True): cv.boolean,
569 vol.Required(CONF_KNX_EXPOSE_TYPE): vol.Any(
570 CONF_KNX_EXPOSE_BINARY, sensor_type_validator
572 vol.Required(KNX_ADDRESS): ga_validator,
573 vol.Required(CONF_ENTITY_ID): cv.entity_id,
574 vol.Optional(CONF_KNX_EXPOSE_ATTRIBUTE): cv.string,
575 vol.Optional(CONF_KNX_EXPOSE_DEFAULT): cv.match_all,
576 vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
579 ENTITY_SCHEMA = vol.Any(EXPOSE_SENSOR_SCHEMA, EXPOSE_TIME_SCHEMA)
583 """Voluptuous schema for KNX fans."""
585 PLATFORM = Platform.FAN
587 CONF_STATE_ADDRESS = CONF_STATE_ADDRESS
588 CONF_OSCILLATION_ADDRESS =
"oscillation_address"
589 CONF_OSCILLATION_STATE_ADDRESS =
"oscillation_state_address"
590 CONF_MAX_STEP =
"max_step"
592 DEFAULT_NAME =
"KNX Fan"
594 ENTITY_SCHEMA = vol.Schema(
596 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
597 vol.Required(KNX_ADDRESS): ga_list_validator,
598 vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
599 vol.Optional(CONF_OSCILLATION_ADDRESS): ga_list_validator,
600 vol.Optional(CONF_OSCILLATION_STATE_ADDRESS): ga_list_validator,
601 vol.Optional(CONF_MAX_STEP): cv.byte,
602 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
608 """Voluptuous schema for KNX lights."""
610 PLATFORM = Platform.LIGHT
612 CONF_STATE_ADDRESS = CONF_STATE_ADDRESS
613 CONF_BRIGHTNESS_ADDRESS =
"brightness_address"
614 CONF_BRIGHTNESS_STATE_ADDRESS =
"brightness_state_address"
615 CONF_COLOR_ADDRESS =
"color_address"
616 CONF_COLOR_STATE_ADDRESS =
"color_state_address"
617 CONF_COLOR_TEMP_ADDRESS =
"color_temperature_address"
618 CONF_COLOR_TEMP_STATE_ADDRESS =
"color_temperature_state_address"
619 CONF_COLOR_TEMP_MODE =
"color_temperature_mode"
620 CONF_HUE_ADDRESS =
"hue_address"
621 CONF_HUE_STATE_ADDRESS =
"hue_state_address"
622 CONF_RGBW_ADDRESS =
"rgbw_address"
623 CONF_RGBW_STATE_ADDRESS =
"rgbw_state_address"
624 CONF_SATURATION_ADDRESS =
"saturation_address"
625 CONF_SATURATION_STATE_ADDRESS =
"saturation_state_address"
626 CONF_XYY_ADDRESS =
"xyy_address"
627 CONF_XYY_STATE_ADDRESS =
"xyy_state_address"
628 CONF_MIN_KELVIN =
"min_kelvin"
629 CONF_MAX_KELVIN =
"max_kelvin"
631 DEFAULT_NAME =
"KNX Light"
632 DEFAULT_COLOR_TEMP_MODE =
"absolute"
633 DEFAULT_MIN_KELVIN = 2700
634 DEFAULT_MAX_KELVIN = 6000
636 CONF_INDIVIDUAL_COLORS =
"individual_colors"
642 _hs_color_inclusion_msg = (
643 "'hue_address', 'saturation_address' and 'brightness_address'"
644 " are required for hs_color configuration"
647 vol.Optional(CONF_HUE_ADDRESS): ga_list_validator,
648 vol.Optional(CONF_HUE_STATE_ADDRESS): ga_list_validator,
649 vol.Optional(CONF_SATURATION_ADDRESS): ga_list_validator,
650 vol.Optional(CONF_SATURATION_STATE_ADDRESS): ga_list_validator,
653 INDIVIDUAL_COLOR_SCHEMA = vol.Schema(
655 vol.Optional(KNX_ADDRESS): ga_list_validator,
656 vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
657 vol.Required(CONF_BRIGHTNESS_ADDRESS): ga_list_validator,
658 vol.Optional(CONF_BRIGHTNESS_STATE_ADDRESS): ga_list_validator,
662 ENTITY_SCHEMA = vol.All(
665 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
666 vol.Optional(KNX_ADDRESS): ga_list_validator,
667 vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
668 vol.Optional(CONF_BRIGHTNESS_ADDRESS): ga_list_validator,
669 vol.Optional(CONF_BRIGHTNESS_STATE_ADDRESS): ga_list_validator,
670 vol.Exclusive(CONF_INDIVIDUAL_COLORS,
"color"): {
675 "'red', 'green' and 'blue' are required for individual"
676 " colors configuration"
678 ): INDIVIDUAL_COLOR_SCHEMA,
683 "'red', 'green' and 'blue' are required for individual"
684 " colors configuration"
686 ): INDIVIDUAL_COLOR_SCHEMA,
691 "'red', 'green' and 'blue' are required for individual"
692 " colors configuration"
694 ): INDIVIDUAL_COLOR_SCHEMA,
695 vol.Optional(CONF_WHITE): INDIVIDUAL_COLOR_SCHEMA,
697 vol.Exclusive(CONF_COLOR_ADDRESS,
"color"): ga_list_validator,
698 vol.Optional(CONF_COLOR_STATE_ADDRESS): ga_list_validator,
699 vol.Optional(CONF_COLOR_TEMP_ADDRESS): ga_list_validator,
700 vol.Optional(CONF_COLOR_TEMP_STATE_ADDRESS): ga_list_validator,
702 CONF_COLOR_TEMP_MODE, default=DEFAULT_COLOR_TEMP_MODE
703 ): vol.All(vol.Upper, cv.enum(ColorTempModes)),
705 vol.Exclusive(CONF_RGBW_ADDRESS,
"color"): ga_list_validator,
706 vol.Optional(CONF_RGBW_STATE_ADDRESS): ga_list_validator,
707 vol.Exclusive(CONF_XYY_ADDRESS,
"color"): ga_list_validator,
708 vol.Optional(CONF_XYY_STATE_ADDRESS): ga_list_validator,
709 vol.Optional(CONF_MIN_KELVIN, default=DEFAULT_MIN_KELVIN): vol.All(
710 vol.Coerce(int), vol.Range(min=1)
712 vol.Optional(CONF_MAX_KELVIN, default=DEFAULT_MAX_KELVIN): vol.All(
713 vol.Coerce(int), vol.Range(min=1)
715 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
720 {vol.Required(KNX_ADDRESS): object},
721 extra=vol.ALLOW_EXTRA,
724 {vol.Required(CONF_INDIVIDUAL_COLORS): object},
725 extra=vol.ALLOW_EXTRA,
727 msg=
"either 'address' or 'individual_colors' is required",
733 CONF_BRIGHTNESS_ADDRESS,
"hs_color", msg=_hs_color_inclusion_msg
736 CONF_HUE_ADDRESS,
"hs_color", msg=_hs_color_inclusion_msg
739 CONF_SATURATION_ADDRESS,
"hs_color", msg=_hs_color_inclusion_msg
742 extra=vol.ALLOW_EXTRA,
746 vol.Optional(CONF_HUE_ADDRESS):
None,
747 vol.Optional(CONF_SATURATION_ADDRESS):
None,
749 extra=vol.ALLOW_EXTRA,
751 msg=_hs_color_inclusion_msg,
757 """Voluptuous schema for KNX notifications."""
759 PLATFORM = Platform.NOTIFY
761 DEFAULT_NAME =
"KNX Notify"
763 ENTITY_SCHEMA = vol.Schema(
765 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
766 vol.Optional(CONF_TYPE, default=
"latin_1"): string_type_validator,
767 vol.Required(KNX_ADDRESS): ga_validator,
768 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
774 """Voluptuous schema for KNX numbers."""
776 PLATFORM = Platform.NUMBER
781 DEFAULT_NAME =
"KNX Number"
783 ENTITY_SCHEMA = vol.All(
786 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
787 vol.Optional(CONF_RESPOND_TO_READ, default=
False): cv.boolean,
788 vol.Optional(CONF_MODE, default=NumberMode.AUTO): vol.Coerce(
791 vol.Required(CONF_TYPE): numeric_type_validator,
792 vol.Required(KNX_ADDRESS): ga_list_validator,
793 vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
794 vol.Optional(CONF_MAX): vol.Coerce(float),
795 vol.Optional(CONF_MIN): vol.Coerce(float),
796 vol.Optional(CONF_STEP): cv.positive_float,
797 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
800 number_limit_sub_validator,
805 """Voluptuous schema for KNX scenes."""
807 PLATFORM = Platform.SCENE
809 CONF_SCENE_NUMBER =
"scene_number"
811 DEFAULT_NAME =
"KNX SCENE"
812 ENTITY_SCHEMA = vol.Schema(
814 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
815 vol.Required(KNX_ADDRESS): ga_list_validator,
816 vol.Required(CONF_SCENE_NUMBER): vol.All(
817 vol.Coerce(int), vol.Range(min=1, max=64)
819 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
825 """Voluptuous schema for KNX selects."""
827 PLATFORM = Platform.SELECT
829 CONF_OPTION =
"option"
830 CONF_OPTIONS =
"options"
831 DEFAULT_NAME =
"KNX Select"
833 ENTITY_SCHEMA = vol.All(
836 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
837 vol.Optional(CONF_SYNC_STATE, default=
True): sync_state_validator,
838 vol.Optional(CONF_RESPOND_TO_READ, default=
False): cv.boolean,
839 vol.Required(CONF_PAYLOAD_LENGTH): vol.All(
840 vol.Coerce(int), vol.Range(min=0, max=14)
842 vol.Required(CONF_OPTIONS): [
844 vol.Required(CONF_OPTION): vol.Coerce(str),
845 vol.Required(CONF_PAYLOAD): cv.positive_int,
848 vol.Required(KNX_ADDRESS): ga_list_validator,
849 vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
850 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
853 select_options_sub_validator,
858 """Voluptuous schema for KNX sensors."""
860 PLATFORM = Platform.SENSOR
862 CONF_ALWAYS_CALLBACK =
"always_callback"
863 CONF_STATE_ADDRESS = CONF_STATE_ADDRESS
864 CONF_SYNC_STATE = CONF_SYNC_STATE
865 DEFAULT_NAME =
"KNX Sensor"
867 ENTITY_SCHEMA = vol.Schema(
869 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
870 vol.Optional(CONF_SYNC_STATE, default=
True): sync_state_validator,
871 vol.Optional(CONF_ALWAYS_CALLBACK, default=
False): cv.boolean,
872 vol.Optional(CONF_STATE_CLASS): STATE_CLASSES_SCHEMA,
873 vol.Required(CONF_TYPE): sensor_type_validator,
874 vol.Required(CONF_STATE_ADDRESS): ga_list_validator,
875 vol.Optional(CONF_DEVICE_CLASS): SENSOR_DEVICE_CLASSES_SCHEMA,
876 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
882 """Voluptuous schema for KNX switches."""
884 PLATFORM = Platform.SWITCH
886 CONF_INVERT = CONF_INVERT
887 CONF_STATE_ADDRESS = CONF_STATE_ADDRESS
889 DEFAULT_NAME =
"KNX Switch"
890 ENTITY_SCHEMA = vol.Schema(
892 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
893 vol.Optional(CONF_INVERT, default=
False): cv.boolean,
894 vol.Optional(CONF_RESPOND_TO_READ, default=
False): cv.boolean,
895 vol.Required(KNX_ADDRESS): ga_list_validator,
896 vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
897 vol.Optional(CONF_DEVICE_CLASS): SWITCH_DEVICE_CLASSES_SCHEMA,
898 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
904 """Voluptuous schema for KNX text."""
906 PLATFORM = Platform.TEXT
908 DEFAULT_NAME =
"KNX Text"
910 ENTITY_SCHEMA = vol.Schema(
912 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
913 vol.Optional(CONF_RESPOND_TO_READ, default=
False): cv.boolean,
914 vol.Optional(CONF_TYPE, default=
"latin_1"): string_type_validator,
915 vol.Optional(CONF_MODE, default=TextMode.TEXT): vol.Coerce(TextMode),
916 vol.Required(KNX_ADDRESS): ga_list_validator,
917 vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
918 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
924 """Voluptuous schema for KNX time."""
926 PLATFORM = Platform.TIME
928 DEFAULT_NAME =
"KNX Time"
930 ENTITY_SCHEMA = vol.Schema(
932 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
933 vol.Optional(CONF_RESPOND_TO_READ, default=
False): cv.boolean,
934 vol.Optional(CONF_SYNC_STATE, default=
True): sync_state_validator,
935 vol.Required(KNX_ADDRESS): ga_list_validator,
936 vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
937 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
943 """Voluptuous schema for KNX weather station."""
945 PLATFORM = Platform.WEATHER
947 CONF_SYNC_STATE = CONF_SYNC_STATE
948 CONF_KNX_TEMPERATURE_ADDRESS =
"address_temperature"
949 CONF_KNX_BRIGHTNESS_SOUTH_ADDRESS =
"address_brightness_south"
950 CONF_KNX_BRIGHTNESS_EAST_ADDRESS =
"address_brightness_east"
951 CONF_KNX_BRIGHTNESS_WEST_ADDRESS =
"address_brightness_west"
952 CONF_KNX_BRIGHTNESS_NORTH_ADDRESS =
"address_brightness_north"
953 CONF_KNX_WIND_SPEED_ADDRESS =
"address_wind_speed"
954 CONF_KNX_WIND_BEARING_ADDRESS =
"address_wind_bearing"
955 CONF_KNX_RAIN_ALARM_ADDRESS =
"address_rain_alarm"
956 CONF_KNX_FROST_ALARM_ADDRESS =
"address_frost_alarm"
957 CONF_KNX_WIND_ALARM_ADDRESS =
"address_wind_alarm"
958 CONF_KNX_DAY_NIGHT_ADDRESS =
"address_day_night"
959 CONF_KNX_AIR_PRESSURE_ADDRESS =
"address_air_pressure"
960 CONF_KNX_HUMIDITY_ADDRESS =
"address_humidity"
962 DEFAULT_NAME =
"KNX Weather Station"
964 ENTITY_SCHEMA = vol.All(
967 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
968 vol.Optional(CONF_SYNC_STATE, default=
True): sync_state_validator,
969 vol.Required(CONF_KNX_TEMPERATURE_ADDRESS): ga_list_validator,
970 vol.Optional(CONF_KNX_BRIGHTNESS_SOUTH_ADDRESS): ga_list_validator,
971 vol.Optional(CONF_KNX_BRIGHTNESS_EAST_ADDRESS): ga_list_validator,
972 vol.Optional(CONF_KNX_BRIGHTNESS_WEST_ADDRESS): ga_list_validator,
973 vol.Optional(CONF_KNX_BRIGHTNESS_NORTH_ADDRESS): ga_list_validator,
974 vol.Optional(CONF_KNX_WIND_SPEED_ADDRESS): ga_list_validator,
975 vol.Optional(CONF_KNX_WIND_BEARING_ADDRESS): ga_list_validator,
976 vol.Optional(CONF_KNX_RAIN_ALARM_ADDRESS): ga_list_validator,
977 vol.Optional(CONF_KNX_FROST_ALARM_ADDRESS): ga_list_validator,
978 vol.Optional(CONF_KNX_WIND_ALARM_ADDRESS): ga_list_validator,
979 vol.Optional(CONF_KNX_DAY_NIGHT_ADDRESS): ga_list_validator,
980 vol.Optional(CONF_KNX_AIR_PRESSURE_ADDRESS): ga_list_validator,
981 vol.Optional(CONF_KNX_HUMIDITY_ADDRESS): ga_list_validator,
982 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
OrderedDict number_limit_sub_validator(OrderedDict entity_config)
KNX SUB VALIDATORS.
OrderedDict select_options_sub_validator(OrderedDict entity_config)
OrderedDict button_payload_sub_validator(OrderedDict entity_config)
int _max_payload_value(int payload_length)
vol.All backwards_compatible_xknx_climate_enum_member(type[Enum] enumClass)