conson-xp 1.2.0__py3-none-any.whl → 1.4.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 (62) hide show
  1. {conson_xp-1.2.0.dist-info → conson_xp-1.4.0.dist-info}/METADATA +1 -5
  2. {conson_xp-1.2.0.dist-info → conson_xp-1.4.0.dist-info}/RECORD +43 -60
  3. xp/__init__.py +1 -1
  4. xp/cli/commands/__init__.py +0 -2
  5. xp/cli/commands/conbus/conbus_actiontable_commands.py +5 -3
  6. xp/cli/commands/conbus/conbus_autoreport_commands.py +39 -21
  7. xp/cli/commands/conbus/conbus_blink_commands.py +8 -8
  8. xp/cli/commands/conbus/conbus_config_commands.py +3 -1
  9. xp/cli/commands/conbus/conbus_custom_commands.py +3 -1
  10. xp/cli/commands/conbus/conbus_datapoint_commands.py +4 -2
  11. xp/cli/commands/conbus/conbus_discover_commands.py +5 -3
  12. xp/cli/commands/conbus/conbus_lightlevel_commands.py +68 -32
  13. xp/cli/commands/conbus/conbus_linknumber_commands.py +32 -17
  14. xp/cli/commands/conbus/conbus_msactiontable_commands.py +11 -4
  15. xp/cli/commands/conbus/conbus_output_commands.py +6 -2
  16. xp/cli/commands/conbus/conbus_receive_commands.py +5 -3
  17. xp/cli/commands/file_commands.py +9 -3
  18. xp/cli/commands/homekit/homekit_start_commands.py +3 -1
  19. xp/cli/commands/module_commands.py +12 -4
  20. xp/cli/commands/reverse_proxy_commands.py +3 -1
  21. xp/cli/main.py +0 -2
  22. xp/models/conbus/conbus_datapoint.py +3 -0
  23. xp/models/conbus/conbus_discover.py +19 -3
  24. xp/models/conbus/conbus_writeconfig.py +60 -0
  25. xp/models/telegram/system_telegram.py +4 -4
  26. xp/services/conbus/conbus_datapoint_service.py +9 -6
  27. xp/services/conbus/conbus_discover_service.py +120 -2
  28. xp/services/conbus/conbus_scan_service.py +1 -1
  29. xp/services/conbus/{conbus_linknumber_set_service.py → write_config_service.py} +78 -66
  30. xp/services/protocol/telegram_protocol.py +4 -4
  31. xp/services/server/base_server_service.py +9 -4
  32. xp/services/server/cp20_server_service.py +2 -1
  33. xp/services/server/server_service.py +75 -4
  34. xp/services/server/xp130_server_service.py +2 -1
  35. xp/services/server/xp20_server_service.py +2 -1
  36. xp/services/server/xp230_server_service.py +2 -1
  37. xp/services/server/xp24_server_service.py +123 -50
  38. xp/services/server/xp33_server_service.py +150 -20
  39. xp/services/telegram/telegram_datapoint_service.py +70 -0
  40. xp/utils/dependencies.py +4 -46
  41. xp/api/__init__.py +0 -1
  42. xp/api/main.py +0 -125
  43. xp/api/models/__init__.py +0 -1
  44. xp/api/models/api.py +0 -31
  45. xp/api/models/discover.py +0 -31
  46. xp/api/routers/__init__.py +0 -17
  47. xp/api/routers/conbus.py +0 -5
  48. xp/api/routers/conbus_blink.py +0 -117
  49. xp/api/routers/conbus_custom.py +0 -71
  50. xp/api/routers/conbus_datapoint.py +0 -74
  51. xp/api/routers/conbus_output.py +0 -167
  52. xp/api/routers/errors.py +0 -38
  53. xp/cli/commands/api.py +0 -12
  54. xp/cli/commands/api_start_commands.py +0 -132
  55. xp/services/conbus/conbus_autoreport_get_service.py +0 -94
  56. xp/services/conbus/conbus_autoreport_set_service.py +0 -141
  57. xp/services/conbus/conbus_lightlevel_get_service.py +0 -109
  58. xp/services/conbus/conbus_lightlevel_set_service.py +0 -225
  59. xp/services/conbus/conbus_linknumber_get_service.py +0 -94
  60. {conson_xp-1.2.0.dist-info → conson_xp-1.4.0.dist-info}/WHEEL +0 -0
  61. {conson_xp-1.2.0.dist-info → conson_xp-1.4.0.dist-info}/entry_points.txt +0 -0
  62. {conson_xp-1.2.0.dist-info → conson_xp-1.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,225 +0,0 @@
1
- """Conbus Lightlevel Service for controlling light levels on Conbus modules.
2
-
3
- This service implements lightlevel control operations for XP modules,
4
- including setting specific light levels, turning lights on/off, and
5
- querying current light levels.
6
- """
7
-
8
- import logging
9
- from datetime import datetime
10
- from typing import Callable, Optional
11
-
12
- from twisted.internet.posixbase import PosixReactorBase
13
-
14
- from xp.models import ConbusClientConfig
15
- from xp.models.conbus.conbus_lightlevel import ConbusLightlevelResponse
16
- from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
17
- from xp.models.telegram.datapoint_type import DataPointType
18
- from xp.models.telegram.system_function import SystemFunction
19
- from xp.models.telegram.telegram_type import TelegramType
20
- from xp.services.protocol import ConbusProtocol
21
-
22
-
23
- class ConbusLightlevelError(Exception):
24
- """Raised when Conbus lightlevel operations fail."""
25
-
26
- pass
27
-
28
-
29
- class ConbusLightlevelSetService(ConbusProtocol):
30
- """
31
- Service for controlling light levels on Conbus modules.
32
-
33
- Manages lightlevel operations including setting specific levels,
34
- turning lights on/off, and querying current states.
35
- """
36
-
37
- def __init__(
38
- self,
39
- cli_config: ConbusClientConfig,
40
- reactor: PosixReactorBase,
41
- ):
42
- """Initialize the Conbus lightlevel service.
43
-
44
- Args:
45
- cli_config: Configuration for Conbus client connection.
46
- reactor: Twisted reactor for event loop.
47
- """
48
- super().__init__(cli_config, reactor)
49
- self.serial_number: str = ""
50
- self.output_number: int = 0
51
- self.level: int = 0
52
- self.finish_callback: Optional[Callable[[ConbusLightlevelResponse], None]] = (
53
- None
54
- )
55
- self.service_response: ConbusLightlevelResponse = ConbusLightlevelResponse(
56
- success=False,
57
- serial_number=self.serial_number,
58
- output_number=self.output_number,
59
- level=None,
60
- timestamp=datetime.now(),
61
- )
62
-
63
- # Set up logging
64
- self.logger = logging.getLogger(__name__)
65
-
66
- def connection_established(self) -> None:
67
- """Handle connection established event."""
68
- self.logger.debug(
69
- f"Connection established, setting light level for output {self.output_number} to {self.level}%."
70
- )
71
-
72
- # Format data as output_number:level (e.g., ""15" + "02:050")
73
- data_value = f"{DataPointType.MODULE_LIGHT_LEVEL.value}{self.output_number:02d}:{self.level:03d}"
74
-
75
- # Send telegram using WRITE_CONFIG function with MODULE_LIGHT_LEVEL datapoint
76
- self.send_telegram(
77
- telegram_type=TelegramType.SYSTEM,
78
- serial_number=self.serial_number,
79
- system_function=SystemFunction.WRITE_CONFIG, # "04"
80
- data_value=data_value,
81
- )
82
-
83
- def telegram_sent(self, telegram_sent: str) -> None:
84
- """Handle telegram sent event.
85
-
86
- Args:
87
- telegram_sent: The telegram that was sent.
88
- """
89
- self.service_response.sent_telegram = telegram_sent
90
-
91
- def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
92
- """Handle telegram received event.
93
-
94
- Args:
95
- telegram_received: The telegram received event.
96
- """
97
- self.logger.debug(f"Telegram received: {telegram_received}")
98
- if not self.service_response.received_telegrams:
99
- self.service_response.received_telegrams = []
100
- self.service_response.received_telegrams.append(telegram_received.frame)
101
-
102
- if (
103
- not telegram_received.checksum_valid
104
- or telegram_received.telegram_type != TelegramType.REPLY
105
- or telegram_received.serial_number != self.serial_number
106
- ):
107
- self.logger.debug("Not a reply for our serial number")
108
- return
109
-
110
- # Any valid reply means success (ACK or NAK)
111
- if telegram_received.telegram_type == TelegramType.REPLY:
112
- self.logger.debug("Received lightlevel response")
113
- self.succeed()
114
-
115
- def succeed(self) -> None:
116
- """Handle successful light level set operation."""
117
- self.logger.debug("Succeed")
118
- self.service_response.success = True
119
- self.service_response.serial_number = self.serial_number
120
- self.service_response.output_number = self.output_number
121
- self.service_response.level = self.level
122
- self.service_response.timestamp = datetime.now()
123
-
124
- if self.finish_callback:
125
- self.finish_callback(self.service_response)
126
-
127
- def failed(self, message: str) -> None:
128
- """Handle failed connection event.
129
-
130
- Args:
131
- message: Failure message.
132
- """
133
- self.logger.debug(f"Failed with message: {message}")
134
- self.service_response.success = False
135
- self.service_response.serial_number = self.serial_number
136
- self.service_response.output_number = self.output_number
137
- self.service_response.level = self.level
138
- self.service_response.timestamp = datetime.now()
139
- self.service_response.error = message
140
-
141
- if self.finish_callback:
142
- self.finish_callback(self.service_response)
143
-
144
- def set_lightlevel(
145
- self,
146
- serial_number: str,
147
- output_number: int,
148
- level: int,
149
- finish_callback: Callable[[ConbusLightlevelResponse], None],
150
- timeout_seconds: Optional[float] = None,
151
- ) -> None:
152
- """Set light level for a specific output on a module.
153
-
154
- Args:
155
- serial_number: Module serial number.
156
- output_number: Output number (0-based, 0-8).
157
- level: Light level percentage (0-100).
158
- finish_callback: Callback function to call when operation completes.
159
- timeout_seconds: Optional timeout in seconds.
160
-
161
- Examples:
162
- xp conbus lightlevel set 0012345008 2 50
163
- xp conbus lightlevel set 0012345008 0 100
164
- """
165
- self.logger.info(
166
- f"Setting light level for {serial_number} output {output_number} to {level}%"
167
- )
168
- if timeout_seconds:
169
- self.timeout_seconds = timeout_seconds
170
- self.finish_callback = finish_callback
171
- self.serial_number = serial_number
172
- self.output_number = output_number
173
- self.level = level
174
-
175
- # Validate output_number range (0-8)
176
- if not 0 <= self.output_number <= 8:
177
- self.failed(
178
- f"Output number must be between 0 and 8, got {self.output_number}"
179
- )
180
- return
181
-
182
- # Validate level range
183
- if not 0 <= self.level <= 100:
184
- self.failed(f"Light level must be between 0 and 100, got {self.level}")
185
- return
186
-
187
- self.start_reactor()
188
-
189
- def turn_off(
190
- self,
191
- serial_number: str,
192
- output_number: int,
193
- finish_callback: Callable[[ConbusLightlevelResponse], None],
194
- timeout_seconds: Optional[float] = None,
195
- ) -> None:
196
- """Turn off light (set level to 0) for a specific output.
197
-
198
- Args:
199
- serial_number: Module serial number.
200
- output_number: Output number (0-8).
201
- finish_callback: Callback function to call when operation completes.
202
- timeout_seconds: Optional timeout in seconds.
203
- """
204
- self.set_lightlevel(
205
- serial_number, output_number, 0, finish_callback, timeout_seconds
206
- )
207
-
208
- def turn_on(
209
- self,
210
- serial_number: str,
211
- output_number: int,
212
- finish_callback: Callable[[ConbusLightlevelResponse], None],
213
- timeout_seconds: Optional[float] = None,
214
- ) -> None:
215
- """Turn on light (set level to 80%) for a specific output.
216
-
217
- Args:
218
- serial_number: Module serial number.
219
- output_number: Output number (0-8).
220
- finish_callback: Callback function to call when operation completes.
221
- timeout_seconds: Optional timeout in seconds.
222
- """
223
- self.set_lightlevel(
224
- serial_number, output_number, 80, finish_callback, timeout_seconds
225
- )
@@ -1,94 +0,0 @@
1
- """Conbus Link Number Service for setting module link numbers.
2
-
3
- This service handles setting link numbers for modules through Conbus telegrams.
4
- """
5
-
6
- import logging
7
- from typing import Callable, Optional
8
-
9
- from twisted.internet.posixbase import PosixReactorBase
10
-
11
- from xp.models import ConbusClientConfig, ConbusDatapointResponse
12
- from xp.models.conbus.conbus_linknumber import ConbusLinknumberResponse
13
- from xp.models.telegram.datapoint_type import DataPointType
14
- from xp.services.conbus.conbus_datapoint_service import ConbusDatapointService
15
- from xp.services.telegram.telegram_service import TelegramService
16
-
17
-
18
- class ConbusLinknumberGetService(ConbusDatapointService):
19
- """
20
- Service for getting link numbers from Conbus modules.
21
-
22
- Uses ConbusProtocol to provide link number query functionality
23
- for reading the current link number configuration from modules.
24
- """
25
-
26
- def __init__(
27
- self,
28
- telegram_service: TelegramService,
29
- cli_config: ConbusClientConfig,
30
- reactor: PosixReactorBase,
31
- ) -> None:
32
- """Initialize the Conbus linknumber get service.
33
-
34
- Args:
35
- telegram_service: Service for parsing telegrams.
36
- cli_config: Configuration for Conbus client connection.
37
- reactor: Twisted reactor for event loop.
38
- """
39
- super().__init__(telegram_service, cli_config, reactor)
40
- self.service_callback: Optional[Callable[[ConbusLinknumberResponse], None]] = (
41
- None
42
- )
43
-
44
- # Set up logging
45
- self.logger = logging.getLogger(__name__)
46
-
47
- def finish_service_callback(
48
- self, datapoint_response: ConbusDatapointResponse
49
- ) -> None:
50
- """Process datapoint response and extract link number.
51
-
52
- Args:
53
- datapoint_response: The datapoint response from the module.
54
- """
55
- self.logger.debug("Parsing datapoint response")
56
- link_number_value = 0
57
- if datapoint_response.success and datapoint_response.datapoint_telegram:
58
- link_number_value = int(datapoint_response.datapoint_telegram.data_value)
59
-
60
- linknumber_response = ConbusLinknumberResponse(
61
- success=datapoint_response.success,
62
- result="SUCCESS" if datapoint_response.success else "FAILURE",
63
- link_number=link_number_value,
64
- serial_number=self.serial_number,
65
- error=datapoint_response.error,
66
- sent_telegram=datapoint_response.sent_telegram,
67
- received_telegrams=datapoint_response.received_telegrams,
68
- timestamp=datapoint_response.timestamp,
69
- )
70
-
71
- if self.service_callback:
72
- self.service_callback(linknumber_response)
73
-
74
- def get_linknumber(
75
- self,
76
- serial_number: str,
77
- finish_callback: Callable[[ConbusLinknumberResponse], None],
78
- timeout_seconds: Optional[float] = None,
79
- ) -> None:
80
- """Get the current link number for a specific module.
81
-
82
- Args:
83
- serial_number: 10-digit module serial number.
84
- finish_callback: Callback function to call when the link number is received.
85
- timeout_seconds: Timeout in seconds.
86
- """
87
- self.logger.info("Starting get_linknumber")
88
- if timeout_seconds:
89
- self.timeout_seconds = timeout_seconds
90
- self.serial_number = serial_number
91
- self.datapoint_type = DataPointType.LINK_NUMBER
92
- self.finish_callback = self.finish_service_callback
93
- self.service_callback = finish_callback
94
- self.start_reactor()