conson-xp 1.1.0__py3-none-any.whl → 1.3.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.1.0.dist-info → conson_xp-1.3.0.dist-info}/METADATA +1 -5
- conson_xp-1.3.0.dist-info/RECORD +164 -0
- xp/__init__.py +4 -3
- xp/cli/__init__.py +1 -1
- xp/cli/commands/__init__.py +1 -2
- xp/cli/commands/conbus/conbus.py +9 -37
- xp/cli/commands/conbus/conbus_actiontable_commands.py +26 -4
- xp/cli/commands/conbus/conbus_autoreport_commands.py +58 -30
- xp/cli/commands/conbus/conbus_blink_commands.py +61 -29
- xp/cli/commands/conbus/conbus_config_commands.py +10 -5
- xp/cli/commands/conbus/conbus_custom_commands.py +16 -5
- xp/cli/commands/conbus/conbus_datapoint_commands.py +32 -10
- xp/cli/commands/conbus/conbus_discover_commands.py +20 -7
- xp/cli/commands/conbus/conbus_lightlevel_commands.py +114 -39
- xp/cli/commands/conbus/conbus_linknumber_commands.py +50 -25
- xp/cli/commands/conbus/conbus_msactiontable_commands.py +36 -5
- xp/cli/commands/conbus/conbus_output_commands.py +52 -14
- xp/cli/commands/conbus/conbus_raw_commands.py +17 -6
- xp/cli/commands/conbus/conbus_receive_commands.py +20 -10
- xp/cli/commands/conbus/conbus_scan_commands.py +17 -4
- xp/cli/commands/file_commands.py +35 -18
- xp/cli/commands/homekit/homekit.py +14 -8
- xp/cli/commands/homekit/homekit_start_commands.py +8 -6
- xp/cli/commands/module_commands.py +38 -23
- xp/cli/commands/reverse_proxy_commands.py +27 -19
- xp/cli/commands/server/server_commands.py +18 -18
- xp/cli/commands/telegram/telegram.py +4 -12
- xp/cli/commands/telegram/telegram_blink_commands.py +10 -8
- xp/cli/commands/telegram/telegram_checksum_commands.py +19 -8
- xp/cli/commands/telegram/telegram_discover_commands.py +2 -4
- xp/cli/commands/telegram/telegram_linknumber_commands.py +11 -8
- xp/cli/commands/telegram/telegram_parse_commands.py +10 -9
- xp/cli/commands/telegram/telegram_version_commands.py +8 -4
- xp/cli/main.py +5 -3
- xp/cli/utils/click_tree.py +23 -3
- xp/cli/utils/datapoint_type_choice.py +20 -0
- xp/cli/utils/decorators.py +165 -14
- xp/cli/utils/error_handlers.py +49 -18
- xp/cli/utils/formatters.py +95 -10
- xp/cli/utils/serial_number_type.py +18 -0
- xp/cli/utils/system_function_choice.py +20 -0
- xp/cli/utils/xp_module_type.py +20 -0
- xp/connection/__init__.py +1 -1
- xp/connection/exceptions.py +5 -5
- xp/models/__init__.py +1 -1
- xp/models/actiontable/__init__.py +1 -0
- xp/models/actiontable/actiontable.py +17 -1
- xp/models/actiontable/msactiontable_xp20.py +10 -0
- xp/models/actiontable/msactiontable_xp24.py +20 -3
- xp/models/actiontable/msactiontable_xp33.py +27 -4
- xp/models/conbus/__init__.py +1 -0
- xp/models/conbus/conbus.py +34 -4
- xp/models/conbus/conbus_autoreport.py +20 -2
- xp/models/conbus/conbus_blink.py +22 -2
- xp/models/conbus/conbus_client_config.py +22 -1
- xp/models/conbus/conbus_connection_status.py +16 -2
- xp/models/conbus/conbus_custom.py +21 -2
- xp/models/conbus/conbus_datapoint.py +25 -2
- xp/models/conbus/conbus_discover.py +18 -2
- xp/models/conbus/conbus_lightlevel.py +20 -2
- xp/models/conbus/conbus_linknumber.py +20 -2
- xp/models/conbus/conbus_output.py +22 -2
- xp/models/conbus/conbus_raw.py +17 -2
- xp/models/conbus/conbus_receive.py +16 -2
- xp/models/conbus/conbus_writeconfig.py +60 -0
- xp/models/homekit/__init__.py +1 -0
- xp/models/homekit/homekit_accessory.py +15 -1
- xp/models/homekit/homekit_config.py +52 -0
- xp/models/homekit/homekit_conson_config.py +32 -0
- xp/models/log_entry.py +49 -9
- xp/models/protocol/__init__.py +1 -0
- xp/models/protocol/conbus_protocol.py +130 -21
- xp/models/telegram/__init__.py +1 -0
- xp/models/telegram/action_type.py +16 -2
- xp/models/telegram/datapoint_type.py +36 -2
- xp/models/telegram/event_telegram.py +46 -10
- xp/models/telegram/event_type.py +8 -1
- xp/models/telegram/input_action_type.py +34 -2
- xp/models/telegram/input_type.py +9 -1
- xp/models/telegram/module_type.py +69 -19
- xp/models/telegram/module_type_code.py +43 -1
- xp/models/telegram/output_telegram.py +30 -6
- xp/models/telegram/reply_telegram.py +56 -11
- xp/models/telegram/system_function.py +35 -3
- xp/models/telegram/system_telegram.py +18 -4
- xp/models/telegram/telegram.py +12 -3
- xp/models/telegram/telegram_type.py +8 -1
- xp/models/telegram/timeparam_type.py +27 -0
- xp/models/write_config_type.py +17 -2
- xp/services/__init__.py +1 -1
- xp/services/conbus/__init__.py +1 -0
- xp/services/conbus/actiontable/__init__.py +1 -0
- xp/services/conbus/actiontable/actiontable_service.py +33 -2
- xp/services/conbus/actiontable/msactiontable_service.py +40 -3
- xp/services/conbus/actiontable/msactiontable_xp24_serializer.py +36 -4
- xp/services/conbus/actiontable/msactiontable_xp33_serializer.py +45 -5
- xp/services/conbus/conbus_blink_all_service.py +40 -21
- xp/services/conbus/conbus_blink_service.py +37 -13
- xp/services/conbus/conbus_custom_service.py +29 -13
- xp/services/conbus/conbus_datapoint_queryall_service.py +40 -16
- xp/services/conbus/conbus_datapoint_service.py +42 -18
- xp/services/conbus/conbus_discover_service.py +43 -7
- xp/services/conbus/conbus_output_service.py +33 -13
- xp/services/conbus/conbus_raw_service.py +36 -16
- xp/services/conbus/conbus_receive_service.py +38 -6
- xp/services/conbus/conbus_scan_service.py +44 -18
- xp/services/conbus/write_config_service.py +193 -0
- xp/services/homekit/__init__.py +1 -0
- xp/services/homekit/homekit_cache_service.py +31 -6
- xp/services/homekit/homekit_conbus_service.py +33 -2
- xp/services/homekit/homekit_config_validator.py +97 -15
- xp/services/homekit/homekit_conson_validator.py +51 -7
- xp/services/homekit/homekit_dimminglight.py +47 -1
- xp/services/homekit/homekit_dimminglight_service.py +35 -1
- xp/services/homekit/homekit_hap_service.py +71 -18
- xp/services/homekit/homekit_lightbulb.py +35 -1
- xp/services/homekit/homekit_lightbulb_service.py +30 -2
- xp/services/homekit/homekit_module_service.py +23 -1
- xp/services/homekit/homekit_outlet.py +47 -1
- xp/services/homekit/homekit_outlet_service.py +44 -2
- xp/services/homekit/homekit_service.py +113 -19
- xp/services/log_file_service.py +37 -41
- xp/services/module_type_service.py +26 -5
- xp/services/protocol/__init__.py +1 -1
- xp/services/protocol/conbus_protocol.py +110 -16
- xp/services/protocol/protocol_factory.py +40 -0
- xp/services/protocol/telegram_protocol.py +38 -7
- xp/services/reverse_proxy_service.py +79 -14
- xp/services/server/__init__.py +1 -0
- xp/services/server/base_server_service.py +102 -14
- xp/services/server/cp20_server_service.py +12 -4
- xp/services/server/server_service.py +26 -11
- xp/services/server/xp130_server_service.py +11 -3
- xp/services/server/xp20_server_service.py +11 -3
- xp/services/server/xp230_server_service.py +11 -3
- xp/services/server/xp24_server_service.py +33 -6
- xp/services/server/xp33_server_service.py +41 -8
- xp/services/telegram/__init__.py +1 -0
- xp/services/telegram/telegram_blink_service.py +19 -31
- xp/services/telegram/telegram_checksum_service.py +10 -10
- xp/services/telegram/telegram_datapoint_service.py +70 -0
- xp/services/telegram/telegram_discover_service.py +58 -29
- xp/services/telegram/telegram_link_number_service.py +27 -40
- xp/services/telegram/telegram_output_service.py +46 -49
- xp/services/telegram/telegram_service.py +41 -41
- xp/services/telegram/telegram_version_service.py +4 -2
- xp/utils/__init__.py +1 -1
- xp/utils/dependencies.py +4 -47
- xp/utils/serialization.py +6 -0
- xp/utils/time_utils.py +6 -11
- conson_xp-1.1.0.dist-info/RECORD +0 -181
- xp/api/__init__.py +0 -1
- xp/api/main.py +0 -110
- xp/api/models/__init__.py +0 -1
- xp/api/models/api.py +0 -20
- xp/api/models/discover.py +0 -21
- xp/api/routers/__init__.py +0 -17
- xp/api/routers/conbus.py +0 -5
- xp/api/routers/conbus_blink.py +0 -105
- xp/api/routers/conbus_custom.py +0 -63
- xp/api/routers/conbus_datapoint.py +0 -67
- xp/api/routers/conbus_output.py +0 -147
- xp/api/routers/errors.py +0 -37
- xp/cli/commands/api.py +0 -16
- xp/cli/commands/api_start_commands.py +0 -126
- xp/services/conbus/conbus_autoreport_get_service.py +0 -85
- xp/services/conbus/conbus_autoreport_set_service.py +0 -128
- xp/services/conbus/conbus_lightlevel_get_service.py +0 -101
- xp/services/conbus/conbus_lightlevel_set_service.py +0 -205
- xp/services/conbus/conbus_linknumber_get_service.py +0 -86
- xp/services/conbus/conbus_linknumber_set_service.py +0 -155
- {conson_xp-1.1.0.dist-info → conson_xp-1.3.0.dist-info}/WHEEL +0 -0
- {conson_xp-1.1.0.dist-info → conson_xp-1.3.0.dist-info}/entry_points.txt +0 -0
- {conson_xp-1.1.0.dist-info → conson_xp-1.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Conbus output response model."""
|
|
2
|
+
|
|
1
3
|
from dataclasses import dataclass
|
|
2
4
|
from datetime import datetime
|
|
3
5
|
from typing import Any, Dict, Optional
|
|
@@ -9,7 +11,20 @@ from xp.models.telegram.reply_telegram import ReplyTelegram
|
|
|
9
11
|
|
|
10
12
|
@dataclass
|
|
11
13
|
class ConbusOutputResponse:
|
|
12
|
-
"""Represents a response from Conbus send operation
|
|
14
|
+
"""Represents a response from Conbus send operation.
|
|
15
|
+
|
|
16
|
+
Attributes:
|
|
17
|
+
success: Whether the operation was successful.
|
|
18
|
+
serial_number: Serial number of the device.
|
|
19
|
+
output_number: Output number controlled.
|
|
20
|
+
action_type: Type of action performed.
|
|
21
|
+
timestamp: Timestamp of the response.
|
|
22
|
+
output_telegram: Output telegram sent.
|
|
23
|
+
sent_telegram: Raw telegram sent to device.
|
|
24
|
+
received_telegrams: List of telegrams received.
|
|
25
|
+
datapoint_telegram: Datapoint telegram received.
|
|
26
|
+
error: Error message if operation failed.
|
|
27
|
+
"""
|
|
13
28
|
|
|
14
29
|
success: bool
|
|
15
30
|
serial_number: str
|
|
@@ -23,11 +38,16 @@ class ConbusOutputResponse:
|
|
|
23
38
|
error: Optional[str] = None
|
|
24
39
|
|
|
25
40
|
def __post_init__(self) -> None:
|
|
41
|
+
"""Initialize received_telegrams if not provided."""
|
|
26
42
|
if self.received_telegrams is None:
|
|
27
43
|
self.received_telegrams = []
|
|
28
44
|
|
|
29
45
|
def to_dict(self) -> Dict[str, Any]:
|
|
30
|
-
"""Convert to dictionary for JSON serialization
|
|
46
|
+
"""Convert to dictionary for JSON serialization.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Dictionary representation of the response.
|
|
50
|
+
"""
|
|
31
51
|
return {
|
|
32
52
|
"success": self.success,
|
|
33
53
|
"sent_telegram": self.sent_telegram,
|
xp/models/conbus/conbus_raw.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Conbus raw response model."""
|
|
2
|
+
|
|
1
3
|
from dataclasses import dataclass
|
|
2
4
|
from datetime import datetime
|
|
3
5
|
from typing import Any, Dict, List, Optional
|
|
@@ -5,7 +7,15 @@ from typing import Any, Dict, List, Optional
|
|
|
5
7
|
|
|
6
8
|
@dataclass
|
|
7
9
|
class ConbusRawResponse:
|
|
8
|
-
"""Represents a response from Conbus raw telegram send operation
|
|
10
|
+
"""Represents a response from Conbus raw telegram send operation.
|
|
11
|
+
|
|
12
|
+
Attributes:
|
|
13
|
+
success: Whether the operation was successful.
|
|
14
|
+
sent_telegrams: Raw telegrams sent.
|
|
15
|
+
received_telegrams: List of telegrams received.
|
|
16
|
+
error: Error message if operation failed.
|
|
17
|
+
timestamp: Timestamp of the response.
|
|
18
|
+
"""
|
|
9
19
|
|
|
10
20
|
success: bool
|
|
11
21
|
sent_telegrams: Optional[str] = None
|
|
@@ -14,13 +24,18 @@ class ConbusRawResponse:
|
|
|
14
24
|
timestamp: Optional[datetime] = None
|
|
15
25
|
|
|
16
26
|
def __post_init__(self) -> None:
|
|
27
|
+
"""Initialize timestamp and received_telegrams if not provided."""
|
|
17
28
|
if self.timestamp is None:
|
|
18
29
|
self.timestamp = datetime.now()
|
|
19
30
|
if self.received_telegrams is None:
|
|
20
31
|
self.received_telegrams = []
|
|
21
32
|
|
|
22
33
|
def to_dict(self) -> Dict[str, Any]:
|
|
23
|
-
"""Convert to dictionary for JSON serialization
|
|
34
|
+
"""Convert to dictionary for JSON serialization.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Dictionary representation of the response.
|
|
38
|
+
"""
|
|
24
39
|
return {
|
|
25
40
|
"success": self.success,
|
|
26
41
|
"sent_telegrams": self.sent_telegrams,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Conbus receive response model."""
|
|
2
|
+
|
|
1
3
|
from dataclasses import dataclass
|
|
2
4
|
from datetime import datetime
|
|
3
5
|
from typing import Any, Dict, List, Optional
|
|
@@ -5,7 +7,14 @@ from typing import Any, Dict, List, Optional
|
|
|
5
7
|
|
|
6
8
|
@dataclass
|
|
7
9
|
class ConbusReceiveResponse:
|
|
8
|
-
"""Represents a response from Conbus receive operation
|
|
10
|
+
"""Represents a response from Conbus receive operation.
|
|
11
|
+
|
|
12
|
+
Attributes:
|
|
13
|
+
success: Whether the operation was successful.
|
|
14
|
+
received_telegrams: List of telegrams received.
|
|
15
|
+
error: Error message if operation failed.
|
|
16
|
+
timestamp: Timestamp of the response.
|
|
17
|
+
"""
|
|
9
18
|
|
|
10
19
|
success: bool
|
|
11
20
|
received_telegrams: Optional[List[str]] = None
|
|
@@ -13,13 +22,18 @@ class ConbusReceiveResponse:
|
|
|
13
22
|
timestamp: Optional[datetime] = None
|
|
14
23
|
|
|
15
24
|
def __post_init__(self) -> None:
|
|
25
|
+
"""Initialize timestamp and received_telegrams if not provided."""
|
|
16
26
|
if self.timestamp is None:
|
|
17
27
|
self.timestamp = datetime.now()
|
|
18
28
|
if self.received_telegrams is None:
|
|
19
29
|
self.received_telegrams = []
|
|
20
30
|
|
|
21
31
|
def to_dict(self) -> Dict[str, Any]:
|
|
22
|
-
"""Convert to dictionary for JSON serialization
|
|
32
|
+
"""Convert to dictionary for JSON serialization.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Dictionary representation of the response.
|
|
36
|
+
"""
|
|
23
37
|
return {
|
|
24
38
|
"success": self.success,
|
|
25
39
|
"received_telegrams": self.received_telegrams,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Conbus link number response model."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import Any, Dict, Optional
|
|
6
|
+
|
|
7
|
+
from xp.models.telegram.datapoint_type import DataPointType
|
|
8
|
+
from xp.models.telegram.system_function import SystemFunction
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class ConbusWriteConfigResponse:
|
|
13
|
+
"""Represents a response from Conbus write config operations (set/get).
|
|
14
|
+
|
|
15
|
+
Attributes:
|
|
16
|
+
success: Whether the operation was successful.
|
|
17
|
+
serial_number: Serial number of the device.
|
|
18
|
+
datapoint_type: the datapoint to write.
|
|
19
|
+
system_function: ACK or NAK received.
|
|
20
|
+
sent_telegram: Telegram sent to device.
|
|
21
|
+
received_telegrams: List of telegrams received.
|
|
22
|
+
data_value: written value.
|
|
23
|
+
error: Error message if operation failed.
|
|
24
|
+
timestamp: Timestamp of the response.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
success: bool
|
|
28
|
+
serial_number: str
|
|
29
|
+
datapoint_type: Optional[DataPointType] = None
|
|
30
|
+
system_function: Optional[SystemFunction] = None
|
|
31
|
+
sent_telegram: Optional[str] = None
|
|
32
|
+
received_telegrams: Optional[list] = None
|
|
33
|
+
data_value: Optional[str] = None
|
|
34
|
+
error: Optional[str] = None
|
|
35
|
+
timestamp: Optional[datetime] = None
|
|
36
|
+
|
|
37
|
+
def __post_init__(self) -> None:
|
|
38
|
+
"""Initialize timestamp and received_telegrams if not provided."""
|
|
39
|
+
if self.timestamp is None:
|
|
40
|
+
self.timestamp = datetime.now()
|
|
41
|
+
if self.received_telegrams is None:
|
|
42
|
+
self.received_telegrams = []
|
|
43
|
+
|
|
44
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
45
|
+
"""Convert to dictionary for JSON serialization.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Dictionary representation of the response.
|
|
49
|
+
"""
|
|
50
|
+
return {
|
|
51
|
+
"success": self.success,
|
|
52
|
+
"system_function": self.system_function,
|
|
53
|
+
"datapoint_type": self.datapoint_type,
|
|
54
|
+
"data_value": self.data_value,
|
|
55
|
+
"serial_number": self.serial_number,
|
|
56
|
+
"sent_telegram": self.sent_telegram,
|
|
57
|
+
"received_telegrams": self.received_telegrams,
|
|
58
|
+
"error": self.error,
|
|
59
|
+
"timestamp": self.timestamp.isoformat() if self.timestamp else None,
|
|
60
|
+
}
|
xp/models/homekit/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""HomeKit integration models."""
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""HomeKit configuration models."""
|
|
2
|
+
|
|
1
3
|
import random
|
|
2
4
|
from typing import Any
|
|
3
5
|
|
|
@@ -6,11 +8,22 @@ from pyhap.const import CATEGORY_SENSOR
|
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
class TemperatureSensor(Accessory):
|
|
9
|
-
"""Fake Temperature sensor, measuring every 3 seconds.
|
|
11
|
+
"""Fake Temperature sensor, measuring every 3 seconds.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
category: HomeKit category for sensor.
|
|
15
|
+
char_temp: Temperature characteristic.
|
|
16
|
+
"""
|
|
10
17
|
|
|
11
18
|
category = CATEGORY_SENSOR
|
|
12
19
|
|
|
13
20
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
21
|
+
"""Initialize temperature sensor accessory.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
args: Positional arguments passed to parent Accessory.
|
|
25
|
+
kwargs: Keyword arguments passed to parent Accessory.
|
|
26
|
+
"""
|
|
14
27
|
super().__init__(*args, **kwargs)
|
|
15
28
|
|
|
16
29
|
serv_temp = self.add_preload_service("TemperatureSensor")
|
|
@@ -18,4 +31,5 @@ class TemperatureSensor(Accessory):
|
|
|
18
31
|
|
|
19
32
|
@Accessory.run_at_interval(30)
|
|
20
33
|
async def run(self) -> None:
|
|
34
|
+
"""Update temperature value every 30 seconds."""
|
|
21
35
|
self.char_temp.set_value(random.randint(-25, 25))
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""HomeKit configuration models."""
|
|
2
|
+
|
|
1
3
|
import logging
|
|
2
4
|
from ipaddress import IPv4Address, IPv6Address
|
|
3
5
|
from pathlib import Path
|
|
@@ -8,21 +10,54 @@ from pydantic import BaseModel, Field, IPvAnyAddress
|
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
class NetworkConfig(BaseModel):
|
|
13
|
+
"""Network configuration settings.
|
|
14
|
+
|
|
15
|
+
Attributes:
|
|
16
|
+
ip: IP address for the network connection.
|
|
17
|
+
port: Port number for the network connection.
|
|
18
|
+
"""
|
|
19
|
+
|
|
11
20
|
ip: Union[IPvAnyAddress, IPv4Address, IPv6Address, str] = "127.0.0.1"
|
|
12
21
|
port: int = 51826
|
|
13
22
|
|
|
14
23
|
|
|
15
24
|
class RoomConfig(BaseModel):
|
|
25
|
+
"""Room configuration settings.
|
|
26
|
+
|
|
27
|
+
Attributes:
|
|
28
|
+
name: Name of the room.
|
|
29
|
+
accessories: List of accessory identifiers in the room.
|
|
30
|
+
"""
|
|
31
|
+
|
|
16
32
|
name: str
|
|
17
33
|
accessories: List[str]
|
|
18
34
|
|
|
19
35
|
|
|
20
36
|
class BridgeConfig(BaseModel):
|
|
37
|
+
"""HomeKit bridge settings.
|
|
38
|
+
|
|
39
|
+
Attributes:
|
|
40
|
+
name: Name of the HomeKit bridge.
|
|
41
|
+
rooms: List of room configurations.
|
|
42
|
+
"""
|
|
43
|
+
|
|
21
44
|
name: str = "Conson Bridge"
|
|
22
45
|
rooms: List[RoomConfig] = []
|
|
23
46
|
|
|
24
47
|
|
|
25
48
|
class HomekitAccessoryConfig(BaseModel):
|
|
49
|
+
"""HomeKit accessory configuration.
|
|
50
|
+
|
|
51
|
+
Attributes:
|
|
52
|
+
name: Name of the accessory.
|
|
53
|
+
id: Unique identifier for the accessory.
|
|
54
|
+
serial_number: Serial number of the accessory.
|
|
55
|
+
output_number: Output number for the accessory.
|
|
56
|
+
description: Description of the accessory.
|
|
57
|
+
service: Service type for the accessory.
|
|
58
|
+
hap_accessory: Optional HAP accessory identifier.
|
|
59
|
+
"""
|
|
60
|
+
|
|
26
61
|
name: str
|
|
27
62
|
id: str
|
|
28
63
|
serial_number: str
|
|
@@ -33,6 +68,15 @@ class HomekitAccessoryConfig(BaseModel):
|
|
|
33
68
|
|
|
34
69
|
|
|
35
70
|
class HomekitConfig(BaseModel):
|
|
71
|
+
"""HomeKit bridge configuration.
|
|
72
|
+
|
|
73
|
+
Attributes:
|
|
74
|
+
homekit: Network configuration for HomeKit.
|
|
75
|
+
conson: Network configuration for Conson.
|
|
76
|
+
bridge: Bridge configuration settings.
|
|
77
|
+
accessories: List of accessory configurations.
|
|
78
|
+
"""
|
|
79
|
+
|
|
36
80
|
homekit: NetworkConfig = Field(default_factory=NetworkConfig)
|
|
37
81
|
conson: NetworkConfig = Field(default_factory=NetworkConfig)
|
|
38
82
|
bridge: BridgeConfig = Field(default_factory=BridgeConfig)
|
|
@@ -40,6 +84,14 @@ class HomekitConfig(BaseModel):
|
|
|
40
84
|
|
|
41
85
|
@classmethod
|
|
42
86
|
def from_yaml(cls, file_path: str) -> "HomekitConfig":
|
|
87
|
+
"""Load configuration from YAML file.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
file_path: Path to the YAML configuration file.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
HomekitConfig instance loaded from file or default config.
|
|
94
|
+
"""
|
|
43
95
|
if not Path(file_path).exists():
|
|
44
96
|
logger = logging.getLogger(__name__)
|
|
45
97
|
logger.error(f"File {file_path} does not exist, loading default")
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""HomeKit configuration models."""
|
|
2
|
+
|
|
1
3
|
import logging
|
|
2
4
|
from pathlib import Path
|
|
3
5
|
from typing import List, Optional
|
|
@@ -6,6 +8,22 @@ from pydantic import BaseModel, IPvAnyAddress
|
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
class ConsonModuleConfig(BaseModel):
|
|
11
|
+
"""Configuration for a Conson module.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
name: Name of the module.
|
|
15
|
+
serial_number: Serial number of the module.
|
|
16
|
+
module_type: Type of the module.
|
|
17
|
+
module_type_code: Numeric code for the module type.
|
|
18
|
+
link_number: Link number for the module.
|
|
19
|
+
enabled: Whether the module is enabled.
|
|
20
|
+
module_number: Optional module number.
|
|
21
|
+
conbus_ip: Optional Conbus IP address.
|
|
22
|
+
conbus_port: Optional Conbus port number.
|
|
23
|
+
sw_version: Optional software version.
|
|
24
|
+
hw_version: Optional hardware version.
|
|
25
|
+
"""
|
|
26
|
+
|
|
9
27
|
name: str
|
|
10
28
|
serial_number: str
|
|
11
29
|
module_type: str
|
|
@@ -20,10 +38,24 @@ class ConsonModuleConfig(BaseModel):
|
|
|
20
38
|
|
|
21
39
|
|
|
22
40
|
class ConsonModuleListConfig(BaseModel):
|
|
41
|
+
"""Configuration list for Conson modules.
|
|
42
|
+
|
|
43
|
+
Attributes:
|
|
44
|
+
root: List of Conson module configurations.
|
|
45
|
+
"""
|
|
46
|
+
|
|
23
47
|
root: List[ConsonModuleConfig] = []
|
|
24
48
|
|
|
25
49
|
@classmethod
|
|
26
50
|
def from_yaml(cls, file_path: str) -> "ConsonModuleListConfig":
|
|
51
|
+
"""Load configuration from YAML file.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
file_path: Path to the YAML configuration file.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
ConsonModuleListConfig instance loaded from file or default config.
|
|
58
|
+
"""
|
|
27
59
|
import yaml
|
|
28
60
|
|
|
29
61
|
if not Path(file_path).exists():
|
xp/models/log_entry.py
CHANGED
|
@@ -11,11 +11,23 @@ from xp.models.telegram.system_telegram import SystemTelegram
|
|
|
11
11
|
|
|
12
12
|
@dataclass
|
|
13
13
|
class LogEntry:
|
|
14
|
-
"""
|
|
15
|
-
Represents a single entry in a console bus log file.
|
|
14
|
+
"""Represents a single entry in a console bus log file.
|
|
16
15
|
|
|
17
16
|
Format: HH:MM:SS,mmm [TX/RX] <telegram>
|
|
18
17
|
Examples: 22:44:20,352 [TX] <S0012345008F27D00AAFN>
|
|
18
|
+
|
|
19
|
+
Attributes:
|
|
20
|
+
timestamp: Timestamp of the log entry.
|
|
21
|
+
direction: Direction of telegram ("TX" or "RX").
|
|
22
|
+
raw_telegram: Raw telegram string.
|
|
23
|
+
parsed_telegram: Parsed telegram object if successfully parsed.
|
|
24
|
+
parse_error: Error message if parsing failed.
|
|
25
|
+
line_number: Line number in the log file.
|
|
26
|
+
is_transmitted: True if this is a transmitted telegram.
|
|
27
|
+
is_received: True if this is a received telegram.
|
|
28
|
+
telegram_type: Telegram type (event, system, reply, unknown).
|
|
29
|
+
is_valid_parse: True if the telegram was successfully parsed.
|
|
30
|
+
checksum_validated: Checksum validation status if available.
|
|
19
31
|
"""
|
|
20
32
|
|
|
21
33
|
timestamp: datetime
|
|
@@ -29,17 +41,29 @@ class LogEntry:
|
|
|
29
41
|
|
|
30
42
|
@property
|
|
31
43
|
def is_transmitted(self) -> bool:
|
|
32
|
-
"""True if this is a transmitted telegram
|
|
44
|
+
"""True if this is a transmitted telegram.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
True if direction is TX, False otherwise.
|
|
48
|
+
"""
|
|
33
49
|
return self.direction == "TX"
|
|
34
50
|
|
|
35
51
|
@property
|
|
36
52
|
def is_received(self) -> bool:
|
|
37
|
-
"""True if this is a received telegram
|
|
53
|
+
"""True if this is a received telegram.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
True if direction is RX, False otherwise.
|
|
57
|
+
"""
|
|
38
58
|
return self.direction == "RX"
|
|
39
59
|
|
|
40
60
|
@property
|
|
41
61
|
def telegram_type(self) -> str:
|
|
42
|
-
"""Get the telegram type (event, system, reply, unknown)
|
|
62
|
+
"""Get the telegram type (event, system, reply, unknown).
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
Telegram type string.
|
|
66
|
+
"""
|
|
43
67
|
if self.parsed_telegram is None:
|
|
44
68
|
return "unknown"
|
|
45
69
|
|
|
@@ -47,18 +71,30 @@ class LogEntry:
|
|
|
47
71
|
|
|
48
72
|
@property
|
|
49
73
|
def is_valid_parse(self) -> bool:
|
|
50
|
-
"""True if the telegram was successfully parsed
|
|
74
|
+
"""True if the telegram was successfully parsed.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
True if parsed without errors, False otherwise.
|
|
78
|
+
"""
|
|
51
79
|
return self.parsed_telegram is not None and self.parse_error is None
|
|
52
80
|
|
|
53
81
|
@property
|
|
54
82
|
def checksum_validated(self) -> Optional[bool]:
|
|
55
|
-
"""Get checksum validation status if available
|
|
83
|
+
"""Get checksum validation status if available.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
Checksum validation status or None if not available.
|
|
87
|
+
"""
|
|
56
88
|
if self.parsed_telegram and hasattr(self.parsed_telegram, "checksum_validated"):
|
|
57
89
|
return self.parsed_telegram.checksum_validated
|
|
58
90
|
return None
|
|
59
91
|
|
|
60
92
|
def to_dict(self) -> dict[str, Any]:
|
|
61
|
-
"""Convert to dictionary for JSON serialization
|
|
93
|
+
"""Convert to dictionary for JSON serialization.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
Dictionary representation of the log entry.
|
|
97
|
+
"""
|
|
62
98
|
result: dict[str, Any] = {
|
|
63
99
|
"line_number": self.line_number,
|
|
64
100
|
"timestamp": self.timestamp.strftime("%H:%M:%S.%f")[
|
|
@@ -79,7 +115,11 @@ class LogEntry:
|
|
|
79
115
|
return result
|
|
80
116
|
|
|
81
117
|
def __str__(self) -> str:
|
|
82
|
-
"""Human-readable string representation
|
|
118
|
+
"""Human-readable string representation.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Formatted string representation of the log entry.
|
|
122
|
+
"""
|
|
83
123
|
timestamp_str = self.timestamp.strftime("%H:%M:%S,%f")[:-3] # HH:MM:SS,mmm
|
|
84
124
|
status = "✓" if self.is_valid_parse else "✗"
|
|
85
125
|
checksum_status = ""
|
xp/models/protocol/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Protocol models and interfaces."""
|