aiohomematic 2026.1.29__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. aiohomematic/__init__.py +110 -0
  2. aiohomematic/_log_context_protocol.py +29 -0
  3. aiohomematic/api.py +410 -0
  4. aiohomematic/async_support.py +250 -0
  5. aiohomematic/backend_detection.py +462 -0
  6. aiohomematic/central/__init__.py +103 -0
  7. aiohomematic/central/async_rpc_server.py +760 -0
  8. aiohomematic/central/central_unit.py +1152 -0
  9. aiohomematic/central/config.py +463 -0
  10. aiohomematic/central/config_builder.py +772 -0
  11. aiohomematic/central/connection_state.py +160 -0
  12. aiohomematic/central/coordinators/__init__.py +38 -0
  13. aiohomematic/central/coordinators/cache.py +414 -0
  14. aiohomematic/central/coordinators/client.py +480 -0
  15. aiohomematic/central/coordinators/connection_recovery.py +1141 -0
  16. aiohomematic/central/coordinators/device.py +1166 -0
  17. aiohomematic/central/coordinators/event.py +514 -0
  18. aiohomematic/central/coordinators/hub.py +532 -0
  19. aiohomematic/central/decorators.py +184 -0
  20. aiohomematic/central/device_registry.py +229 -0
  21. aiohomematic/central/events/__init__.py +104 -0
  22. aiohomematic/central/events/bus.py +1392 -0
  23. aiohomematic/central/events/integration.py +424 -0
  24. aiohomematic/central/events/types.py +194 -0
  25. aiohomematic/central/health.py +762 -0
  26. aiohomematic/central/rpc_server.py +353 -0
  27. aiohomematic/central/scheduler.py +794 -0
  28. aiohomematic/central/state_machine.py +391 -0
  29. aiohomematic/client/__init__.py +203 -0
  30. aiohomematic/client/_rpc_errors.py +187 -0
  31. aiohomematic/client/backends/__init__.py +48 -0
  32. aiohomematic/client/backends/base.py +335 -0
  33. aiohomematic/client/backends/capabilities.py +138 -0
  34. aiohomematic/client/backends/ccu.py +487 -0
  35. aiohomematic/client/backends/factory.py +116 -0
  36. aiohomematic/client/backends/homegear.py +294 -0
  37. aiohomematic/client/backends/json_ccu.py +252 -0
  38. aiohomematic/client/backends/protocol.py +316 -0
  39. aiohomematic/client/ccu.py +1857 -0
  40. aiohomematic/client/circuit_breaker.py +459 -0
  41. aiohomematic/client/config.py +64 -0
  42. aiohomematic/client/handlers/__init__.py +40 -0
  43. aiohomematic/client/handlers/backup.py +157 -0
  44. aiohomematic/client/handlers/base.py +79 -0
  45. aiohomematic/client/handlers/device_ops.py +1085 -0
  46. aiohomematic/client/handlers/firmware.py +144 -0
  47. aiohomematic/client/handlers/link_mgmt.py +199 -0
  48. aiohomematic/client/handlers/metadata.py +436 -0
  49. aiohomematic/client/handlers/programs.py +144 -0
  50. aiohomematic/client/handlers/sysvars.py +100 -0
  51. aiohomematic/client/interface_client.py +1304 -0
  52. aiohomematic/client/json_rpc.py +2068 -0
  53. aiohomematic/client/request_coalescer.py +282 -0
  54. aiohomematic/client/rpc_proxy.py +629 -0
  55. aiohomematic/client/state_machine.py +324 -0
  56. aiohomematic/const.py +2207 -0
  57. aiohomematic/context.py +275 -0
  58. aiohomematic/converter.py +270 -0
  59. aiohomematic/decorators.py +390 -0
  60. aiohomematic/exceptions.py +185 -0
  61. aiohomematic/hmcli.py +997 -0
  62. aiohomematic/i18n.py +193 -0
  63. aiohomematic/interfaces/__init__.py +407 -0
  64. aiohomematic/interfaces/central.py +1067 -0
  65. aiohomematic/interfaces/client.py +1096 -0
  66. aiohomematic/interfaces/coordinators.py +63 -0
  67. aiohomematic/interfaces/model.py +1921 -0
  68. aiohomematic/interfaces/operations.py +217 -0
  69. aiohomematic/logging_context.py +134 -0
  70. aiohomematic/metrics/__init__.py +125 -0
  71. aiohomematic/metrics/_protocols.py +140 -0
  72. aiohomematic/metrics/aggregator.py +534 -0
  73. aiohomematic/metrics/dataclasses.py +489 -0
  74. aiohomematic/metrics/emitter.py +292 -0
  75. aiohomematic/metrics/events.py +183 -0
  76. aiohomematic/metrics/keys.py +300 -0
  77. aiohomematic/metrics/observer.py +563 -0
  78. aiohomematic/metrics/stats.py +172 -0
  79. aiohomematic/model/__init__.py +189 -0
  80. aiohomematic/model/availability.py +65 -0
  81. aiohomematic/model/calculated/__init__.py +89 -0
  82. aiohomematic/model/calculated/climate.py +276 -0
  83. aiohomematic/model/calculated/data_point.py +315 -0
  84. aiohomematic/model/calculated/field.py +147 -0
  85. aiohomematic/model/calculated/operating_voltage_level.py +286 -0
  86. aiohomematic/model/calculated/support.py +232 -0
  87. aiohomematic/model/custom/__init__.py +214 -0
  88. aiohomematic/model/custom/capabilities/__init__.py +67 -0
  89. aiohomematic/model/custom/capabilities/climate.py +41 -0
  90. aiohomematic/model/custom/capabilities/light.py +87 -0
  91. aiohomematic/model/custom/capabilities/lock.py +44 -0
  92. aiohomematic/model/custom/capabilities/siren.py +63 -0
  93. aiohomematic/model/custom/climate.py +1130 -0
  94. aiohomematic/model/custom/cover.py +722 -0
  95. aiohomematic/model/custom/data_point.py +360 -0
  96. aiohomematic/model/custom/definition.py +300 -0
  97. aiohomematic/model/custom/field.py +89 -0
  98. aiohomematic/model/custom/light.py +1174 -0
  99. aiohomematic/model/custom/lock.py +322 -0
  100. aiohomematic/model/custom/mixins.py +445 -0
  101. aiohomematic/model/custom/profile.py +945 -0
  102. aiohomematic/model/custom/registry.py +251 -0
  103. aiohomematic/model/custom/siren.py +462 -0
  104. aiohomematic/model/custom/switch.py +195 -0
  105. aiohomematic/model/custom/text_display.py +289 -0
  106. aiohomematic/model/custom/valve.py +78 -0
  107. aiohomematic/model/data_point.py +1416 -0
  108. aiohomematic/model/device.py +1840 -0
  109. aiohomematic/model/event.py +216 -0
  110. aiohomematic/model/generic/__init__.py +327 -0
  111. aiohomematic/model/generic/action.py +40 -0
  112. aiohomematic/model/generic/action_select.py +62 -0
  113. aiohomematic/model/generic/binary_sensor.py +30 -0
  114. aiohomematic/model/generic/button.py +31 -0
  115. aiohomematic/model/generic/data_point.py +177 -0
  116. aiohomematic/model/generic/dummy.py +150 -0
  117. aiohomematic/model/generic/number.py +76 -0
  118. aiohomematic/model/generic/select.py +56 -0
  119. aiohomematic/model/generic/sensor.py +76 -0
  120. aiohomematic/model/generic/switch.py +54 -0
  121. aiohomematic/model/generic/text.py +33 -0
  122. aiohomematic/model/hub/__init__.py +100 -0
  123. aiohomematic/model/hub/binary_sensor.py +24 -0
  124. aiohomematic/model/hub/button.py +28 -0
  125. aiohomematic/model/hub/connectivity.py +190 -0
  126. aiohomematic/model/hub/data_point.py +342 -0
  127. aiohomematic/model/hub/hub.py +864 -0
  128. aiohomematic/model/hub/inbox.py +135 -0
  129. aiohomematic/model/hub/install_mode.py +393 -0
  130. aiohomematic/model/hub/metrics.py +208 -0
  131. aiohomematic/model/hub/number.py +42 -0
  132. aiohomematic/model/hub/select.py +52 -0
  133. aiohomematic/model/hub/sensor.py +37 -0
  134. aiohomematic/model/hub/switch.py +43 -0
  135. aiohomematic/model/hub/text.py +30 -0
  136. aiohomematic/model/hub/update.py +221 -0
  137. aiohomematic/model/support.py +592 -0
  138. aiohomematic/model/update.py +140 -0
  139. aiohomematic/model/week_profile.py +1827 -0
  140. aiohomematic/property_decorators.py +719 -0
  141. aiohomematic/py.typed +0 -0
  142. aiohomematic/rega_scripts/accept_device_in_inbox.fn +51 -0
  143. aiohomematic/rega_scripts/create_backup_start.fn +28 -0
  144. aiohomematic/rega_scripts/create_backup_status.fn +89 -0
  145. aiohomematic/rega_scripts/fetch_all_device_data.fn +97 -0
  146. aiohomematic/rega_scripts/get_backend_info.fn +25 -0
  147. aiohomematic/rega_scripts/get_inbox_devices.fn +61 -0
  148. aiohomematic/rega_scripts/get_program_descriptions.fn +31 -0
  149. aiohomematic/rega_scripts/get_serial.fn +44 -0
  150. aiohomematic/rega_scripts/get_service_messages.fn +83 -0
  151. aiohomematic/rega_scripts/get_system_update_info.fn +39 -0
  152. aiohomematic/rega_scripts/get_system_variable_descriptions.fn +31 -0
  153. aiohomematic/rega_scripts/set_program_state.fn +17 -0
  154. aiohomematic/rega_scripts/set_system_variable.fn +19 -0
  155. aiohomematic/rega_scripts/trigger_firmware_update.fn +67 -0
  156. aiohomematic/schemas.py +256 -0
  157. aiohomematic/store/__init__.py +55 -0
  158. aiohomematic/store/dynamic/__init__.py +43 -0
  159. aiohomematic/store/dynamic/command.py +250 -0
  160. aiohomematic/store/dynamic/data.py +175 -0
  161. aiohomematic/store/dynamic/details.py +187 -0
  162. aiohomematic/store/dynamic/ping_pong.py +416 -0
  163. aiohomematic/store/persistent/__init__.py +71 -0
  164. aiohomematic/store/persistent/base.py +285 -0
  165. aiohomematic/store/persistent/device.py +233 -0
  166. aiohomematic/store/persistent/incident.py +380 -0
  167. aiohomematic/store/persistent/paramset.py +241 -0
  168. aiohomematic/store/persistent/session.py +556 -0
  169. aiohomematic/store/serialization.py +150 -0
  170. aiohomematic/store/storage.py +689 -0
  171. aiohomematic/store/types.py +526 -0
  172. aiohomematic/store/visibility/__init__.py +40 -0
  173. aiohomematic/store/visibility/parser.py +141 -0
  174. aiohomematic/store/visibility/registry.py +722 -0
  175. aiohomematic/store/visibility/rules.py +307 -0
  176. aiohomematic/strings.json +237 -0
  177. aiohomematic/support.py +706 -0
  178. aiohomematic/tracing.py +236 -0
  179. aiohomematic/translations/de.json +237 -0
  180. aiohomematic/translations/en.json +237 -0
  181. aiohomematic/type_aliases.py +51 -0
  182. aiohomematic/validator.py +128 -0
  183. aiohomematic-2026.1.29.dist-info/METADATA +296 -0
  184. aiohomematic-2026.1.29.dist-info/RECORD +188 -0
  185. aiohomematic-2026.1.29.dist-info/WHEEL +5 -0
  186. aiohomematic-2026.1.29.dist-info/entry_points.txt +2 -0
  187. aiohomematic-2026.1.29.dist-info/licenses/LICENSE +21 -0
  188. aiohomematic-2026.1.29.dist-info/top_level.txt +1 -0
