Home Assistant Unofficial Reference 2024.12.1
entity_store_schema.py
Go to the documentation of this file.
1 """KNX entity store schema."""
2 
3 from enum import StrEnum, unique
4 
5 import voluptuous as vol
6 
7 from homeassistant.const import (
8  CONF_ENTITY_CATEGORY,
9  CONF_ENTITY_ID,
10  CONF_NAME,
11  CONF_PLATFORM,
12  Platform,
13 )
14 from homeassistant.helpers import config_validation as cv
15 from homeassistant.helpers.entity import ENTITY_CATEGORIES_SCHEMA
16 from homeassistant.helpers.typing import VolDictType, VolSchemaType
17 
18 from ..const import (
19  CONF_INVERT,
20  CONF_RESPOND_TO_READ,
21  CONF_SYNC_STATE,
22  DOMAIN,
23  SUPPORTED_PLATFORMS_UI,
24  ColorTempModes,
25 )
26 from ..validation import sync_state_validator
27 from .const import (
28  CONF_COLOR_TEMP_MAX,
29  CONF_COLOR_TEMP_MIN,
30  CONF_DATA,
31  CONF_DEVICE_INFO,
32  CONF_ENTITY,
33  CONF_GA_BLUE_BRIGHTNESS,
34  CONF_GA_BLUE_SWITCH,
35  CONF_GA_BRIGHTNESS,
36  CONF_GA_COLOR,
37  CONF_GA_COLOR_TEMP,
38  CONF_GA_GREEN_BRIGHTNESS,
39  CONF_GA_GREEN_SWITCH,
40  CONF_GA_HUE,
41  CONF_GA_PASSIVE,
42  CONF_GA_RED_BRIGHTNESS,
43  CONF_GA_RED_SWITCH,
44  CONF_GA_SATURATION,
45  CONF_GA_STATE,
46  CONF_GA_SWITCH,
47  CONF_GA_WHITE_BRIGHTNESS,
48  CONF_GA_WHITE_SWITCH,
49  CONF_GA_WRITE,
50 )
51 from .knx_selector import GASelector
52 
53 BASE_ENTITY_SCHEMA = vol.All(
54  {
55  vol.Optional(CONF_NAME, default=None): vol.Maybe(str),
56  vol.Optional(CONF_DEVICE_INFO, default=None): vol.Maybe(str),
57  vol.Optional(CONF_ENTITY_CATEGORY, default=None): vol.Any(
58  ENTITY_CATEGORIES_SCHEMA, vol.SetTo(None)
59  ),
60  },
61  vol.Any(
62  vol.Schema(
63  {
64  vol.Required(CONF_NAME): vol.All(str, vol.IsTrue()),
65  },
66  extra=vol.ALLOW_EXTRA,
67  ),
68  vol.Schema(
69  {
70  vol.Required(CONF_DEVICE_INFO): str,
71  },
72  extra=vol.ALLOW_EXTRA,
73  ),
74  msg="One of `Device` or `Name` is required",
75  ),
76 )
77 
78 
79 def optional_ga_schema(key: str, ga_selector: GASelector) -> VolDictType:
80  """Validate group address schema or remove key if no address is set."""
81  # frontend will return {key: {"write": None, "state": None}} for unused GA sets
82  # -> remove this entirely for optional keys
83  # if one GA is set, validate as usual
84  return {
85  vol.Optional(key): ga_selector,
86  vol.Remove(key): vol.Schema(
87  {
88  vol.Optional(CONF_GA_WRITE): None,
89  vol.Optional(CONF_GA_STATE): None,
90  vol.Optional(CONF_GA_PASSIVE): vol.IsFalse(), # None or empty list
91  },
92  extra=vol.ALLOW_EXTRA,
93  ),
94  }
95 
96 
97 SWITCH_SCHEMA = vol.Schema(
98  {
99  vol.Required(CONF_ENTITY): BASE_ENTITY_SCHEMA,
100  vol.Required(DOMAIN): {
101  vol.Optional(CONF_INVERT, default=False): bool,
102  vol.Required(CONF_GA_SWITCH): GASelector(write_required=True),
103  vol.Optional(CONF_RESPOND_TO_READ, default=False): bool,
104  vol.Optional(CONF_SYNC_STATE, default=True): sync_state_validator,
105  },
106  }
107 )
108 
109 
110 @unique
111 class LightColorMode(StrEnum):
112  """Enum for light color mode."""
113 
114  RGB = "232.600"
115  RGBW = "251.600"
116  XYY = "242.600"
117 
118 
119 @unique
120 class LightColorModeSchema(StrEnum):
121  """Enum for light color mode."""
122 
123  DEFAULT = "default"
124  INDIVIDUAL = "individual"
125  HSV = "hsv"
126 
127 
128 _LIGHT_COLOR_MODE_SCHEMA = "_light_color_mode_schema"
129 
130 _COMMON_LIGHT_SCHEMA = vol.Schema(
131  {
132  vol.Optional(CONF_SYNC_STATE, default=True): sync_state_validator,
134  CONF_GA_COLOR_TEMP, GASelector(write_required=True, dpt=ColorTempModes)
135  ),
136  vol.Optional(CONF_COLOR_TEMP_MIN, default=2700): vol.All(
137  vol.Coerce(int), vol.Range(min=1)
138  ),
139  vol.Optional(CONF_COLOR_TEMP_MAX, default=6000): vol.All(
140  vol.Coerce(int), vol.Range(min=1)
141  ),
142  },
143  extra=vol.REMOVE_EXTRA,
144 )
145 
146 _DEFAULT_LIGHT_SCHEMA = _COMMON_LIGHT_SCHEMA.extend(
147  {
148  vol.Required(_LIGHT_COLOR_MODE_SCHEMA): LightColorModeSchema.DEFAULT.value,
149  vol.Required(CONF_GA_SWITCH): GASelector(write_required=True),
150  **optional_ga_schema(CONF_GA_BRIGHTNESS, GASelector(write_required=True)),
152  CONF_GA_COLOR,
153  GASelector(write_required=True, dpt=LightColorMode),
154  ),
155  }
156 )
157 
158 _INDIVIDUAL_LIGHT_SCHEMA = _COMMON_LIGHT_SCHEMA.extend(
159  {
160  vol.Required(_LIGHT_COLOR_MODE_SCHEMA): LightColorModeSchema.INDIVIDUAL.value,
161  **optional_ga_schema(CONF_GA_SWITCH, GASelector(write_required=True)),
162  **optional_ga_schema(CONF_GA_BRIGHTNESS, GASelector(write_required=True)),
163  vol.Required(CONF_GA_RED_BRIGHTNESS): GASelector(write_required=True),
164  **optional_ga_schema(CONF_GA_RED_SWITCH, GASelector(write_required=False)),
165  vol.Required(CONF_GA_GREEN_BRIGHTNESS): GASelector(write_required=True),
166  **optional_ga_schema(CONF_GA_GREEN_SWITCH, GASelector(write_required=False)),
167  vol.Required(CONF_GA_BLUE_BRIGHTNESS): GASelector(write_required=True),
168  **optional_ga_schema(CONF_GA_BLUE_SWITCH, GASelector(write_required=False)),
169  **optional_ga_schema(CONF_GA_WHITE_BRIGHTNESS, GASelector(write_required=True)),
170  **optional_ga_schema(CONF_GA_WHITE_SWITCH, GASelector(write_required=False)),
171  }
172 )
173 
174 _HSV_LIGHT_SCHEMA = _COMMON_LIGHT_SCHEMA.extend(
175  {
176  vol.Required(_LIGHT_COLOR_MODE_SCHEMA): LightColorModeSchema.HSV.value,
177  vol.Required(CONF_GA_SWITCH): GASelector(write_required=True),
178  vol.Required(CONF_GA_BRIGHTNESS): GASelector(write_required=True),
179  vol.Required(CONF_GA_HUE): GASelector(write_required=True),
180  vol.Required(CONF_GA_SATURATION): GASelector(write_required=True),
181  }
182 )
183 
184 
185 LIGHT_KNX_SCHEMA = cv.key_value_schemas(
186  _LIGHT_COLOR_MODE_SCHEMA,
187  default_schema=_DEFAULT_LIGHT_SCHEMA,
188  value_schemas={
189  LightColorModeSchema.DEFAULT: _DEFAULT_LIGHT_SCHEMA,
190  LightColorModeSchema.INDIVIDUAL: _INDIVIDUAL_LIGHT_SCHEMA,
191  LightColorModeSchema.HSV: _HSV_LIGHT_SCHEMA,
192  },
193 )
194 
195 LIGHT_SCHEMA = vol.Schema(
196  {
197  vol.Required(CONF_ENTITY): BASE_ENTITY_SCHEMA,
198  vol.Required(DOMAIN): LIGHT_KNX_SCHEMA,
199  }
200 )
201 
202 ENTITY_STORE_DATA_SCHEMA: VolSchemaType = vol.All(
203  vol.Schema(
204  {
205  vol.Required(CONF_PLATFORM): vol.All(
206  vol.Coerce(Platform),
207  vol.In(SUPPORTED_PLATFORMS_UI),
208  ),
209  vol.Required(CONF_DATA): dict,
210  },
211  extra=vol.ALLOW_EXTRA,
212  ),
213  cv.key_value_schemas(
214  CONF_PLATFORM,
215  {
216  Platform.SWITCH: vol.Schema(
217  {vol.Required(CONF_DATA): SWITCH_SCHEMA}, extra=vol.ALLOW_EXTRA
218  ),
219  Platform.LIGHT: vol.Schema(
220  {vol.Required("data"): LIGHT_SCHEMA}, extra=vol.ALLOW_EXTRA
221  ),
222  },
223  ),
224 )
225 
226 CREATE_ENTITY_BASE_SCHEMA: VolDictType = {
227  vol.Required(CONF_PLATFORM): str,
228  vol.Required(CONF_DATA): dict, # validated by ENTITY_STORE_DATA_SCHEMA for platform
229 }
230 
231 UPDATE_ENTITY_BASE_SCHEMA = {
232  vol.Required(CONF_ENTITY_ID): str,
233  **CREATE_ENTITY_BASE_SCHEMA,
234 }
VolDictType optional_ga_schema(str key, GASelector ga_selector)