conson-xp 1.2.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.2.0.dist-info → conson_xp-1.3.0.dist-info}/METADATA +1 -5
- {conson_xp-1.2.0.dist-info → conson_xp-1.3.0.dist-info}/RECORD +30 -47
- xp/__init__.py +1 -1
- xp/cli/commands/__init__.py +0 -2
- xp/cli/commands/conbus/conbus_actiontable_commands.py +5 -3
- xp/cli/commands/conbus/conbus_autoreport_commands.py +39 -21
- xp/cli/commands/conbus/conbus_blink_commands.py +8 -8
- xp/cli/commands/conbus/conbus_config_commands.py +3 -1
- xp/cli/commands/conbus/conbus_custom_commands.py +3 -1
- xp/cli/commands/conbus/conbus_datapoint_commands.py +4 -2
- xp/cli/commands/conbus/conbus_discover_commands.py +5 -3
- xp/cli/commands/conbus/conbus_lightlevel_commands.py +68 -32
- xp/cli/commands/conbus/conbus_linknumber_commands.py +32 -17
- xp/cli/commands/conbus/conbus_msactiontable_commands.py +11 -4
- xp/cli/commands/conbus/conbus_output_commands.py +6 -2
- xp/cli/commands/conbus/conbus_receive_commands.py +5 -3
- xp/cli/commands/file_commands.py +9 -3
- xp/cli/commands/homekit/homekit_start_commands.py +3 -1
- xp/cli/commands/module_commands.py +12 -4
- xp/cli/commands/reverse_proxy_commands.py +3 -1
- xp/cli/main.py +0 -2
- xp/models/conbus/conbus_datapoint.py +3 -0
- xp/models/conbus/conbus_writeconfig.py +60 -0
- xp/services/conbus/conbus_datapoint_service.py +9 -6
- xp/services/conbus/{conbus_linknumber_set_service.py → write_config_service.py} +78 -66
- xp/services/telegram/telegram_datapoint_service.py +70 -0
- xp/utils/dependencies.py +4 -46
- xp/api/__init__.py +0 -1
- xp/api/main.py +0 -125
- xp/api/models/__init__.py +0 -1
- xp/api/models/api.py +0 -31
- xp/api/models/discover.py +0 -31
- xp/api/routers/__init__.py +0 -17
- xp/api/routers/conbus.py +0 -5
- xp/api/routers/conbus_blink.py +0 -117
- xp/api/routers/conbus_custom.py +0 -71
- xp/api/routers/conbus_datapoint.py +0 -74
- xp/api/routers/conbus_output.py +0 -167
- xp/api/routers/errors.py +0 -38
- xp/cli/commands/api.py +0 -12
- xp/cli/commands/api_start_commands.py +0 -132
- xp/services/conbus/conbus_autoreport_get_service.py +0 -94
- xp/services/conbus/conbus_autoreport_set_service.py +0 -141
- xp/services/conbus/conbus_lightlevel_get_service.py +0 -109
- xp/services/conbus/conbus_lightlevel_set_service.py +0 -225
- xp/services/conbus/conbus_linknumber_get_service.py +0 -94
- {conson_xp-1.2.0.dist-info → conson_xp-1.3.0.dist-info}/WHEEL +0 -0
- {conson_xp-1.2.0.dist-info → conson_xp-1.3.0.dist-info}/entry_points.txt +0 -0
- {conson_xp-1.2.0.dist-info → conson_xp-1.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""Service for processing Telegram protocol datapoint values."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TelegramDatapointService:
|
|
5
|
+
"""Service for processing Telegram protocol datapoint values.
|
|
6
|
+
|
|
7
|
+
Provides methods to parse and extract values from different types of
|
|
8
|
+
Telegram datapoints including autoreport status, light level outputs,
|
|
9
|
+
and link number values.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def get_autoreport_status(self, data_value: str) -> bool:
|
|
13
|
+
"""Get the autoreport status value.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
data_value: The raw autoreport status data value (PP or AA).
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
The autoreport status: Enable (True) or disable (False).
|
|
20
|
+
"""
|
|
21
|
+
status_value = True if data_value == "PP" else False
|
|
22
|
+
return status_value
|
|
23
|
+
|
|
24
|
+
def get_autoreport_status_data_value(self, status_value: bool) -> str:
|
|
25
|
+
"""Get the autoreport status data_value.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
status_value: Enable (True) or disable (False).
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
data_value: The raw autoreport status data value (PP or AA).
|
|
32
|
+
"""
|
|
33
|
+
data_value = "PP" if status_value else "AA"
|
|
34
|
+
return data_value
|
|
35
|
+
|
|
36
|
+
def get_lightlevel(self, data_value: str, output_number: int) -> int:
|
|
37
|
+
"""Extract the light level for a specific output number.
|
|
38
|
+
|
|
39
|
+
Parses comma-separated output data in the format "output:level[%]"
|
|
40
|
+
and returns the level for the requested output number.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
data_value: Comma-separated string of output:level pairs
|
|
44
|
+
(e.g., "1:50[%],2:75[%]").
|
|
45
|
+
output_number: The output number to get the level for.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
The light level as an integer (0 if output not found).
|
|
49
|
+
"""
|
|
50
|
+
level = 0
|
|
51
|
+
for output_data in data_value.split(","):
|
|
52
|
+
if ":" in output_data:
|
|
53
|
+
output_str, level_str = output_data.split(":")
|
|
54
|
+
if int(output_str) == output_number:
|
|
55
|
+
level_str = level_str.replace("[%]", "")
|
|
56
|
+
level = int(level_str)
|
|
57
|
+
break
|
|
58
|
+
return level
|
|
59
|
+
|
|
60
|
+
def get_linknumber(self, data_value: str) -> int:
|
|
61
|
+
"""Parse and return the link number value.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
data_value: The raw link number data value as a string.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
The link number as an integer.
|
|
68
|
+
"""
|
|
69
|
+
link_number_value = int(data_value)
|
|
70
|
+
return link_number_value
|
xp/utils/dependencies.py
CHANGED
|
@@ -21,8 +21,6 @@ from xp.services.conbus.actiontable.msactiontable_xp24_serializer import (
|
|
|
21
21
|
from xp.services.conbus.actiontable.msactiontable_xp33_serializer import (
|
|
22
22
|
Xp33MsActionTableSerializer,
|
|
23
23
|
)
|
|
24
|
-
from xp.services.conbus.conbus_autoreport_get_service import ConbusAutoreportGetService
|
|
25
|
-
from xp.services.conbus.conbus_autoreport_set_service import ConbusAutoreportSetService
|
|
26
24
|
from xp.services.conbus.conbus_blink_all_service import ConbusBlinkAllService
|
|
27
25
|
from xp.services.conbus.conbus_blink_service import ConbusBlinkService
|
|
28
26
|
from xp.services.conbus.conbus_custom_service import ConbusCustomService
|
|
@@ -33,13 +31,11 @@ from xp.services.conbus.conbus_datapoint_service import (
|
|
|
33
31
|
ConbusDatapointService,
|
|
34
32
|
)
|
|
35
33
|
from xp.services.conbus.conbus_discover_service import ConbusDiscoverService
|
|
36
|
-
from xp.services.conbus.conbus_lightlevel_set_service import ConbusLightlevelSetService
|
|
37
|
-
from xp.services.conbus.conbus_linknumber_get_service import ConbusLinknumberGetService
|
|
38
|
-
from xp.services.conbus.conbus_linknumber_set_service import ConbusLinknumberSetService
|
|
39
34
|
from xp.services.conbus.conbus_output_service import ConbusOutputService
|
|
40
35
|
from xp.services.conbus.conbus_raw_service import ConbusRawService
|
|
41
36
|
from xp.services.conbus.conbus_receive_service import ConbusReceiveService
|
|
42
37
|
from xp.services.conbus.conbus_scan_service import ConbusScanService
|
|
38
|
+
from xp.services.conbus.write_config_service import WriteConfigService
|
|
43
39
|
from xp.services.homekit.homekit_cache_service import HomeKitCacheService
|
|
44
40
|
from xp.services.homekit.homekit_conbus_service import HomeKitConbusService
|
|
45
41
|
from xp.services.homekit.homekit_dimminglight_service import HomeKitDimmingLightService
|
|
@@ -191,8 +187,9 @@ class ServiceContainer:
|
|
|
191
187
|
)
|
|
192
188
|
|
|
193
189
|
self.container.register(
|
|
194
|
-
|
|
195
|
-
factory=lambda:
|
|
190
|
+
WriteConfigService,
|
|
191
|
+
factory=lambda: WriteConfigService(
|
|
192
|
+
telegram_service=self.container.resolve(TelegramService),
|
|
196
193
|
cli_config=self.container.resolve(ConbusClientConfig),
|
|
197
194
|
reactor=self.container.resolve(PosixReactorBase),
|
|
198
195
|
),
|
|
@@ -247,45 +244,6 @@ class ServiceContainer:
|
|
|
247
244
|
scope=punq.Scope.singleton,
|
|
248
245
|
)
|
|
249
246
|
|
|
250
|
-
self.container.register(
|
|
251
|
-
ConbusAutoreportSetService,
|
|
252
|
-
factory=lambda: ConbusAutoreportSetService(
|
|
253
|
-
cli_config=self.container.resolve(ConbusClientConfig),
|
|
254
|
-
reactor=self.container.resolve(PosixReactorBase),
|
|
255
|
-
),
|
|
256
|
-
scope=punq.Scope.singleton,
|
|
257
|
-
)
|
|
258
|
-
|
|
259
|
-
self.container.register(
|
|
260
|
-
ConbusAutoreportGetService,
|
|
261
|
-
factory=lambda: ConbusAutoreportGetService(
|
|
262
|
-
telegram_service=self.container.resolve(TelegramService),
|
|
263
|
-
cli_config=self.container.resolve(ConbusClientConfig),
|
|
264
|
-
reactor=self.container.resolve(PosixReactorBase),
|
|
265
|
-
),
|
|
266
|
-
scope=punq.Scope.singleton,
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
self.container.register(
|
|
270
|
-
ConbusLinknumberGetService,
|
|
271
|
-
factory=lambda: ConbusLinknumberGetService(
|
|
272
|
-
telegram_service=self.container.resolve(TelegramService),
|
|
273
|
-
cli_config=self.container.resolve(ConbusClientConfig),
|
|
274
|
-
reactor=self.container.resolve(PosixReactorBase),
|
|
275
|
-
),
|
|
276
|
-
scope=punq.Scope.singleton,
|
|
277
|
-
)
|
|
278
|
-
|
|
279
|
-
self.container.register(
|
|
280
|
-
ConbusLinknumberSetService,
|
|
281
|
-
factory=lambda: ConbusLinknumberSetService(
|
|
282
|
-
telegram_service=self.container.resolve(TelegramService),
|
|
283
|
-
cli_config=self.container.resolve(ConbusClientConfig),
|
|
284
|
-
reactor=self.container.resolve(PosixReactorBase),
|
|
285
|
-
),
|
|
286
|
-
scope=punq.Scope.singleton,
|
|
287
|
-
)
|
|
288
|
-
|
|
289
247
|
self.container.register(
|
|
290
248
|
ConbusCustomService,
|
|
291
249
|
factory=lambda: ConbusCustomService(
|
xp/api/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""API module for FastAPI endpoints and models."""
|
xp/api/main.py
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
"""FastAPI application for XP Protocol API endpoints."""
|
|
2
|
-
|
|
3
|
-
import logging
|
|
4
|
-
import os
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from typing import Any
|
|
7
|
-
|
|
8
|
-
import yaml
|
|
9
|
-
from fastapi import FastAPI
|
|
10
|
-
from fastapi.middleware.cors import CORSMiddleware
|
|
11
|
-
|
|
12
|
-
from xp.api.routers import conbus
|
|
13
|
-
from xp.utils.dependencies import ServiceContainer
|
|
14
|
-
|
|
15
|
-
# Set up logging
|
|
16
|
-
logging.basicConfig(level=logging.INFO)
|
|
17
|
-
logger = logging.getLogger(__name__)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def load_api_config() -> dict[str, Any]:
|
|
21
|
-
"""Load API configuration from api.yml or environment variables.
|
|
22
|
-
|
|
23
|
-
Returns:
|
|
24
|
-
Dictionary containing API configuration settings.
|
|
25
|
-
"""
|
|
26
|
-
config = {
|
|
27
|
-
"title": "XP Protocol API",
|
|
28
|
-
"description": "REST API for XP Protocol Conbus operations",
|
|
29
|
-
"version": "0.2.0",
|
|
30
|
-
"cors_origins": ["*"],
|
|
31
|
-
"cors_methods": ["GET", "POST"],
|
|
32
|
-
"cors_headers": ["*"],
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
# Try to load from api.yml
|
|
36
|
-
try:
|
|
37
|
-
if Path("api.yml").exists():
|
|
38
|
-
with Path("api.yml").open("r") as file:
|
|
39
|
-
file_config = yaml.safe_load(file)
|
|
40
|
-
if file_config:
|
|
41
|
-
config.update(file_config.get("api", {}))
|
|
42
|
-
logger.info("Loaded API configuration from api.yml")
|
|
43
|
-
except Exception as e:
|
|
44
|
-
logger.warning(f"Could not load api.yml: {e}")
|
|
45
|
-
|
|
46
|
-
# Override with environment variables
|
|
47
|
-
config["title"] = os.getenv("API_TITLE", config["title"])
|
|
48
|
-
config["description"] = os.getenv("API_DESCRIPTION", config["description"])
|
|
49
|
-
config["version"] = os.getenv("API_VERSION", config["version"])
|
|
50
|
-
|
|
51
|
-
# CORS configuration from environment
|
|
52
|
-
cors_origins = os.getenv("CORS_ORIGINS")
|
|
53
|
-
if cors_origins is not None:
|
|
54
|
-
config["cors_origins"] = cors_origins.split(",")
|
|
55
|
-
cors_methods = os.getenv("CORS_METHODS")
|
|
56
|
-
if cors_methods is not None:
|
|
57
|
-
config["cors_methods"] = cors_methods.split(",")
|
|
58
|
-
cors_headers = os.getenv("CORS_HEADERS")
|
|
59
|
-
if cors_headers is not None:
|
|
60
|
-
config["cors_headers"] = cors_headers.split(",")
|
|
61
|
-
|
|
62
|
-
return config
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def create_app(container: ServiceContainer) -> FastAPI:
|
|
66
|
-
"""Create and configure the FastAPI application.
|
|
67
|
-
|
|
68
|
-
Args:
|
|
69
|
-
container: Optional ServiceContainer instance. If not provided, a new one will be created.
|
|
70
|
-
|
|
71
|
-
Returns:
|
|
72
|
-
Configured FastAPI application instance.
|
|
73
|
-
"""
|
|
74
|
-
config = load_api_config()
|
|
75
|
-
|
|
76
|
-
fastapi = FastAPI(
|
|
77
|
-
title=config["title"],
|
|
78
|
-
description=config["description"],
|
|
79
|
-
version=config["version"],
|
|
80
|
-
docs_url="/docs",
|
|
81
|
-
redoc_url="/redoc",
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
# Add CORS middleware
|
|
85
|
-
fastapi.add_middleware(
|
|
86
|
-
CORSMiddleware,
|
|
87
|
-
allow_origins=config["cors_origins"],
|
|
88
|
-
allow_credentials=True,
|
|
89
|
-
allow_methods=config["cors_methods"],
|
|
90
|
-
allow_headers=config["cors_headers"],
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
# Initialize service container
|
|
94
|
-
fastapi.state.container = container
|
|
95
|
-
|
|
96
|
-
# Include routers
|
|
97
|
-
fastapi.include_router(conbus.router)
|
|
98
|
-
|
|
99
|
-
# Health check endpoint
|
|
100
|
-
@fastapi.get("/health")
|
|
101
|
-
async def health_check() -> dict[str, str]:
|
|
102
|
-
"""Return health status of the API.
|
|
103
|
-
|
|
104
|
-
Returns:
|
|
105
|
-
Dictionary containing status and service information.
|
|
106
|
-
"""
|
|
107
|
-
return {"status": "healthy", "service": "xp-api"}
|
|
108
|
-
|
|
109
|
-
# Root endpoint
|
|
110
|
-
@fastapi.get("/")
|
|
111
|
-
async def root() -> dict[str, str]:
|
|
112
|
-
"""Return API information and available endpoints.
|
|
113
|
-
|
|
114
|
-
Returns:
|
|
115
|
-
Dictionary containing API metadata and endpoint links.
|
|
116
|
-
"""
|
|
117
|
-
return {
|
|
118
|
-
"message": "XP Protocol API",
|
|
119
|
-
"version": config["version"],
|
|
120
|
-
"docs": "/docs",
|
|
121
|
-
"health": "/health",
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
logger.info(f"FastAPI application created: {config['title']} v{config['version']}")
|
|
125
|
-
return fastapi
|
xp/api/models/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""API models for request and response validation."""
|
xp/api/models/api.py
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"""Pydantic models for Input API endpoints."""
|
|
2
|
-
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class ApiResponse(BaseModel):
|
|
9
|
-
"""Response model for successful Input operation.
|
|
10
|
-
|
|
11
|
-
Attributes:
|
|
12
|
-
success: Operation success status.
|
|
13
|
-
result: Result value.
|
|
14
|
-
description: Description of the result.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
success: bool = Field(default=True, description="Operation success status")
|
|
18
|
-
result: Optional[str] = Field(default=None, description="Result")
|
|
19
|
-
description: Optional[str] = Field(default=None, description="Description")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class ApiErrorResponse(BaseModel):
|
|
23
|
-
"""Response model for failed Input operation.
|
|
24
|
-
|
|
25
|
-
Attributes:
|
|
26
|
-
success: Operation success status (always False).
|
|
27
|
-
error: Error message describing what went wrong.
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
success: bool = Field(default=False, description="Operation success status")
|
|
31
|
-
error: str = Field(..., description="Error message")
|
xp/api/models/discover.py
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"""Pydantic models for discover API endpoints."""
|
|
2
|
-
|
|
3
|
-
from typing import List
|
|
4
|
-
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class DiscoverResponse(BaseModel):
|
|
9
|
-
"""Response model for successful discover operation.
|
|
10
|
-
|
|
11
|
-
Attributes:
|
|
12
|
-
success: Operation success status.
|
|
13
|
-
devices: List of discovered device information strings.
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
success: bool = Field(default=True, description="Operation success status")
|
|
17
|
-
devices: List[str] = Field(
|
|
18
|
-
default_factory=list, description="Parsed device information"
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class DiscoverErrorResponse(BaseModel):
|
|
23
|
-
"""Response model for failed discover operation.
|
|
24
|
-
|
|
25
|
-
Attributes:
|
|
26
|
-
success: Operation success status (always False).
|
|
27
|
-
error: Error message describing what went wrong.
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
success: bool = Field(default=False, description="Operation success status")
|
|
31
|
-
error: str = Field(..., description="Error message")
|
xp/api/routers/__init__.py
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"""API routers for FastAPI endpoints."""
|
|
2
|
-
|
|
3
|
-
from xp.api.routers import (
|
|
4
|
-
conbus_blink,
|
|
5
|
-
conbus_custom,
|
|
6
|
-
conbus_datapoint,
|
|
7
|
-
conbus_output,
|
|
8
|
-
)
|
|
9
|
-
from xp.api.routers.conbus import router
|
|
10
|
-
|
|
11
|
-
__all__ = [
|
|
12
|
-
"router",
|
|
13
|
-
"conbus_blink",
|
|
14
|
-
"conbus_custom",
|
|
15
|
-
"conbus_datapoint",
|
|
16
|
-
"conbus_output",
|
|
17
|
-
]
|
xp/api/routers/conbus.py
DELETED
xp/api/routers/conbus_blink.py
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
"""FastAPI router for Conbus operations."""
|
|
2
|
-
|
|
3
|
-
import json
|
|
4
|
-
import logging
|
|
5
|
-
from typing import Union
|
|
6
|
-
|
|
7
|
-
from fastapi import Request
|
|
8
|
-
from fastapi.responses import JSONResponse
|
|
9
|
-
|
|
10
|
-
from xp.api.models.api import ApiErrorResponse, ApiResponse
|
|
11
|
-
from xp.api.routers.conbus import router
|
|
12
|
-
from xp.api.routers.errors import handle_service_error
|
|
13
|
-
from xp.services.conbus.conbus_blink_service import ConbusBlinkService
|
|
14
|
-
|
|
15
|
-
logger = logging.getLogger(__name__)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@router.get(
|
|
19
|
-
"/blink/on/{serial_number}",
|
|
20
|
-
response_model=Union[ApiResponse, ApiErrorResponse],
|
|
21
|
-
responses={
|
|
22
|
-
200: {"model": ApiResponse, "description": "Input completed successfully"},
|
|
23
|
-
400: {"model": ApiErrorResponse, "description": "Connection or request error"},
|
|
24
|
-
408: {"model": ApiErrorResponse, "description": "Request timeout"},
|
|
25
|
-
500: {"model": ApiErrorResponse, "description": "Internal server error"},
|
|
26
|
-
},
|
|
27
|
-
)
|
|
28
|
-
async def blink_on(
|
|
29
|
-
request: Request,
|
|
30
|
-
serial_number: str = "1702033007",
|
|
31
|
-
) -> Union[ApiResponse, ApiErrorResponse, JSONResponse]:
|
|
32
|
-
"""Turn on device blinking.
|
|
33
|
-
|
|
34
|
-
Sends a blink on telegram to make the device blink.
|
|
35
|
-
|
|
36
|
-
Args:
|
|
37
|
-
request: FastAPI request object.
|
|
38
|
-
serial_number: Serial number of the device.
|
|
39
|
-
|
|
40
|
-
Returns:
|
|
41
|
-
API response with blink result or error.
|
|
42
|
-
"""
|
|
43
|
-
service = request.app.state.container.get_container().resolve(ConbusBlinkService)
|
|
44
|
-
|
|
45
|
-
# SendInput telegram and receive responses
|
|
46
|
-
with service:
|
|
47
|
-
response = service.send_blink_telegram(
|
|
48
|
-
serial_number=serial_number, on_or_off="on"
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
if not response.success:
|
|
52
|
-
return handle_service_error(response.error or "Unknown error")
|
|
53
|
-
|
|
54
|
-
logger.debug(json.dumps(response.to_dict(), indent=2))
|
|
55
|
-
|
|
56
|
-
# Build successful response
|
|
57
|
-
return ApiResponse(
|
|
58
|
-
success=True,
|
|
59
|
-
result=response.system_function.name,
|
|
60
|
-
description=(
|
|
61
|
-
response.reply_telegram.system_function.get_description()
|
|
62
|
-
if response.reply_telegram and response.reply_telegram.system_function
|
|
63
|
-
else None
|
|
64
|
-
),
|
|
65
|
-
# raw_telegram = response.output_telegram.raw_telegram,
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
@router.get(
|
|
70
|
-
"/blink/off/{serial_number}",
|
|
71
|
-
response_model=Union[ApiResponse, ApiErrorResponse],
|
|
72
|
-
responses={
|
|
73
|
-
200: {"model": ApiResponse, "description": "Input completed successfully"},
|
|
74
|
-
400: {"model": ApiErrorResponse, "description": "Connection or request error"},
|
|
75
|
-
408: {"model": ApiErrorResponse, "description": "Request timeout"},
|
|
76
|
-
500: {"model": ApiErrorResponse, "description": "Internal server error"},
|
|
77
|
-
},
|
|
78
|
-
)
|
|
79
|
-
async def blink_off(
|
|
80
|
-
request: Request,
|
|
81
|
-
serial_number: str = "1702033007",
|
|
82
|
-
) -> Union[ApiResponse, ApiErrorResponse, JSONResponse]:
|
|
83
|
-
"""Turn off device blinking.
|
|
84
|
-
|
|
85
|
-
Sends a blink off telegram to stop the device from blinking.
|
|
86
|
-
|
|
87
|
-
Args:
|
|
88
|
-
request: FastAPI request object.
|
|
89
|
-
serial_number: Serial number of the device.
|
|
90
|
-
|
|
91
|
-
Returns:
|
|
92
|
-
API response with blink result or error.
|
|
93
|
-
"""
|
|
94
|
-
service = request.app.state.container.get_container().resolve(ConbusBlinkService)
|
|
95
|
-
|
|
96
|
-
# SendInput telegram and receive responses
|
|
97
|
-
with service:
|
|
98
|
-
response = service.send_blink_telegram(
|
|
99
|
-
serial_number=serial_number, on_or_off="off"
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
if not response.success:
|
|
103
|
-
return handle_service_error(response.error or "Unknown error")
|
|
104
|
-
|
|
105
|
-
logger.debug(json.dumps(response.to_dict(), indent=2))
|
|
106
|
-
|
|
107
|
-
# Build successful response
|
|
108
|
-
return ApiResponse(
|
|
109
|
-
success=True,
|
|
110
|
-
result=response.system_function.name,
|
|
111
|
-
description=(
|
|
112
|
-
response.reply_telegram.system_function.get_description()
|
|
113
|
-
if response.reply_telegram and response.reply_telegram.system_function
|
|
114
|
-
else None
|
|
115
|
-
),
|
|
116
|
-
# raw_telegram = response.output_telegram.raw_telegram,
|
|
117
|
-
)
|
xp/api/routers/conbus_custom.py
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
"""FastAPI router for Conbus operations."""
|
|
2
|
-
|
|
3
|
-
import logging
|
|
4
|
-
from typing import Union
|
|
5
|
-
|
|
6
|
-
from fastapi import Request
|
|
7
|
-
from fastapi.responses import JSONResponse
|
|
8
|
-
|
|
9
|
-
from xp.api.models.api import ApiErrorResponse, ApiResponse
|
|
10
|
-
from xp.api.routers.conbus import router
|
|
11
|
-
from xp.api.routers.errors import handle_service_error
|
|
12
|
-
from xp.services.conbus.conbus_custom_service import ConbusCustomService
|
|
13
|
-
|
|
14
|
-
logger = logging.getLogger(__name__)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@router.get(
|
|
18
|
-
"/custom/{serial_number}/{function_code}/{data}",
|
|
19
|
-
response_model=Union[ApiResponse, ApiErrorResponse],
|
|
20
|
-
responses={
|
|
21
|
-
200: {"model": ApiResponse, "description": "Datapoint completed successfully"},
|
|
22
|
-
400: {"model": ApiErrorResponse, "description": "Connection or request error"},
|
|
23
|
-
408: {"model": ApiErrorResponse, "description": "Request timeout"},
|
|
24
|
-
500: {"model": ApiErrorResponse, "description": "Internal server error"},
|
|
25
|
-
},
|
|
26
|
-
)
|
|
27
|
-
async def custom_function(
|
|
28
|
-
request: Request,
|
|
29
|
-
serial_number: str = "1702033007",
|
|
30
|
-
function_code: str = "02",
|
|
31
|
-
data: str = "00",
|
|
32
|
-
) -> Union[ApiResponse, ApiErrorResponse, JSONResponse]:
|
|
33
|
-
"""Execute a custom function on a device.
|
|
34
|
-
|
|
35
|
-
Sends a custom telegram with specified function code and data.
|
|
36
|
-
|
|
37
|
-
Args:
|
|
38
|
-
request: FastAPI request object.
|
|
39
|
-
serial_number: Serial number of the device.
|
|
40
|
-
function_code: Function code to execute.
|
|
41
|
-
data: Data to send with the function.
|
|
42
|
-
|
|
43
|
-
Returns:
|
|
44
|
-
API response with custom function result or error.
|
|
45
|
-
"""
|
|
46
|
-
service = request.app.state.container.get_container().resolve(ConbusCustomService)
|
|
47
|
-
# SendDatapoint telegram and receive responses
|
|
48
|
-
with service:
|
|
49
|
-
response = service.send_custom_telegram(serial_number, function_code, data)
|
|
50
|
-
|
|
51
|
-
if not response.success:
|
|
52
|
-
return handle_service_error(response.error or "Unknown error")
|
|
53
|
-
|
|
54
|
-
if response.reply_telegram is None:
|
|
55
|
-
return ApiErrorResponse(
|
|
56
|
-
success=False,
|
|
57
|
-
error=response.error or "Unknown error",
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
# Build successful response
|
|
61
|
-
if response.reply_telegram and response.reply_telegram.datapoint_type:
|
|
62
|
-
return ApiResponse(
|
|
63
|
-
success=True,
|
|
64
|
-
result=response.reply_telegram.data_value,
|
|
65
|
-
description=response.reply_telegram.datapoint_type.name,
|
|
66
|
-
)
|
|
67
|
-
return ApiResponse(
|
|
68
|
-
success=True,
|
|
69
|
-
result=response.reply_telegram.data_value,
|
|
70
|
-
description="Custom command executed successfully",
|
|
71
|
-
)
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
"""FastAPI router for Conbus operations."""
|
|
2
|
-
|
|
3
|
-
import logging
|
|
4
|
-
from typing import Union
|
|
5
|
-
|
|
6
|
-
from fastapi import Request
|
|
7
|
-
from fastapi.responses import JSONResponse
|
|
8
|
-
|
|
9
|
-
from xp.api.models.api import ApiErrorResponse, ApiResponse
|
|
10
|
-
from xp.api.routers.conbus import router
|
|
11
|
-
from xp.api.routers.errors import handle_service_error
|
|
12
|
-
from xp.models.telegram.datapoint_type import DataPointType
|
|
13
|
-
from xp.services.conbus.conbus_datapoint_service import ConbusDatapointService
|
|
14
|
-
|
|
15
|
-
logger = logging.getLogger(__name__)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@router.get(
|
|
19
|
-
"/datapoint/{datapoint}/{serial_number}",
|
|
20
|
-
response_model=Union[ApiResponse, ApiErrorResponse],
|
|
21
|
-
responses={
|
|
22
|
-
200: {"model": ApiResponse, "description": "Datapoint completed successfully"},
|
|
23
|
-
400: {"model": ApiErrorResponse, "description": "Connection or request error"},
|
|
24
|
-
408: {"model": ApiErrorResponse, "description": "Request timeout"},
|
|
25
|
-
500: {"model": ApiErrorResponse, "description": "Internal server error"},
|
|
26
|
-
},
|
|
27
|
-
)
|
|
28
|
-
async def datapoint_devices(
|
|
29
|
-
request: Request,
|
|
30
|
-
datapoint: DataPointType = DataPointType.SW_VERSION,
|
|
31
|
-
serial_number: str = "1702033007",
|
|
32
|
-
) -> Union[ApiResponse, ApiErrorResponse, JSONResponse]:
|
|
33
|
-
"""Query a datapoint value from a device.
|
|
34
|
-
|
|
35
|
-
Sends a datapoint query telegram and retrieves the requested datapoint value.
|
|
36
|
-
|
|
37
|
-
Args:
|
|
38
|
-
request: FastAPI request object.
|
|
39
|
-
datapoint: Type of datapoint to query (default: SW_VERSION).
|
|
40
|
-
serial_number: Serial number of the device.
|
|
41
|
-
|
|
42
|
-
Returns:
|
|
43
|
-
API response with datapoint value or error.
|
|
44
|
-
"""
|
|
45
|
-
service = request.app.state.container.get_container().resolve(
|
|
46
|
-
ConbusDatapointService
|
|
47
|
-
)
|
|
48
|
-
# SendDatapoint telegram and receive responses
|
|
49
|
-
with service:
|
|
50
|
-
response = service.query_datapoint(
|
|
51
|
-
datapoint_type=datapoint, serial_number=serial_number
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
if not response.success:
|
|
55
|
-
return handle_service_error(response.error or "Unknown error")
|
|
56
|
-
|
|
57
|
-
if response.datapoint_telegram is None:
|
|
58
|
-
return ApiErrorResponse(
|
|
59
|
-
success=False,
|
|
60
|
-
error=response.error or "Unknown error",
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
# Build successful response
|
|
64
|
-
if response.datapoint_telegram and response.datapoint_telegram.datapoint_type:
|
|
65
|
-
return ApiResponse(
|
|
66
|
-
success=True,
|
|
67
|
-
result=response.datapoint_telegram.data_value,
|
|
68
|
-
description=response.datapoint_telegram.datapoint_type.name,
|
|
69
|
-
)
|
|
70
|
-
return ApiResponse(
|
|
71
|
-
success=True,
|
|
72
|
-
result=response.datapoint_telegram.data_value,
|
|
73
|
-
description="Datapoint value retrieved",
|
|
74
|
-
)
|