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.
- conson_xp-1.18.0.dist-info/METADATA +412 -0
- conson_xp-1.18.0.dist-info/RECORD +176 -0
- conson_xp-1.18.0.dist-info/WHEEL +4 -0
- conson_xp-1.18.0.dist-info/entry_points.txt +5 -0
- conson_xp-1.18.0.dist-info/licenses/LICENSE +29 -0
- xp/__init__.py +9 -0
- xp/cli/__init__.py +5 -0
- xp/cli/__main__.py +6 -0
- xp/cli/commands/__init__.py +153 -0
- xp/cli/commands/conbus/__init__.py +25 -0
- xp/cli/commands/conbus/conbus.py +128 -0
- xp/cli/commands/conbus/conbus_actiontable_commands.py +233 -0
- xp/cli/commands/conbus/conbus_autoreport_commands.py +108 -0
- xp/cli/commands/conbus/conbus_blink_commands.py +163 -0
- xp/cli/commands/conbus/conbus_config_commands.py +29 -0
- xp/cli/commands/conbus/conbus_custom_commands.py +57 -0
- xp/cli/commands/conbus/conbus_datapoint_commands.py +113 -0
- xp/cli/commands/conbus/conbus_discover_commands.py +61 -0
- xp/cli/commands/conbus/conbus_event_commands.py +81 -0
- xp/cli/commands/conbus/conbus_lightlevel_commands.py +207 -0
- xp/cli/commands/conbus/conbus_linknumber_commands.py +102 -0
- xp/cli/commands/conbus/conbus_modulenumber_commands.py +104 -0
- xp/cli/commands/conbus/conbus_msactiontable_commands.py +94 -0
- xp/cli/commands/conbus/conbus_output_commands.py +163 -0
- xp/cli/commands/conbus/conbus_raw_commands.py +62 -0
- xp/cli/commands/conbus/conbus_receive_commands.py +59 -0
- xp/cli/commands/conbus/conbus_scan_commands.py +58 -0
- xp/cli/commands/file_commands.py +186 -0
- xp/cli/commands/homekit/__init__.py +3 -0
- xp/cli/commands/homekit/homekit.py +118 -0
- xp/cli/commands/homekit/homekit_start_commands.py +43 -0
- xp/cli/commands/module_commands.py +187 -0
- xp/cli/commands/reverse_proxy_commands.py +178 -0
- xp/cli/commands/server/__init__.py +3 -0
- xp/cli/commands/server/server_commands.py +135 -0
- xp/cli/commands/telegram/__init__.py +5 -0
- xp/cli/commands/telegram/telegram.py +41 -0
- xp/cli/commands/telegram/telegram_blink_commands.py +79 -0
- xp/cli/commands/telegram/telegram_checksum_commands.py +112 -0
- xp/cli/commands/telegram/telegram_discover_commands.py +41 -0
- xp/cli/commands/telegram/telegram_linknumber_commands.py +86 -0
- xp/cli/commands/telegram/telegram_parse_commands.py +75 -0
- xp/cli/commands/telegram/telegram_version_commands.py +52 -0
- xp/cli/main.py +87 -0
- xp/cli/utils/__init__.py +1 -0
- xp/cli/utils/click_tree.py +57 -0
- xp/cli/utils/datapoint_type_choice.py +57 -0
- xp/cli/utils/decorators.py +351 -0
- xp/cli/utils/error_handlers.py +201 -0
- xp/cli/utils/formatters.py +312 -0
- xp/cli/utils/module_type_choice.py +56 -0
- xp/cli/utils/serial_number_type.py +52 -0
- xp/cli/utils/system_function_choice.py +57 -0
- xp/cli/utils/xp_module_type.py +53 -0
- xp/connection/__init__.py +13 -0
- xp/connection/exceptions.py +22 -0
- xp/models/__init__.py +36 -0
- xp/models/actiontable/__init__.py +1 -0
- xp/models/actiontable/actiontable.py +43 -0
- xp/models/actiontable/msactiontable_xp20.py +53 -0
- xp/models/actiontable/msactiontable_xp24.py +58 -0
- xp/models/actiontable/msactiontable_xp33.py +65 -0
- xp/models/conbus/__init__.py +1 -0
- xp/models/conbus/conbus.py +87 -0
- xp/models/conbus/conbus_autoreport.py +67 -0
- xp/models/conbus/conbus_blink.py +80 -0
- xp/models/conbus/conbus_client_config.py +55 -0
- xp/models/conbus/conbus_connection_status.py +40 -0
- xp/models/conbus/conbus_custom.py +58 -0
- xp/models/conbus/conbus_datapoint.py +89 -0
- xp/models/conbus/conbus_discover.py +64 -0
- xp/models/conbus/conbus_event_raw.py +47 -0
- xp/models/conbus/conbus_lightlevel.py +52 -0
- xp/models/conbus/conbus_linknumber.py +54 -0
- xp/models/conbus/conbus_output.py +57 -0
- xp/models/conbus/conbus_raw.py +45 -0
- xp/models/conbus/conbus_receive.py +42 -0
- xp/models/conbus/conbus_writeconfig.py +60 -0
- xp/models/homekit/__init__.py +1 -0
- xp/models/homekit/homekit_accessory.py +35 -0
- xp/models/homekit/homekit_config.py +106 -0
- xp/models/homekit/homekit_conson_config.py +86 -0
- xp/models/log_entry.py +130 -0
- xp/models/protocol/__init__.py +1 -0
- xp/models/protocol/conbus_protocol.py +312 -0
- xp/models/response.py +42 -0
- xp/models/telegram/__init__.py +1 -0
- xp/models/telegram/action_type.py +31 -0
- xp/models/telegram/datapoint_type.py +82 -0
- xp/models/telegram/event_telegram.py +140 -0
- xp/models/telegram/event_type.py +15 -0
- xp/models/telegram/input_action_type.py +69 -0
- xp/models/telegram/input_type.py +17 -0
- xp/models/telegram/module_type.py +188 -0
- xp/models/telegram/module_type_code.py +205 -0
- xp/models/telegram/output_telegram.py +103 -0
- xp/models/telegram/reply_telegram.py +297 -0
- xp/models/telegram/system_function.py +116 -0
- xp/models/telegram/system_telegram.py +94 -0
- xp/models/telegram/telegram.py +28 -0
- xp/models/telegram/telegram_type.py +19 -0
- xp/models/telegram/timeparam_type.py +51 -0
- xp/models/write_config_type.py +33 -0
- xp/services/__init__.py +26 -0
- xp/services/actiontable/__init__.py +1 -0
- xp/services/actiontable/actiontable_serializer.py +273 -0
- xp/services/actiontable/msactiontable_serializer.py +7 -0
- xp/services/actiontable/msactiontable_xp20_serializer.py +169 -0
- xp/services/actiontable/msactiontable_xp24_serializer.py +120 -0
- xp/services/actiontable/msactiontable_xp33_serializer.py +239 -0
- xp/services/conbus/__init__.py +1 -0
- xp/services/conbus/actiontable/__init__.py +1 -0
- xp/services/conbus/actiontable/actiontable_download_service.py +158 -0
- xp/services/conbus/actiontable/actiontable_list_service.py +91 -0
- xp/services/conbus/actiontable/actiontable_show_service.py +89 -0
- xp/services/conbus/actiontable/actiontable_upload_service.py +211 -0
- xp/services/conbus/actiontable/msactiontable_service.py +232 -0
- xp/services/conbus/conbus_blink_all_service.py +181 -0
- xp/services/conbus/conbus_blink_service.py +158 -0
- xp/services/conbus/conbus_custom_service.py +156 -0
- xp/services/conbus/conbus_datapoint_queryall_service.py +182 -0
- xp/services/conbus/conbus_datapoint_service.py +170 -0
- xp/services/conbus/conbus_discover_service.py +312 -0
- xp/services/conbus/conbus_event_raw_service.py +181 -0
- xp/services/conbus/conbus_output_service.py +194 -0
- xp/services/conbus/conbus_raw_service.py +122 -0
- xp/services/conbus/conbus_receive_service.py +115 -0
- xp/services/conbus/conbus_scan_service.py +150 -0
- xp/services/conbus/write_config_service.py +194 -0
- xp/services/homekit/__init__.py +1 -0
- xp/services/homekit/homekit_cache_service.py +307 -0
- xp/services/homekit/homekit_conbus_service.py +93 -0
- xp/services/homekit/homekit_config_validator.py +310 -0
- xp/services/homekit/homekit_conson_validator.py +121 -0
- xp/services/homekit/homekit_dimminglight.py +182 -0
- xp/services/homekit/homekit_dimminglight_service.py +148 -0
- xp/services/homekit/homekit_hap_service.py +342 -0
- xp/services/homekit/homekit_lightbulb.py +120 -0
- xp/services/homekit/homekit_lightbulb_service.py +86 -0
- xp/services/homekit/homekit_module_service.py +56 -0
- xp/services/homekit/homekit_outlet.py +168 -0
- xp/services/homekit/homekit_outlet_service.py +121 -0
- xp/services/homekit/homekit_service.py +359 -0
- xp/services/log_file_service.py +309 -0
- xp/services/module_type_service.py +257 -0
- xp/services/protocol/__init__.py +21 -0
- xp/services/protocol/conbus_event_protocol.py +360 -0
- xp/services/protocol/conbus_protocol.py +318 -0
- xp/services/protocol/protocol_factory.py +78 -0
- xp/services/protocol/telegram_protocol.py +264 -0
- xp/services/reverse_proxy_service.py +435 -0
- xp/services/server/__init__.py +1 -0
- xp/services/server/base_server_service.py +366 -0
- xp/services/server/cp20_server_service.py +65 -0
- xp/services/server/device_service_factory.py +94 -0
- xp/services/server/server_service.py +428 -0
- xp/services/server/xp130_server_service.py +67 -0
- xp/services/server/xp20_server_service.py +92 -0
- xp/services/server/xp230_server_service.py +58 -0
- xp/services/server/xp24_server_service.py +245 -0
- xp/services/server/xp33_server_service.py +535 -0
- xp/services/telegram/__init__.py +1 -0
- xp/services/telegram/telegram_blink_service.py +138 -0
- xp/services/telegram/telegram_checksum_service.py +149 -0
- xp/services/telegram/telegram_datapoint_service.py +82 -0
- xp/services/telegram/telegram_discover_service.py +277 -0
- xp/services/telegram/telegram_link_number_service.py +216 -0
- xp/services/telegram/telegram_output_service.py +322 -0
- xp/services/telegram/telegram_service.py +380 -0
- xp/services/telegram/telegram_version_service.py +288 -0
- xp/utils/__init__.py +12 -0
- xp/utils/checksum.py +61 -0
- xp/utils/dependencies.py +531 -0
- xp/utils/event_helper.py +31 -0
- xp/utils/serialization.py +205 -0
- 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
|
+
}
|