@@ -0,0 +1,945 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2021-2026
3
+ """
4
+ Profile configuration dataclasses for custom data points.
5
+
6
+ This module provides type-safe dataclass definitions for device profiles,
7
+ offering a cleaner alternative to the nested dictionary structure in definition.py.
8
+
9
+ Key types:
10
+ - ChannelGroupConfig: Configuration for channel structure and field mappings
11
+ - ProfileConfig: Complete profile configuration including channel groups
12
+ - ProfileRegistry: Type alias for the profile configuration mapping
13
+
14
+ Example usage:
15
+ from aiohomematic.model.custom import (
16
+ ProfileConfig,
17
+ ChannelGroupConfig,
18
+ )
19
+
20
+ MY_PROFILE = ProfileConfig(
21
+ profile_type=ProfileType.HMIP_THERMOSTAT,
22
+ channel_group=ChannelGroupConfig(
23
+ fields={Field.SETPOINT: Parameter.SET_POINT_TEMPERATURE},
24
+ ),
25
+ )
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ from collections.abc import Mapping
31
+ from dataclasses import dataclass, field
32
+ from typing import Final, TypeAlias
33
+
34
+ from aiohomematic.const import ChannelOffset, DeviceProfile, Field, Parameter
35
+
36
+ __all__ = [
37
+ "ChannelGroupConfig",
38
+ "DEFAULT_DATA_POINTS",
39
+ "ProfileConfig",
40
+ "ProfileRegistry",
41
+ "PROFILE_CONFIGS",
42
+ "RebasedChannelGroupConfig",
43
+ "get_profile_config",
44
+ "rebase_channel_group",
45
+ ]
46
+
47
+
48
+ @dataclass(frozen=True, kw_only=True, slots=True)
49
+ class ChannelGroupConfig:
50
+ """
51
+ Configuration for a channel group within a profile.
52
+
53
+ A channel group defines the structure of channels for a device type,
54
+ including which fields are available on each channel.
55
+
56
+ Channel Number Convention
57
+ -------------------------
58
+ This configuration uses two types of channel numbers:
59
+
60
+ **Relative channel numbers** (used in most fields):
61
+ - `primary_channel`, `secondary_channels`, `state_channel_offset`
62
+ - `channel_fields`, `visible_channel_fields`
63
+
64
+ These are **offsets from a base channel** (group_no). The base channel is
65
+ determined at device registration time via DeviceProfileRegistry.register(channels=(...)).
66
+
67
+ For example, with a configuration of:
68
+ primary_channel=1, secondary_channels=(2, 3)
69
+
70
+ And registration with channels=(4,):
71
+ - group_no becomes 4
72
+ - Actual primary_channel = 4 + 1 = 5
73
+ - Actual secondary_channels = (4 + 2, 4 + 3) = (6, 7)
74
+
75
+ The conversion from relative to absolute channel numbers is performed by
76
+ rebase_channel_group(), which produces a RebasedChannelGroupConfig.
77
+
78
+ **Absolute channel numbers** (fixed, not rebased):
79
+ - `fixed_channel_fields`, `visible_fixed_channel_fields`
80
+
81
+ These are used for fields that must always reference specific device channels,
82
+ regardless of which channel group is being created. Common use case: channel 0
83
+ parameters that apply to the entire device.
84
+
85
+ Special Values
86
+ --------------
87
+ - primary_channel=0: The primary channel is the base channel itself (group_no)
88
+ - primary_channel=None: No primary channel defined
89
+ - ChannelOffset enum values can be used for semantic offsets in channel_fields
90
+ """
91
+
92
+ # Channel structure (relative to group_no base channel)
93
+ primary_channel: int | None = 0
94
+ secondary_channels: tuple[int, ...] = ()
95
+ state_channel_offset: int | None = None
96
+ allow_undefined_generic_data_points: bool = False
97
+
98
+ # Field mappings applied to the primary channel (not channel-specific)
99
+ fields: Mapping[Field, Parameter] = field(default_factory=dict)
100
+ visible_fields: Mapping[Field, Parameter] = field(default_factory=dict)
101
+
102
+ # Channel-specific field mappings with RELATIVE channel offsets
103
+ # {channel_offset: {field: parameter}} - channel numbers are offsets from group_no
104
+ # Use ChannelOffset enum values (e.g., ChannelOffset.STATE) for semantic offsets.
105
+ channel_fields: Mapping[int | None, Mapping[Field, Parameter]] = field(default_factory=dict)
106
+ visible_channel_fields: Mapping[int | None, Mapping[Field, Parameter]] = field(default_factory=dict)
107
+
108
+ # Channel-specific field mappings with ABSOLUTE (fixed) channel numbers
109
+ # {channel_no: {field: parameter}} - channel numbers are NOT rebased
110
+ # Use for fields that must always reference specific device channels (e.g., channel 0).
111
+ fixed_channel_fields: Mapping[int, Mapping[Field, Parameter]] = field(default_factory=dict)
112
+ visible_fixed_channel_fields: Mapping[int, Mapping[Field, Parameter]] = field(default_factory=dict)
113
+
114
+
115
+ @dataclass(frozen=True, kw_only=True, slots=True)
116
+ class ProfileConfig:
117
+ """Complete profile configuration for a device type."""
118
+
119
+ profile_type: DeviceProfile
120
+ channel_group: ChannelGroupConfig
121
+ additional_data_points: Mapping[int, tuple[Parameter, ...]] = field(default_factory=dict)
122
+ include_default_data_points: bool = True
123
+
124
+
125
+ @dataclass(frozen=True, kw_only=True, slots=True)
126
+ class RebasedChannelGroupConfig:
127
+ """
128
+ Channel group configuration with rebased channel numbers.
129
+
130
+ This dataclass contains channel configuration with all relative channel numbers
131
+ adjusted by the group offset. Used by CustomDataPoint to access field
132
+ mappings without dictionary-based lookups.
133
+
134
+ All channel numbers in this config are **absolute** (actual device channels):
135
+ - `primary_channel`, `secondary_channels`, `state_channel` - rebased from offsets
136
+ - `channel_fields`, `visible_channel_fields` - rebased from offsets
137
+ - `fixed_channel_fields`, `visible_fixed_channel_fields` - already absolute (unchanged)
138
+ """
139
+
140
+ # Rebased channel structure (actual channel numbers after applying group_no)
141
+ primary_channel: int | None
142
+ secondary_channels: tuple[int, ...]
143
+ state_channel: int | None
144
+ allow_undefined_generic_data_points: bool
145
+
146
+ # Field mappings applied to the primary channel
147
+ fields: Mapping[Field, Parameter]
148
+ visible_fields: Mapping[Field, Parameter]
149
+
150
+ # Channel-specific field mappings (rebased to actual channel numbers)
151
+ channel_fields: Mapping[int | None, Mapping[Field, Parameter]]
152
+ visible_channel_fields: Mapping[int | None, Mapping[Field, Parameter]]
153
+
154
+ # Fixed channel field mappings (absolute channel numbers, not rebased)
155
+ fixed_channel_fields: Mapping[int, Mapping[Field, Parameter]]
156
+ visible_fixed_channel_fields: Mapping[int, Mapping[Field, Parameter]]
157
+
158
+
159
+ def rebase_channel_group(
160
+ *,
161
+ profile_config: ProfileConfig,
162
+ group_no: int | None,
163
+ ) -> RebasedChannelGroupConfig:
164
+ """
165
+ Create a rebased channel group from a ProfileConfig.
166
+
167
+ Applies the group offset to relative channel numbers in the configuration,
168
+ producing a RebasedChannelGroupConfig with actual channel numbers.
169
+
170
+ Fixed channel fields are passed through unchanged (they use absolute channel numbers).
171
+
172
+ Args:
173
+ profile_config: The profile configuration to rebase.
174
+ group_no: The group offset to apply (None means no offset).
175
+
176
+ Returns:
177
+ RebasedChannelGroupConfig with rebased channel numbers.
178
+
179
+ """
180
+ cg = profile_config.channel_group
181
+ offset = group_no or 0
182
+
183
+ # Rebase primary channel
184
+ primary = cg.primary_channel
185
+ if primary is not None and offset:
186
+ primary = primary + offset
187
+
188
+ # Rebase secondary channels
189
+ secondary = tuple(ch + offset for ch in cg.secondary_channels) if offset else cg.secondary_channels
190
+
191
+ # Rebase state channel
192
+ state = None
193
+ if cg.state_channel_offset is not None:
194
+ state = cg.state_channel_offset + offset if offset else cg.state_channel_offset
195
+
196
+ # Rebase channel_fields (relative -> absolute)
197
+ channel_fields: dict[int | None, Mapping[Field, Parameter]] = {}
198
+ for ch_no, ch_fields in cg.channel_fields.items():
199
+ if ch_no is None:
200
+ channel_fields[None] = ch_fields
201
+ else:
202
+ channel_fields[ch_no + offset] = ch_fields
203
+
204
+ # Rebase visible_channel_fields (relative -> absolute)
205
+ visible_channel_fields: dict[int | None, Mapping[Field, Parameter]] = {}
206
+ for ch_no, ch_fields in cg.visible_channel_fields.items():
207
+ if ch_no is None:
208
+ visible_channel_fields[None] = ch_fields
209
+ else:
210
+ visible_channel_fields[ch_no + offset] = ch_fields
211
+
212
+ # Fixed channel fields are NOT rebased (already absolute)
213
+ return RebasedChannelGroupConfig(
214
+ primary_channel=primary,
215
+ secondary_channels=secondary,
216
+ state_channel=state,
217
+ allow_undefined_generic_data_points=cg.allow_undefined_generic_data_points,
218
+ fields=cg.fields,
219
+ visible_fields=cg.visible_fields,
220
+ channel_fields=channel_fields,
221
+ visible_channel_fields=visible_channel_fields,
222
+ fixed_channel_fields=cg.fixed_channel_fields,
223
+ visible_fixed_channel_fields=cg.visible_fixed_channel_fields,
224
+ )
225
+
226
+
227
+ # Type alias for the profile registry
228
+ ProfileRegistry: TypeAlias = Mapping[DeviceProfile, ProfileConfig]
229
+
230
+
231
+ # =============================================================================
232
+ # Profile Configurations
233
+ # =============================================================================
234
+ # These configurations mirror the definitions in definition.py but use
235
+ # type-safe dataclasses instead of nested dictionaries.
236
+
237
+
238
+ # --- Button Lock Profiles ---
239
+
240
+ IP_BUTTON_LOCK_CONFIG: Final = ProfileConfig(
241
+ profile_type=DeviceProfile.IP_BUTTON_LOCK,
242
+ channel_group=ChannelGroupConfig(
243
+ allow_undefined_generic_data_points=True,
244
+ fields={
245
+ Field.BUTTON_LOCK: Parameter.GLOBAL_BUTTON_LOCK,
246
+ },
247
+ ),
248
+ )
249
+
250
+ RF_BUTTON_LOCK_CONFIG: Final = ProfileConfig(
251
+ profile_type=DeviceProfile.RF_BUTTON_LOCK,
252
+ channel_group=ChannelGroupConfig(
253
+ primary_channel=None,
254
+ allow_undefined_generic_data_points=True,
255
+ fields={
256
+ Field.BUTTON_LOCK: Parameter.GLOBAL_BUTTON_LOCK,
257
+ },
258
+ ),
259
+ )
260
+
261
+
262
+ # --- Cover Profiles ---
263
+
264
+ IP_COVER_CONFIG: Final = ProfileConfig(
265
+ profile_type=DeviceProfile.IP_COVER,
266
+ channel_group=ChannelGroupConfig(
267
+ secondary_channels=(1, 2),
268
+ state_channel_offset=ChannelOffset.STATE,
269
+ fields={
270
+ Field.COMBINED_PARAMETER: Parameter.COMBINED_PARAMETER,
271
+ Field.LEVEL: Parameter.LEVEL,
272
+ Field.LEVEL_2: Parameter.LEVEL_2,
273
+ Field.STOP: Parameter.STOP,
274
+ },
275
+ channel_fields={
276
+ ChannelOffset.STATE: {
277
+ Field.DIRECTION: Parameter.ACTIVITY_STATE,
278
+ Field.OPERATION_MODE: Parameter.CHANNEL_OPERATION_MODE,
279
+ },
280
+ },
281
+ visible_channel_fields={
282
+ ChannelOffset.STATE: {
283
+ Field.GROUP_LEVEL: Parameter.LEVEL,
284
+ Field.GROUP_LEVEL_2: Parameter.LEVEL_2,
285
+ },
286
+ },
287
+ ),
288
+ )
289
+
290
+ RF_COVER_CONFIG: Final = ProfileConfig(
291
+ profile_type=DeviceProfile.RF_COVER,
292
+ channel_group=ChannelGroupConfig(
293
+ fields={
294
+ Field.DIRECTION: Parameter.DIRECTION,
295
+ Field.LEVEL: Parameter.LEVEL,
296
+ Field.LEVEL_2: Parameter.LEVEL_SLATS,
297
+ Field.LEVEL_COMBINED: Parameter.LEVEL_COMBINED,
298
+ Field.STOP: Parameter.STOP,
299
+ },
300
+ ),
301
+ )
302
+
303
+ IP_HDM_CONFIG: Final = ProfileConfig(
304
+ profile_type=DeviceProfile.IP_HDM,
305
+ channel_group=ChannelGroupConfig(
306
+ channel_fields={
307
+ 0: {
308
+ Field.DIRECTION: Parameter.ACTIVITY_STATE,
309
+ Field.LEVEL: Parameter.LEVEL,
310
+ Field.LEVEL_2: Parameter.LEVEL_2,
311
+ Field.STOP: Parameter.STOP,
312
+ },
313
+ },
314
+ ),
315
+ )
316
+
317
+ IP_GARAGE_CONFIG: Final = ProfileConfig(
318
+ profile_type=DeviceProfile.IP_GARAGE,
319
+ channel_group=ChannelGroupConfig(
320
+ fields={
321
+ Field.DOOR_COMMAND: Parameter.DOOR_COMMAND,
322
+ Field.SECTION: Parameter.SECTION,
323
+ },
324
+ visible_fields={
325
+ Field.DOOR_STATE: Parameter.DOOR_STATE,
326
+ },
327
+ ),
328
+ additional_data_points={
329
+ 1: (Parameter.STATE,),
330
+ },
331
+ )
332
+
333
+
334
+ # --- Dimmer/Light Profiles ---
335
+
336
+ IP_DIMMER_CONFIG: Final = ProfileConfig(
337
+ profile_type=DeviceProfile.IP_DIMMER,
338
+ channel_group=ChannelGroupConfig(
339
+ secondary_channels=(1, 2),
340
+ state_channel_offset=ChannelOffset.STATE,
341
+ fields={
342
+ Field.LEVEL: Parameter.LEVEL,
343
+ Field.ON_TIME_VALUE: Parameter.ON_TIME,
344
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME,
345
+ },
346
+ visible_channel_fields={
347
+ ChannelOffset.STATE: {
348
+ Field.GROUP_LEVEL: Parameter.LEVEL,
349
+ },
350
+ },
351
+ ),
352
+ )
353
+
354
+ RF_DIMMER_CONFIG: Final = ProfileConfig(
355
+ profile_type=DeviceProfile.RF_DIMMER,
356
+ channel_group=ChannelGroupConfig(
357
+ fields={
358
+ Field.LEVEL: Parameter.LEVEL,
359
+ Field.ON_TIME_VALUE: Parameter.ON_TIME,
360
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME,
361
+ },
362
+ ),
363
+ )
364
+
365
+ RF_DIMMER_COLOR_CONFIG: Final = ProfileConfig(
366
+ profile_type=DeviceProfile.RF_DIMMER_COLOR,
367
+ channel_group=ChannelGroupConfig(
368
+ fields={
369
+ Field.LEVEL: Parameter.LEVEL,
370
+ Field.ON_TIME_VALUE: Parameter.ON_TIME,
371
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME,
372
+ },
373
+ channel_fields={
374
+ 1: {Field.COLOR: Parameter.COLOR},
375
+ 2: {Field.PROGRAM: Parameter.PROGRAM},
376
+ },
377
+ ),
378
+ )
379
+
380
+ RF_DIMMER_COLOR_FIXED_CONFIG: Final = ProfileConfig(
381
+ profile_type=DeviceProfile.RF_DIMMER_COLOR_FIXED,
382
+ channel_group=ChannelGroupConfig(
383
+ fields={
384
+ Field.LEVEL: Parameter.LEVEL,
385
+ Field.ON_TIME_VALUE: Parameter.ON_TIME,
386
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME,
387
+ },
388
+ ),
389
+ )
390
+
391
+ RF_DIMMER_COLOR_TEMP_CONFIG: Final = ProfileConfig(
392
+ profile_type=DeviceProfile.RF_DIMMER_COLOR_TEMP,
393
+ channel_group=ChannelGroupConfig(
394
+ fields={
395
+ Field.LEVEL: Parameter.LEVEL,
396
+ Field.ON_TIME_VALUE: Parameter.ON_TIME,
397
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME,
398
+ },
399
+ channel_fields={
400
+ 1: {Field.COLOR_LEVEL: Parameter.LEVEL},
401
+ },
402
+ ),
403
+ )
404
+
405
+ RF_DIMMER_WITH_VIRT_CHANNEL_CONFIG: Final = ProfileConfig(
406
+ profile_type=DeviceProfile.RF_DIMMER_WITH_VIRT_CHANNEL,
407
+ channel_group=ChannelGroupConfig(
408
+ secondary_channels=(1, 2),
409
+ fields={
410
+ Field.LEVEL: Parameter.LEVEL,
411
+ Field.ON_TIME_VALUE: Parameter.ON_TIME,
412
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME,
413
+ },
414
+ ),
415
+ )
416
+
417
+ IP_FIXED_COLOR_LIGHT_CONFIG: Final = ProfileConfig(
418
+ profile_type=DeviceProfile.IP_FIXED_COLOR_LIGHT,
419
+ channel_group=ChannelGroupConfig(
420
+ secondary_channels=(1, 2),
421
+ state_channel_offset=ChannelOffset.STATE,
422
+ fields={
423
+ Field.COLOR: Parameter.COLOR,
424
+ Field.COLOR_BEHAVIOUR: Parameter.COLOR_BEHAVIOUR,
425
+ Field.LEVEL: Parameter.LEVEL,
426
+ Field.ON_TIME_UNIT: Parameter.DURATION_UNIT,
427
+ Field.ON_TIME_VALUE: Parameter.DURATION_VALUE,
428
+ Field.RAMP_TIME_UNIT: Parameter.RAMP_TIME_UNIT,
429
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME_VALUE,
430
+ },
431
+ visible_channel_fields={
432
+ ChannelOffset.STATE: {
433
+ Field.CHANNEL_COLOR: Parameter.COLOR,
434
+ Field.GROUP_LEVEL: Parameter.LEVEL,
435
+ },
436
+ },
437
+ ),
438
+ )
439
+
440
+ IP_SIMPLE_FIXED_COLOR_LIGHT_WIRED_CONFIG: Final = ProfileConfig(
441
+ profile_type=DeviceProfile.IP_SIMPLE_FIXED_COLOR_LIGHT_WIRED,
442
+ channel_group=ChannelGroupConfig(
443
+ fields={
444
+ Field.COLOR: Parameter.COLOR,
445
+ Field.COLOR_BEHAVIOUR: Parameter.COLOR_BEHAVIOUR,
446
+ Field.LEVEL: Parameter.LEVEL,
447
+ Field.ON_TIME_UNIT: Parameter.DURATION_UNIT,
448
+ Field.ON_TIME_VALUE: Parameter.DURATION_VALUE,
449
+ Field.RAMP_TIME_UNIT: Parameter.RAMP_TIME_UNIT,
450
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME_VALUE,
451
+ },
452
+ ),
453
+ )
454
+
455
+ IP_SIMPLE_FIXED_COLOR_LIGHT_CONFIG: Final = ProfileConfig(
456
+ profile_type=DeviceProfile.IP_SIMPLE_FIXED_COLOR_LIGHT,
457
+ channel_group=ChannelGroupConfig(
458
+ fields={
459
+ Field.COLOR: Parameter.COLOR,
460
+ Field.LEVEL: Parameter.LEVEL,
461
+ Field.ON_TIME_UNIT: Parameter.DURATION_UNIT,
462
+ Field.ON_TIME_VALUE: Parameter.DURATION_VALUE,
463
+ Field.RAMP_TIME_UNIT: Parameter.RAMP_TIME_UNIT,
464
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME_VALUE,
465
+ },
466
+ ),
467
+ )
468
+
469
+ IP_RGBW_LIGHT_CONFIG: Final = ProfileConfig(
470
+ profile_type=DeviceProfile.IP_RGBW_LIGHT,
471
+ channel_group=ChannelGroupConfig(
472
+ secondary_channels=(1, 2, 3),
473
+ fields={
474
+ Field.COLOR_TEMPERATURE: Parameter.COLOR_TEMPERATURE,
475
+ Field.DIRECTION: Parameter.ACTIVITY_STATE,
476
+ Field.ON_TIME_VALUE: Parameter.DURATION_VALUE,
477
+ Field.ON_TIME_UNIT: Parameter.DURATION_UNIT,
478
+ Field.EFFECT: Parameter.EFFECT,
479
+ Field.HUE: Parameter.HUE,
480
+ Field.LEVEL: Parameter.LEVEL,
481
+ Field.RAMP_TIME_TO_OFF_UNIT: Parameter.RAMP_TIME_TO_OFF_UNIT,
482
+ Field.RAMP_TIME_TO_OFF_VALUE: Parameter.RAMP_TIME_TO_OFF_VALUE,
483
+ Field.RAMP_TIME_UNIT: Parameter.RAMP_TIME_UNIT,
484
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME_VALUE,
485
+ Field.SATURATION: Parameter.SATURATION,
486
+ },
487
+ channel_fields={
488
+ ChannelOffset.STATE: {
489
+ Field.DEVICE_OPERATION_MODE: Parameter.DEVICE_OPERATION_MODE,
490
+ },
491
+ },
492
+ ),
493
+ )
494
+
495
+ IP_DRG_DALI_CONFIG: Final = ProfileConfig(
496
+ profile_type=DeviceProfile.IP_DRG_DALI,
497
+ channel_group=ChannelGroupConfig(
498
+ fields={
499
+ Field.COLOR_TEMPERATURE: Parameter.COLOR_TEMPERATURE,
500
+ Field.ON_TIME_VALUE: Parameter.DURATION_VALUE,
501
+ Field.ON_TIME_UNIT: Parameter.DURATION_UNIT,
502
+ Field.EFFECT: Parameter.EFFECT,
503
+ Field.HUE: Parameter.HUE,
504
+ Field.LEVEL: Parameter.LEVEL,
505
+ Field.RAMP_TIME_TO_OFF_UNIT: Parameter.RAMP_TIME_TO_OFF_UNIT,
506
+ Field.RAMP_TIME_TO_OFF_VALUE: Parameter.RAMP_TIME_TO_OFF_VALUE,
507
+ Field.RAMP_TIME_UNIT: Parameter.RAMP_TIME_UNIT,
508
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME_VALUE,
509
+ Field.SATURATION: Parameter.SATURATION,
510
+ },
511
+ ),
512
+ )
513
+
514
+
515
+ # --- Switch Profiles ---
516
+
517
+ IP_SWITCH_CONFIG: Final = ProfileConfig(
518
+ profile_type=DeviceProfile.IP_SWITCH,
519
+ channel_group=ChannelGroupConfig(
520
+ secondary_channels=(1, 2),
521
+ state_channel_offset=ChannelOffset.STATE,
522
+ fields={
523
+ Field.STATE: Parameter.STATE,
524
+ Field.ON_TIME_VALUE: Parameter.ON_TIME,
525
+ },
526
+ visible_channel_fields={
527
+ ChannelOffset.STATE: {
528
+ Field.GROUP_STATE: Parameter.STATE,
529
+ },
530
+ },
531
+ ),
532
+ additional_data_points={
533
+ 3: (
534
+ Parameter.CURRENT,
535
+ Parameter.ENERGY_COUNTER,
536
+ Parameter.ENERGY_COUNTER_FEED_IN,
537
+ Parameter.FREQUENCY,
538
+ Parameter.POWER,
539
+ Parameter.ACTUAL_TEMPERATURE,
540
+ Parameter.VOLTAGE,
541
+ ),
542
+ },
543
+ )
544
+
545
+ RF_SWITCH_CONFIG: Final = ProfileConfig(
546
+ profile_type=DeviceProfile.RF_SWITCH,
547
+ channel_group=ChannelGroupConfig(
548
+ fields={
549
+ Field.STATE: Parameter.STATE,
550
+ Field.ON_TIME_VALUE: Parameter.ON_TIME,
551
+ },
552
+ ),
553
+ additional_data_points={
554
+ 1: (
555
+ Parameter.CURRENT,
556
+ Parameter.ENERGY_COUNTER,
557
+ Parameter.FREQUENCY,
558
+ Parameter.POWER,
559
+ Parameter.VOLTAGE,
560
+ ),
561
+ },
562
+ )
563
+
564
+ IP_IRRIGATION_VALVE_CONFIG: Final = ProfileConfig(
565
+ profile_type=DeviceProfile.IP_IRRIGATION_VALVE,
566
+ channel_group=ChannelGroupConfig(
567
+ secondary_channels=(1, 2),
568
+ fields={
569
+ Field.STATE: Parameter.STATE,
570
+ Field.ON_TIME_VALUE: Parameter.ON_TIME,
571
+ },
572
+ visible_channel_fields={
573
+ ChannelOffset.STATE: {
574
+ Field.GROUP_STATE: Parameter.STATE,
575
+ },
576
+ },
577
+ ),
578
+ additional_data_points={
579
+ ChannelOffset.SENSOR: (
580
+ Parameter.WATER_FLOW,
581
+ Parameter.WATER_VOLUME,
582
+ Parameter.WATER_VOLUME_SINCE_OPEN,
583
+ ),
584
+ },
585
+ )
586
+
587
+
588
+ # --- Lock Profiles ---
589
+
590
+ IP_LOCK_CONFIG: Final = ProfileConfig(
591
+ profile_type=DeviceProfile.IP_LOCK,
592
+ channel_group=ChannelGroupConfig(
593
+ fields={
594
+ Field.DIRECTION: Parameter.ACTIVITY_STATE,
595
+ Field.LOCK_STATE: Parameter.LOCK_STATE,
596
+ Field.LOCK_TARGET_LEVEL: Parameter.LOCK_TARGET_LEVEL,
597
+ },
598
+ channel_fields={
599
+ ChannelOffset.STATE: {
600
+ Field.ERROR: Parameter.ERROR_JAMMED,
601
+ },
602
+ },
603
+ ),
604
+ )
605
+
606
+ RF_LOCK_CONFIG: Final = ProfileConfig(
607
+ profile_type=DeviceProfile.RF_LOCK,
608
+ channel_group=ChannelGroupConfig(
609
+ fields={
610
+ Field.DIRECTION: Parameter.DIRECTION,
611
+ Field.OPEN: Parameter.OPEN,
612
+ Field.STATE: Parameter.STATE,
613
+ Field.ERROR: Parameter.ERROR,
614
+ },
615
+ ),
616
+ )
617
+
618
+
619
+ # --- Siren Profiles ---
620
+
621
+ IP_SIREN_CONFIG: Final = ProfileConfig(
622
+ profile_type=DeviceProfile.IP_SIREN,
623
+ channel_group=ChannelGroupConfig(
624
+ fields={
625
+ Field.ACOUSTIC_ALARM_ACTIVE: Parameter.ACOUSTIC_ALARM_ACTIVE,
626
+ Field.OPTICAL_ALARM_ACTIVE: Parameter.OPTICAL_ALARM_ACTIVE,
627
+ Field.DURATION: Parameter.DURATION_VALUE,
628
+ Field.DURATION_UNIT: Parameter.DURATION_UNIT,
629
+ },
630
+ visible_fields={
631
+ Field.ACOUSTIC_ALARM_SELECTION: Parameter.ACOUSTIC_ALARM_SELECTION,
632
+ Field.OPTICAL_ALARM_SELECTION: Parameter.OPTICAL_ALARM_SELECTION,
633
+ },
634
+ ),
635
+ )
636
+
637
+ IP_SIREN_SMOKE_CONFIG: Final = ProfileConfig(
638
+ profile_type=DeviceProfile.IP_SIREN_SMOKE,
639
+ channel_group=ChannelGroupConfig(
640
+ fields={
641
+ Field.SMOKE_DETECTOR_COMMAND: Parameter.SMOKE_DETECTOR_COMMAND,
642
+ },
643
+ visible_fields={
644
+ Field.SMOKE_DETECTOR_ALARM_STATUS: Parameter.SMOKE_DETECTOR_ALARM_STATUS,
645
+ },
646
+ ),
647
+ )
648
+
649
+
650
+ # --- Sound Player Profiles ---
651
+
652
+ IP_SOUND_PLAYER_CONFIG: Final = ProfileConfig(
653
+ profile_type=DeviceProfile.IP_SOUND_PLAYER,
654
+ channel_group=ChannelGroupConfig(
655
+ fields={
656
+ Field.DIRECTION: Parameter.ACTIVITY_STATE,
657
+ Field.DURATION_UNIT: Parameter.DURATION_UNIT,
658
+ Field.DURATION_VALUE: Parameter.DURATION_VALUE,
659
+ Field.LEVEL: Parameter.LEVEL,
660
+ Field.RAMP_TIME_UNIT: Parameter.RAMP_TIME_UNIT,
661
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME_VALUE,
662
+ Field.REPETITIONS: Parameter.REPETITIONS,
663
+ Field.SOUNDFILE: Parameter.SOUNDFILE,
664
+ },
665
+ ),
666
+ )
667
+
668
+ IP_SOUND_PLAYER_LED_CONFIG: Final = ProfileConfig(
669
+ profile_type=DeviceProfile.IP_SOUND_PLAYER_LED,
670
+ channel_group=ChannelGroupConfig(
671
+ fields={
672
+ Field.COLOR: Parameter.COLOR,
673
+ Field.DIRECTION: Parameter.ACTIVITY_STATE,
674
+ Field.DURATION_UNIT: Parameter.DURATION_UNIT,
675
+ Field.DURATION_VALUE: Parameter.DURATION_VALUE,
676
+ Field.LEVEL: Parameter.LEVEL,
677
+ Field.ON_TIME_LIST: Parameter.ON_TIME_LIST_1,
678
+ Field.RAMP_TIME_UNIT: Parameter.RAMP_TIME_UNIT,
679
+ Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME_VALUE,
680
+ Field.REPETITIONS: Parameter.REPETITIONS,
681
+ },
682
+ ),
683
+ )
684
+
685
+
686
+ # --- Text Display Profiles ---
687
+
688
+ IP_TEXT_DISPLAY_CONFIG: Final = ProfileConfig(
689
+ profile_type=DeviceProfile.IP_TEXT_DISPLAY,
690
+ channel_group=ChannelGroupConfig(
691
+ fields={
692
+ Field.ACOUSTIC_NOTIFICATION_SELECTION: Parameter.ACOUSTIC_NOTIFICATION_SELECTION,
693
+ Field.DISPLAY_DATA_ALIGNMENT: Parameter.DISPLAY_DATA_ALIGNMENT,
694
+ Field.DISPLAY_DATA_BACKGROUND_COLOR: Parameter.DISPLAY_DATA_BACKGROUND_COLOR,
695
+ Field.DISPLAY_DATA_COMMIT: Parameter.DISPLAY_DATA_COMMIT,
696
+ Field.DISPLAY_DATA_ICON: Parameter.DISPLAY_DATA_ICON,
697
+ Field.DISPLAY_DATA_ID: Parameter.DISPLAY_DATA_ID,
698
+ Field.DISPLAY_DATA_STRING: Parameter.DISPLAY_DATA_STRING,
699
+ Field.DISPLAY_DATA_TEXT_COLOR: Parameter.DISPLAY_DATA_TEXT_COLOR,
700
+ Field.INTERVAL: Parameter.INTERVAL,
701
+ Field.REPETITIONS: Parameter.REPETITIONS,
702
+ },
703
+ visible_fixed_channel_fields={
704
+ 0: {Field.BURST_LIMIT_WARNING: Parameter.BURST_LIMIT_WARNING},
705
+ },
706
+ ),
707
+ )
708
+
709
+
710
+ # --- Thermostat Profiles ---
711
+
712
+ IP_THERMOSTAT_CONFIG: Final = ProfileConfig(
713
+ profile_type=DeviceProfile.IP_THERMOSTAT,
714
+ channel_group=ChannelGroupConfig(
715
+ fields={
716
+ Field.ACTIVE_PROFILE: Parameter.ACTIVE_PROFILE,
717
+ Field.BOOST_MODE: Parameter.BOOST_MODE,
718
+ Field.CONTROL_MODE: Parameter.CONTROL_MODE,
719
+ Field.MIN_MAX_VALUE_NOT_RELEVANT_FOR_MANU_MODE: Parameter.MIN_MAX_VALUE_NOT_RELEVANT_FOR_MANU_MODE,
720
+ Field.OPTIMUM_START_STOP: Parameter.OPTIMUM_START_STOP,
721
+ Field.PARTY_MODE: Parameter.PARTY_MODE,
722
+ Field.SETPOINT: Parameter.SET_POINT_TEMPERATURE,
723
+ Field.SET_POINT_MODE: Parameter.SET_POINT_MODE,
724
+ Field.TEMPERATURE_MAXIMUM: Parameter.TEMPERATURE_MAXIMUM,
725
+ Field.TEMPERATURE_MINIMUM: Parameter.TEMPERATURE_MINIMUM,
726
+ Field.TEMPERATURE_OFFSET: Parameter.TEMPERATURE_OFFSET,
727
+ },
728
+ visible_fields={
729
+ Field.HEATING_COOLING: Parameter.HEATING_COOLING,
730
+ Field.HUMIDITY: Parameter.HUMIDITY,
731
+ Field.TEMPERATURE: Parameter.ACTUAL_TEMPERATURE,
732
+ },
733
+ visible_channel_fields={
734
+ 0: {
735
+ Field.LEVEL: Parameter.LEVEL,
736
+ Field.CONCENTRATION: Parameter.CONCENTRATION,
737
+ },
738
+ 8: { # BWTH
739
+ Field.STATE: Parameter.STATE,
740
+ },
741
+ },
742
+ channel_fields={
743
+ 7: {
744
+ Field.HEATING_VALVE_TYPE: Parameter.HEATING_VALVE_TYPE,
745
+ },
746
+ ChannelOffset.CONFIG: { # WGTC
747
+ Field.STATE: Parameter.STATE,
748
+ },
749
+ },
750
+ ),
751
+ )
752
+
753
+ IP_THERMOSTAT_GROUP_CONFIG: Final = ProfileConfig(
754
+ profile_type=DeviceProfile.IP_THERMOSTAT_GROUP,
755
+ channel_group=ChannelGroupConfig(
756
+ fields={
757
+ Field.ACTIVE_PROFILE: Parameter.ACTIVE_PROFILE,
758
+ Field.BOOST_MODE: Parameter.BOOST_MODE,
759
+ Field.CONTROL_MODE: Parameter.CONTROL_MODE,
760
+ Field.HEATING_VALVE_TYPE: Parameter.HEATING_VALVE_TYPE,
761
+ Field.MIN_MAX_VALUE_NOT_RELEVANT_FOR_MANU_MODE: Parameter.MIN_MAX_VALUE_NOT_RELEVANT_FOR_MANU_MODE,
762
+ Field.OPTIMUM_START_STOP: Parameter.OPTIMUM_START_STOP,
763
+ Field.PARTY_MODE: Parameter.PARTY_MODE,
764
+ Field.SETPOINT: Parameter.SET_POINT_TEMPERATURE,
765
+ Field.SET_POINT_MODE: Parameter.SET_POINT_MODE,
766
+ Field.TEMPERATURE_MAXIMUM: Parameter.TEMPERATURE_MAXIMUM,
767
+ Field.TEMPERATURE_MINIMUM: Parameter.TEMPERATURE_MINIMUM,
768
+ Field.TEMPERATURE_OFFSET: Parameter.TEMPERATURE_OFFSET,
769
+ },
770
+ visible_fields={
771
+ Field.HEATING_COOLING: Parameter.HEATING_COOLING,
772
+ Field.HUMIDITY: Parameter.HUMIDITY,
773
+ Field.TEMPERATURE: Parameter.ACTUAL_TEMPERATURE,
774
+ },
775
+ channel_fields={
776
+ 0: {
777
+ Field.LEVEL: Parameter.LEVEL,
778
+ },
779
+ 3: {
780
+ Field.STATE: Parameter.STATE,
781
+ },
782
+ },
783
+ ),
784
+ include_default_data_points=False,
785
+ )
786
+
787
+ RF_THERMOSTAT_CONFIG: Final = ProfileConfig(
788
+ profile_type=DeviceProfile.RF_THERMOSTAT,
789
+ channel_group=ChannelGroupConfig(
790
+ fields={
791
+ Field.AUTO_MODE: Parameter.AUTO_MODE,
792
+ Field.BOOST_MODE: Parameter.BOOST_MODE,
793
+ Field.COMFORT_MODE: Parameter.COMFORT_MODE,
794
+ Field.CONTROL_MODE: Parameter.CONTROL_MODE,
795
+ Field.LOWERING_MODE: Parameter.LOWERING_MODE,
796
+ Field.MANU_MODE: Parameter.MANU_MODE,
797
+ Field.SETPOINT: Parameter.SET_TEMPERATURE,
798
+ },
799
+ channel_fields={
800
+ None: {
801
+ Field.MIN_MAX_VALUE_NOT_RELEVANT_FOR_MANU_MODE: Parameter.MIN_MAX_VALUE_NOT_RELEVANT_FOR_MANU_MODE,
802
+ Field.TEMPERATURE_MAXIMUM: Parameter.TEMPERATURE_MAXIMUM,
803
+ Field.TEMPERATURE_MINIMUM: Parameter.TEMPERATURE_MINIMUM,
804
+ Field.TEMPERATURE_OFFSET: Parameter.TEMPERATURE_OFFSET,
805
+ Field.WEEK_PROGRAM_POINTER: Parameter.WEEK_PROGRAM_POINTER,
806
+ },
807
+ },
808
+ visible_fields={
809
+ Field.HUMIDITY: Parameter.ACTUAL_HUMIDITY,
810
+ Field.TEMPERATURE: Parameter.ACTUAL_TEMPERATURE,
811
+ },
812
+ visible_channel_fields={
813
+ 0: {
814
+ Field.VALVE_STATE: Parameter.VALVE_STATE,
815
+ },
816
+ },
817
+ ),
818
+ )
819
+
820
+ RF_THERMOSTAT_GROUP_CONFIG: Final = ProfileConfig(
821
+ profile_type=DeviceProfile.RF_THERMOSTAT_GROUP,
822
+ channel_group=ChannelGroupConfig(
823
+ fields={
824
+ Field.AUTO_MODE: Parameter.AUTO_MODE,
825
+ Field.BOOST_MODE: Parameter.BOOST_MODE,
826
+ Field.COMFORT_MODE: Parameter.COMFORT_MODE,
827
+ Field.CONTROL_MODE: Parameter.CONTROL_MODE,
828
+ Field.LOWERING_MODE: Parameter.LOWERING_MODE,
829
+ Field.MANU_MODE: Parameter.MANU_MODE,
830
+ Field.SETPOINT: Parameter.SET_TEMPERATURE,
831
+ },
832
+ channel_fields={
833
+ None: {
834
+ Field.MIN_MAX_VALUE_NOT_RELEVANT_FOR_MANU_MODE: Parameter.MIN_MAX_VALUE_NOT_RELEVANT_FOR_MANU_MODE,
835
+ Field.TEMPERATURE_MAXIMUM: Parameter.TEMPERATURE_MAXIMUM,
836
+ Field.TEMPERATURE_MINIMUM: Parameter.TEMPERATURE_MINIMUM,
837
+ Field.TEMPERATURE_OFFSET: Parameter.TEMPERATURE_OFFSET,
838
+ Field.WEEK_PROGRAM_POINTER: Parameter.WEEK_PROGRAM_POINTER,
839
+ },
840
+ },
841
+ visible_fields={
842
+ Field.HUMIDITY: Parameter.ACTUAL_HUMIDITY,
843
+ Field.TEMPERATURE: Parameter.ACTUAL_TEMPERATURE,
844
+ },
845
+ visible_channel_fields={
846
+ 0: {
847
+ Field.VALVE_STATE: Parameter.VALVE_STATE,
848
+ },
849
+ },
850
+ ),
851
+ include_default_data_points=False,
852
+ )
853
+
854
+ SIMPLE_RF_THERMOSTAT_CONFIG: Final = ProfileConfig(
855
+ profile_type=DeviceProfile.SIMPLE_RF_THERMOSTAT,
856
+ channel_group=ChannelGroupConfig(
857
+ visible_fields={
858
+ Field.HUMIDITY: Parameter.HUMIDITY,
859
+ Field.TEMPERATURE: Parameter.TEMPERATURE,
860
+ },
861
+ channel_fields={
862
+ 1: {
863
+ Field.SETPOINT: Parameter.SETPOINT,
864
+ },
865
+ },
866
+ ),
867
+ )
868
+
869
+
870
+ # =============================================================================
871
+ # Default Data Points
872
+ # =============================================================================
873
+
874
+ # These parameters are added to all custom data points by default
875
+ # (unless include_default_data_points=False in ProfileConfig)
876
+ DEFAULT_DATA_POINTS: Final[Mapping[int | tuple[int, ...], tuple[Parameter, ...]]] = {
877
+ 0: (
878
+ Parameter.ACTUAL_TEMPERATURE,
879
+ Parameter.DUTY_CYCLE,
880
+ Parameter.DUTYCYCLE,
881
+ Parameter.LOW_BAT,
882
+ Parameter.LOWBAT,
883
+ Parameter.OPERATING_VOLTAGE,
884
+ Parameter.RSSI_DEVICE,
885
+ Parameter.RSSI_PEER,
886
+ Parameter.SABOTAGE,
887
+ Parameter.TIME_OF_OPERATION,
888
+ ),
889
+ 2: (Parameter.BATTERY_STATE,),
890
+ 4: (Parameter.BATTERY_STATE,),
891
+ }
892
+
893
+
894
+ # =============================================================================
895
+ # Profile Registry
896
+ # =============================================================================
897
+
898
+ PROFILE_CONFIGS: Final[ProfileRegistry] = {
899
+ # Button Lock
900
+ DeviceProfile.IP_BUTTON_LOCK: IP_BUTTON_LOCK_CONFIG,
901
+ DeviceProfile.RF_BUTTON_LOCK: RF_BUTTON_LOCK_CONFIG,
902
+ # Cover
903
+ DeviceProfile.IP_COVER: IP_COVER_CONFIG,
904
+ DeviceProfile.IP_GARAGE: IP_GARAGE_CONFIG,
905
+ DeviceProfile.IP_HDM: IP_HDM_CONFIG,
906
+ DeviceProfile.RF_COVER: RF_COVER_CONFIG,
907
+ # Dimmer/Light
908
+ DeviceProfile.IP_DIMMER: IP_DIMMER_CONFIG,
909
+ DeviceProfile.IP_DRG_DALI: IP_DRG_DALI_CONFIG,
910
+ DeviceProfile.IP_FIXED_COLOR_LIGHT: IP_FIXED_COLOR_LIGHT_CONFIG,
911
+ DeviceProfile.IP_RGBW_LIGHT: IP_RGBW_LIGHT_CONFIG,
912
+ DeviceProfile.IP_SIMPLE_FIXED_COLOR_LIGHT: IP_SIMPLE_FIXED_COLOR_LIGHT_CONFIG,
913
+ DeviceProfile.IP_SIMPLE_FIXED_COLOR_LIGHT_WIRED: IP_SIMPLE_FIXED_COLOR_LIGHT_WIRED_CONFIG,
914
+ DeviceProfile.RF_DIMMER: RF_DIMMER_CONFIG,
915
+ DeviceProfile.RF_DIMMER_COLOR: RF_DIMMER_COLOR_CONFIG,
916
+ DeviceProfile.RF_DIMMER_COLOR_FIXED: RF_DIMMER_COLOR_FIXED_CONFIG,
917
+ DeviceProfile.RF_DIMMER_COLOR_TEMP: RF_DIMMER_COLOR_TEMP_CONFIG,
918
+ DeviceProfile.RF_DIMMER_WITH_VIRT_CHANNEL: RF_DIMMER_WITH_VIRT_CHANNEL_CONFIG,
919
+ # Switch
920
+ DeviceProfile.IP_IRRIGATION_VALVE: IP_IRRIGATION_VALVE_CONFIG,
921
+ DeviceProfile.IP_SWITCH: IP_SWITCH_CONFIG,
922
+ DeviceProfile.RF_SWITCH: RF_SWITCH_CONFIG,
923
+ # Lock
924
+ DeviceProfile.IP_LOCK: IP_LOCK_CONFIG,
925
+ DeviceProfile.RF_LOCK: RF_LOCK_CONFIG,
926
+ # Siren
927
+ DeviceProfile.IP_SIREN: IP_SIREN_CONFIG,
928
+ DeviceProfile.IP_SIREN_SMOKE: IP_SIREN_SMOKE_CONFIG,
929
+ # Sound Player
930
+ DeviceProfile.IP_SOUND_PLAYER: IP_SOUND_PLAYER_CONFIG,
931
+ DeviceProfile.IP_SOUND_PLAYER_LED: IP_SOUND_PLAYER_LED_CONFIG,
932
+ # Text Display
933
+ DeviceProfile.IP_TEXT_DISPLAY: IP_TEXT_DISPLAY_CONFIG,
934
+ # Thermostat
935
+ DeviceProfile.IP_THERMOSTAT: IP_THERMOSTAT_CONFIG,
936
+ DeviceProfile.IP_THERMOSTAT_GROUP: IP_THERMOSTAT_GROUP_CONFIG,
937
+ DeviceProfile.RF_THERMOSTAT: RF_THERMOSTAT_CONFIG,
938
+ DeviceProfile.RF_THERMOSTAT_GROUP: RF_THERMOSTAT_GROUP_CONFIG,
939
+ DeviceProfile.SIMPLE_RF_THERMOSTAT: SIMPLE_RF_THERMOSTAT_CONFIG,
940
+ }
941
+
942
+
943
+ def get_profile_config(*, profile_type: DeviceProfile) -> ProfileConfig:
944
+ """Return the profile configuration for a given profile type."""
945
+ return PROFILE_CONFIGS[profile_type]