conson-xp 1.18.0__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 (176) hide show
  1. conson_xp-1.18.0.dist-info/METADATA +412 -0
  2. conson_xp-1.18.0.dist-info/RECORD +176 -0
  3. conson_xp-1.18.0.dist-info/WHEEL +4 -0
  4. conson_xp-1.18.0.dist-info/entry_points.txt +5 -0
  5. conson_xp-1.18.0.dist-info/licenses/LICENSE +29 -0
  6. xp/__init__.py +9 -0
  7. xp/cli/__init__.py +5 -0
  8. xp/cli/__main__.py +6 -0
  9. xp/cli/commands/__init__.py +153 -0
  10. xp/cli/commands/conbus/__init__.py +25 -0
  11. xp/cli/commands/conbus/conbus.py +128 -0
  12. xp/cli/commands/conbus/conbus_actiontable_commands.py +233 -0
  13. xp/cli/commands/conbus/conbus_autoreport_commands.py +108 -0
  14. xp/cli/commands/conbus/conbus_blink_commands.py +163 -0
  15. xp/cli/commands/conbus/conbus_config_commands.py +29 -0
  16. xp/cli/commands/conbus/conbus_custom_commands.py +57 -0
  17. xp/cli/commands/conbus/conbus_datapoint_commands.py +113 -0
  18. xp/cli/commands/conbus/conbus_discover_commands.py +61 -0
  19. xp/cli/commands/conbus/conbus_event_commands.py +81 -0
  20. xp/cli/commands/conbus/conbus_lightlevel_commands.py +207 -0
  21. xp/cli/commands/conbus/conbus_linknumber_commands.py +102 -0
  22. xp/cli/commands/conbus/conbus_modulenumber_commands.py +104 -0
  23. xp/cli/commands/conbus/conbus_msactiontable_commands.py +94 -0
  24. xp/cli/commands/conbus/conbus_output_commands.py +163 -0
  25. xp/cli/commands/conbus/conbus_raw_commands.py +62 -0
  26. xp/cli/commands/conbus/conbus_receive_commands.py +59 -0
  27. xp/cli/commands/conbus/conbus_scan_commands.py +58 -0
  28. xp/cli/commands/file_commands.py +186 -0
  29. xp/cli/commands/homekit/__init__.py +3 -0
  30. xp/cli/commands/homekit/homekit.py +118 -0
  31. xp/cli/commands/homekit/homekit_start_commands.py +43 -0
  32. xp/cli/commands/module_commands.py +187 -0
  33. xp/cli/commands/reverse_proxy_commands.py +178 -0
  34. xp/cli/commands/server/__init__.py +3 -0
  35. xp/cli/commands/server/server_commands.py +135 -0
  36. xp/cli/commands/telegram/__init__.py +5 -0
  37. xp/cli/commands/telegram/telegram.py +41 -0
  38. xp/cli/commands/telegram/telegram_blink_commands.py +79 -0
  39. xp/cli/commands/telegram/telegram_checksum_commands.py +112 -0
  40. xp/cli/commands/telegram/telegram_discover_commands.py +41 -0
  41. xp/cli/commands/telegram/telegram_linknumber_commands.py +86 -0
  42. xp/cli/commands/telegram/telegram_parse_commands.py +75 -0
  43. xp/cli/commands/telegram/telegram_version_commands.py +52 -0
  44. xp/cli/main.py +87 -0
  45. xp/cli/utils/__init__.py +1 -0
  46. xp/cli/utils/click_tree.py +57 -0
  47. xp/cli/utils/datapoint_type_choice.py +57 -0
  48. xp/cli/utils/decorators.py +351 -0
  49. xp/cli/utils/error_handlers.py +201 -0
  50. xp/cli/utils/formatters.py +312 -0
  51. xp/cli/utils/module_type_choice.py +56 -0
  52. xp/cli/utils/serial_number_type.py +52 -0
  53. xp/cli/utils/system_function_choice.py +57 -0
  54. xp/cli/utils/xp_module_type.py +53 -0
  55. xp/connection/__init__.py +13 -0
  56. xp/connection/exceptions.py +22 -0
  57. xp/models/__init__.py +36 -0
  58. xp/models/actiontable/__init__.py +1 -0
  59. xp/models/actiontable/actiontable.py +43 -0
  60. xp/models/actiontable/msactiontable_xp20.py +53 -0
  61. xp/models/actiontable/msactiontable_xp24.py +58 -0
  62. xp/models/actiontable/msactiontable_xp33.py +65 -0
  63. xp/models/conbus/__init__.py +1 -0
  64. xp/models/conbus/conbus.py +87 -0
  65. xp/models/conbus/conbus_autoreport.py +67 -0
  66. xp/models/conbus/conbus_blink.py +80 -0
  67. xp/models/conbus/conbus_client_config.py +55 -0
  68. xp/models/conbus/conbus_connection_status.py +40 -0
  69. xp/models/conbus/conbus_custom.py +58 -0
  70. xp/models/conbus/conbus_datapoint.py +89 -0
  71. xp/models/conbus/conbus_discover.py +64 -0
  72. xp/models/conbus/conbus_event_raw.py +47 -0
  73. xp/models/conbus/conbus_lightlevel.py +52 -0
  74. xp/models/conbus/conbus_linknumber.py +54 -0
  75. xp/models/conbus/conbus_output.py +57 -0
  76. xp/models/conbus/conbus_raw.py +45 -0
  77. xp/models/conbus/conbus_receive.py +42 -0
  78. xp/models/conbus/conbus_writeconfig.py +60 -0
  79. xp/models/homekit/__init__.py +1 -0
  80. xp/models/homekit/homekit_accessory.py +35 -0
  81. xp/models/homekit/homekit_config.py +106 -0
  82. xp/models/homekit/homekit_conson_config.py +86 -0
  83. xp/models/log_entry.py +130 -0
  84. xp/models/protocol/__init__.py +1 -0
  85. xp/models/protocol/conbus_protocol.py +312 -0
  86. xp/models/response.py +42 -0
  87. xp/models/telegram/__init__.py +1 -0
  88. xp/models/telegram/action_type.py +31 -0
  89. xp/models/telegram/datapoint_type.py +82 -0
  90. xp/models/telegram/event_telegram.py +140 -0
  91. xp/models/telegram/event_type.py +15 -0
  92. xp/models/telegram/input_action_type.py +69 -0
  93. xp/models/telegram/input_type.py +17 -0
  94. xp/models/telegram/module_type.py +188 -0
  95. xp/models/telegram/module_type_code.py +205 -0
  96. xp/models/telegram/output_telegram.py +103 -0
  97. xp/models/telegram/reply_telegram.py +297 -0
  98. xp/models/telegram/system_function.py +116 -0
  99. xp/models/telegram/system_telegram.py +94 -0
  100. xp/models/telegram/telegram.py +28 -0
  101. xp/models/telegram/telegram_type.py +19 -0
  102. xp/models/telegram/timeparam_type.py +51 -0
  103. xp/models/write_config_type.py +33 -0
  104. xp/services/__init__.py +26 -0
  105. xp/services/actiontable/__init__.py +1 -0
  106. xp/services/actiontable/actiontable_serializer.py +273 -0
  107. xp/services/actiontable/msactiontable_serializer.py +7 -0
  108. xp/services/actiontable/msactiontable_xp20_serializer.py +169 -0
  109. xp/services/actiontable/msactiontable_xp24_serializer.py +120 -0
  110. xp/services/actiontable/msactiontable_xp33_serializer.py +239 -0
  111. xp/services/conbus/__init__.py +1 -0
  112. xp/services/conbus/actiontable/__init__.py +1 -0
  113. xp/services/conbus/actiontable/actiontable_download_service.py +158 -0
  114. xp/services/conbus/actiontable/actiontable_list_service.py +91 -0
  115. xp/services/conbus/actiontable/actiontable_show_service.py +89 -0
  116. xp/services/conbus/actiontable/actiontable_upload_service.py +211 -0
  117. xp/services/conbus/actiontable/msactiontable_service.py +232 -0
  118. xp/services/conbus/conbus_blink_all_service.py +181 -0
  119. xp/services/conbus/conbus_blink_service.py +158 -0
  120. xp/services/conbus/conbus_custom_service.py +156 -0
  121. xp/services/conbus/conbus_datapoint_queryall_service.py +182 -0
  122. xp/services/conbus/conbus_datapoint_service.py +170 -0
  123. xp/services/conbus/conbus_discover_service.py +312 -0
  124. xp/services/conbus/conbus_event_raw_service.py +181 -0
  125. xp/services/conbus/conbus_output_service.py +194 -0
  126. xp/services/conbus/conbus_raw_service.py +122 -0
  127. xp/services/conbus/conbus_receive_service.py +115 -0
  128. xp/services/conbus/conbus_scan_service.py +150 -0
  129. xp/services/conbus/write_config_service.py +194 -0
  130. xp/services/homekit/__init__.py +1 -0
  131. xp/services/homekit/homekit_cache_service.py +307 -0
  132. xp/services/homekit/homekit_conbus_service.py +93 -0
  133. xp/services/homekit/homekit_config_validator.py +310 -0
  134. xp/services/homekit/homekit_conson_validator.py +121 -0
  135. xp/services/homekit/homekit_dimminglight.py +182 -0
  136. xp/services/homekit/homekit_dimminglight_service.py +148 -0
  137. xp/services/homekit/homekit_hap_service.py +342 -0
  138. xp/services/homekit/homekit_lightbulb.py +120 -0
  139. xp/services/homekit/homekit_lightbulb_service.py +86 -0
  140. xp/services/homekit/homekit_module_service.py +56 -0
  141. xp/services/homekit/homekit_outlet.py +168 -0
  142. xp/services/homekit/homekit_outlet_service.py +121 -0
  143. xp/services/homekit/homekit_service.py +359 -0
  144. xp/services/log_file_service.py +309 -0
  145. xp/services/module_type_service.py +257 -0
  146. xp/services/protocol/__init__.py +21 -0
  147. xp/services/protocol/conbus_event_protocol.py +360 -0
  148. xp/services/protocol/conbus_protocol.py +318 -0
  149. xp/services/protocol/protocol_factory.py +78 -0
  150. xp/services/protocol/telegram_protocol.py +264 -0
  151. xp/services/reverse_proxy_service.py +435 -0
  152. xp/services/server/__init__.py +1 -0
  153. xp/services/server/base_server_service.py +366 -0
  154. xp/services/server/cp20_server_service.py +65 -0
  155. xp/services/server/device_service_factory.py +94 -0
  156. xp/services/server/server_service.py +428 -0
  157. xp/services/server/xp130_server_service.py +67 -0
  158. xp/services/server/xp20_server_service.py +92 -0
  159. xp/services/server/xp230_server_service.py +58 -0
  160. xp/services/server/xp24_server_service.py +245 -0
  161. xp/services/server/xp33_server_service.py +535 -0
  162. xp/services/telegram/__init__.py +1 -0
  163. xp/services/telegram/telegram_blink_service.py +138 -0
  164. xp/services/telegram/telegram_checksum_service.py +149 -0
  165. xp/services/telegram/telegram_datapoint_service.py +82 -0
  166. xp/services/telegram/telegram_discover_service.py +277 -0
  167. xp/services/telegram/telegram_link_number_service.py +216 -0
  168. xp/services/telegram/telegram_output_service.py +322 -0
  169. xp/services/telegram/telegram_service.py +380 -0
  170. xp/services/telegram/telegram_version_service.py +288 -0
  171. xp/utils/__init__.py +12 -0
  172. xp/utils/checksum.py +61 -0
  173. xp/utils/dependencies.py +531 -0
  174. xp/utils/event_helper.py +31 -0
  175. xp/utils/serialization.py +205 -0
  176. xp/utils/time_utils.py +134 -0
@@ -0,0 +1,245 @@
1
+ """XP24 Server Service for device emulation.
2
+
3
+ This service provides XP24-specific device emulation functionality,
4
+ including response generation and device configuration handling.
5
+ """
6
+
7
+ from typing import Dict, Optional
8
+
9
+ from xp.models import ModuleTypeCode
10
+ from xp.models.actiontable.msactiontable_xp24 import InputAction, Xp24MsActionTable
11
+ from xp.models.telegram.datapoint_type import DataPointType
12
+ from xp.models.telegram.input_action_type import InputActionType
13
+ from xp.models.telegram.system_function import SystemFunction
14
+ from xp.models.telegram.system_telegram import SystemTelegram
15
+ from xp.models.telegram.timeparam_type import TimeParam
16
+ from xp.services.actiontable.msactiontable_xp24_serializer import (
17
+ Xp24MsActionTableSerializer,
18
+ )
19
+ from xp.services.server.base_server_service import BaseServerService
20
+
21
+
22
+ class XP24ServerError(Exception):
23
+ """Raised when XP24 server operations fail."""
24
+
25
+ pass
26
+
27
+
28
+ class XP24Output:
29
+ """Represents an XP24 output state.
30
+
31
+ Attributes:
32
+ state: Current state of the output (True=on, False=off).
33
+ """
34
+
35
+ state: bool = False
36
+
37
+
38
+ class XP24ServerService(BaseServerService):
39
+ """
40
+ XP24 device emulation service.
41
+
42
+ Generates XP24-specific responses, handles XP24 device configuration,
43
+ and implements XP24 telegram format.
44
+ """
45
+
46
+ def __init__(
47
+ self,
48
+ serial_number: str,
49
+ _variant: str = "",
50
+ msactiontable_serializer: Optional[Xp24MsActionTableSerializer] = None,
51
+ ):
52
+ """Initialize XP24 server service.
53
+
54
+ Args:
55
+ serial_number: The device serial number.
56
+ _variant: Reserved parameter for consistency (unused).
57
+ msactiontable_serializer: MsActionTable serializer (injected via DI).
58
+ """
59
+ super().__init__(serial_number)
60
+ self.device_type = "XP24"
61
+ self.module_type_code = ModuleTypeCode.XP24
62
+ self.autoreport_status = True
63
+ self.firmware_version = "XP24_V0.34.03"
64
+ self.output_0: XP24Output = XP24Output()
65
+ self.output_1: XP24Output = XP24Output()
66
+ self.output_2: XP24Output = XP24Output()
67
+ self.output_3: XP24Output = XP24Output()
68
+
69
+ # MsActionTable support
70
+ self.msactiontable_serializer = (
71
+ msactiontable_serializer or Xp24MsActionTableSerializer()
72
+ )
73
+ self.msactiontable = self._get_default_msactiontable()
74
+
75
+ def _handle_device_specific_action_request(
76
+ self, request: SystemTelegram
77
+ ) -> Optional[str]:
78
+ """Handle XP24-specific data requests."""
79
+ telegrams = self._handle_action_module_output_state(request.data)
80
+ self.logger.debug(
81
+ f"Generated {self.device_type} module type responses: {telegrams}"
82
+ )
83
+ return telegrams
84
+
85
+ def _handle_action_module_output_state(self, data_value: str) -> str:
86
+ """Handle XP24-specific module output state."""
87
+ output_number = int(data_value[:2])
88
+ output_state = data_value[2:]
89
+ if output_number not in range(0, 4):
90
+ return self._build_ack_nak_response_telegram(False)
91
+
92
+ if output_state not in ("AA", "AB"):
93
+ return self._build_ack_nak_response_telegram(False)
94
+
95
+ output = (self.output_0, self.output_1, self.output_2, self.output_3)[
96
+ output_number
97
+ ]
98
+ previous_state = output.state
99
+ output.state = True if output_state == "AB" else False
100
+ state_changed = previous_state != output.state
101
+
102
+ telegrams = self._build_ack_nak_response_telegram(True)
103
+ if state_changed and self.autoreport_status:
104
+ telegrams += self._build_make_break_response_telegram(
105
+ output.state, output_number
106
+ )
107
+
108
+ return telegrams
109
+
110
+ def _build_ack_nak_response_telegram(self, ack_or_nak: bool) -> str:
111
+ """Build a complete ACK or NAK response telegram with checksum.
112
+
113
+ Args:
114
+ ack_or_nak: true: ACK telegram response, false: NAK telegram response.
115
+
116
+ Returns:
117
+ The complete telegram with checksum enclosed in angle brackets.
118
+ """
119
+ data_value = (
120
+ SystemFunction.ACK.value if ack_or_nak else SystemFunction.NAK.value
121
+ )
122
+ data_part = f"R{self.serial_number}" f"F{data_value:02}D"
123
+ return self._build_response_telegram(data_part)
124
+
125
+ def _build_make_break_response_telegram(
126
+ self, make_or_break: bool, output_number: int
127
+ ) -> str:
128
+ """Build a complete ACK or NAK response telegram with checksum.
129
+
130
+ Args:
131
+ make_or_break: true: MAKE event response, false: BREAK event response.
132
+ output_number: output concerned
133
+
134
+ Returns:
135
+ The complete event telegram with checksum enclosed in angle brackets.
136
+ """
137
+ data_value = "M" if make_or_break else "B"
138
+ data_part = (
139
+ f"E{self.module_type_code.value:02}"
140
+ f"L{self.link_number:02}"
141
+ f"I{output_number:02}"
142
+ f"{data_value}"
143
+ )
144
+ return self._build_response_telegram(data_part)
145
+
146
+ def _handle_device_specific_data_request(
147
+ self, request: SystemTelegram
148
+ ) -> Optional[str]:
149
+ """Handle XP24-specific data requests."""
150
+ if not request.datapoint_type:
151
+ return None
152
+
153
+ datapoint_type = request.datapoint_type
154
+ handler = {
155
+ DataPointType.MODULE_OUTPUT_STATE: self._handle_read_module_output_state,
156
+ DataPointType.MODULE_STATE: self._handle_read_module_state,
157
+ DataPointType.MODULE_OPERATING_HOURS: self._handle_read_module_operating_hours,
158
+ }.get(datapoint_type)
159
+ if not handler:
160
+ return None
161
+
162
+ data_value = handler()
163
+ data_part = (
164
+ f"R{self.serial_number}"
165
+ f"F02D{datapoint_type.value}"
166
+ f"{self.module_type_code.value:02}"
167
+ f"{data_value}"
168
+ )
169
+ telegram = self._build_response_telegram(data_part)
170
+
171
+ self.logger.debug(
172
+ f"Generated {self.device_type} module type response: {telegram}"
173
+ )
174
+ return telegram
175
+
176
+ def _handle_read_module_operating_hours(self) -> str:
177
+ """Handle XP24-specific module operating hours."""
178
+ return "00:000[H],01:000[H],02:000[H],03:000[H]"
179
+
180
+ def _handle_read_module_state(self) -> str:
181
+ """Handle XP24-specific module state."""
182
+ for output in (self.output_0, self.output_1, self.output_2, self.output_3):
183
+ if output.state:
184
+ return "ON"
185
+ return "OFF"
186
+
187
+ def _handle_read_module_output_state(self) -> str:
188
+ """Handle XP24-specific module output state."""
189
+ return (
190
+ f"xxxx"
191
+ f"{1 if self.output_0.state else 0}"
192
+ f"{1 if self.output_1.state else 0}"
193
+ f"{1 if self.output_2.state else 0}"
194
+ f"{1 if self.output_3.state else 0}"
195
+ )
196
+
197
+ def _get_msactiontable_serializer(self) -> Optional[Xp24MsActionTableSerializer]:
198
+ """Get the MsActionTable serializer for XP24.
199
+
200
+ Returns:
201
+ The XP24 MsActionTable serializer instance.
202
+ """
203
+ return self.msactiontable_serializer
204
+
205
+ def _get_msactiontable(self) -> Optional[Xp24MsActionTable]:
206
+ """Get the MsActionTable for XP24.
207
+
208
+ Returns:
209
+ The XP24 MsActionTable instance.
210
+ """
211
+ return self.msactiontable
212
+
213
+ def _get_default_msactiontable(self) -> Xp24MsActionTable:
214
+ """Generate default MsActionTable configuration.
215
+
216
+ Returns:
217
+ Default XP24 MsActionTable with all inputs set to VOID.
218
+ """
219
+ return Xp24MsActionTable(
220
+ input1_action=InputAction(type=InputActionType.VOID, param=TimeParam.NONE),
221
+ input2_action=InputAction(type=InputActionType.VOID, param=TimeParam.NONE),
222
+ input3_action=InputAction(type=InputActionType.VOID, param=TimeParam.NONE),
223
+ input4_action=InputAction(type=InputActionType.VOID, param=TimeParam.NONE),
224
+ mutex12=False,
225
+ mutex34=False,
226
+ curtain12=False,
227
+ curtain34=False,
228
+ mutual_deadtime=12, # MS300
229
+ )
230
+
231
+ def get_device_info(self) -> Dict:
232
+ """Get XP24 device information.
233
+
234
+ Returns:
235
+ Dictionary containing device information.
236
+ """
237
+ return {
238
+ "serial_number": self.serial_number,
239
+ "device_type": self.device_type,
240
+ "module_type_code": self.module_type_code.value,
241
+ "firmware_version": self.firmware_version,
242
+ "status": self.device_status,
243
+ "link_number": self.link_number,
244
+ "autoreport_status": self.autoreport_status,
245
+ }