aioccl 2024.12__tar.gz → 2024.12.3__tar.gz
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.
- {aioccl-2024.12 → aioccl-2024.12.3}/PKG-INFO +1 -1
- {aioccl-2024.12 → aioccl-2024.12.3}/aioccl/device.py +33 -31
- {aioccl-2024.12 → aioccl-2024.12.3}/aioccl/server.py +32 -40
- {aioccl-2024.12 → aioccl-2024.12.3}/aioccl.egg-info/PKG-INFO +1 -1
- {aioccl-2024.12 → aioccl-2024.12.3}/setup.py +1 -1
- {aioccl-2024.12 → aioccl-2024.12.3}/LICENSE +0 -0
- {aioccl-2024.12 → aioccl-2024.12.3}/README.md +0 -0
- {aioccl-2024.12 → aioccl-2024.12.3}/aioccl/__init__.py +0 -0
- {aioccl-2024.12 → aioccl-2024.12.3}/aioccl/sensor.py +0 -0
- {aioccl-2024.12 → aioccl-2024.12.3}/aioccl.egg-info/SOURCES.txt +0 -0
- {aioccl-2024.12 → aioccl-2024.12.3}/aioccl.egg-info/dependency_links.txt +0 -0
- {aioccl-2024.12 → aioccl-2024.12.3}/aioccl.egg-info/requires.txt +0 -0
- {aioccl-2024.12 → aioccl-2024.12.3}/aioccl.egg-info/top_level.txt +0 -0
- {aioccl-2024.12 → aioccl-2024.12.3}/setup.cfg +0 -0
@@ -1,4 +1,5 @@
|
|
1
1
|
"""CCL device mapping."""
|
2
|
+
|
2
3
|
from __future__ import annotations
|
3
4
|
|
4
5
|
import logging
|
@@ -11,72 +12,73 @@ _LOGGER = logging.getLogger(__name__)
|
|
11
12
|
|
12
13
|
CCL_DEVICE_INFO_TYPES = ("serial_no", "mac_address", "model", "fw_ver")
|
13
14
|
|
15
|
+
|
14
16
|
class CCLDevice:
|
17
|
+
"""Mapping for a CCL device."""
|
18
|
+
_binary_sensors: dict[str, CCLSensor] | None = {}
|
19
|
+
_fw_ver: str | None
|
20
|
+
_last_updated_time: float | None
|
21
|
+
_mac_address: str | None
|
22
|
+
_model: str | None
|
23
|
+
_new_binary_sensor_callbacks = set()
|
24
|
+
_new_sensors: list[CCLSensor] | None = []
|
25
|
+
_new_sensor_callbacks = set()
|
26
|
+
_sensors: dict[str, CCLSensor] | None = {}
|
27
|
+
_serial_no: str | None
|
28
|
+
_update_callbacks = set()
|
29
|
+
|
30
|
+
|
15
31
|
def __init__(self, passkey: str):
|
16
32
|
"""Initialize a CCL device."""
|
17
|
-
_LOGGER.debug(
|
33
|
+
_LOGGER.debug("Initializing CCL Device: %s", self)
|
18
34
|
self._passkey = passkey
|
19
|
-
|
20
|
-
self._serial_no: str | None
|
21
|
-
self._mac_address: str | None
|
22
|
-
self._model: str | None
|
23
|
-
self._fw_ver: str | None
|
24
|
-
self._binary_sensors: dict[str, CCLSensor] | None = {}
|
25
|
-
self._sensors: dict[str, CCLSensor] | None = {}
|
26
|
-
self._last_updated_time: float | None
|
27
|
-
|
28
|
-
self._new_sensors: list[CCLSensor] | None = []
|
29
|
-
|
30
|
-
self._update_callbacks = set()
|
31
|
-
self._new_binary_sensor_callbacks = set()
|
32
|
-
self._new_sensor_callbacks = set()
|
33
|
-
|
35
|
+
|
34
36
|
@property
|
35
37
|
def passkey(self) -> str:
|
36
38
|
"""Return the passkey."""
|
37
39
|
return self._passkey
|
38
|
-
|
40
|
+
|
39
41
|
@property
|
40
42
|
def device_id(self) -> str | None:
|
41
43
|
"""Return the device ID."""
|
42
44
|
return self._mac_address.replace(":", "").lower()[-6:]
|
43
|
-
|
45
|
+
|
44
46
|
@property
|
45
47
|
def name(self) -> str | None:
|
46
48
|
"""Return the display name."""
|
47
49
|
return self._model + " - " + self.device_id
|
48
|
-
|
50
|
+
|
49
51
|
@property
|
50
52
|
def mac_address(self) -> str | None:
|
51
53
|
"""Return the MAC address."""
|
52
54
|
return self._mac_address
|
53
|
-
|
55
|
+
|
54
56
|
@property
|
55
57
|
def model(self) -> str | None:
|
56
58
|
"""Return the model."""
|
57
59
|
return self._model
|
58
|
-
|
60
|
+
|
59
61
|
@property
|
60
62
|
def fw_ver(self) -> str | None:
|
61
63
|
"""Return the firmware version."""
|
62
64
|
return self._fw_ver
|
63
|
-
|
65
|
+
|
64
66
|
@property
|
65
67
|
def binary_sensors(self) -> dict[str, CCLSensor] | None:
|
66
68
|
"""Store binary sensor data under this device."""
|
67
69
|
return self._binary_sensors
|
68
|
-
|
70
|
+
|
69
71
|
@property
|
70
72
|
def sensors(self) -> dict[str, CCLSensor] | None:
|
71
73
|
"""Store sensor data under this device."""
|
72
74
|
return self._sensors
|
73
|
-
|
75
|
+
|
74
76
|
def update_info(self, info: dict[str, None | str]) -> None:
|
75
77
|
"""Add or update device info."""
|
76
|
-
self._mac_address = info.get(
|
77
|
-
self._model = info.get(
|
78
|
-
self._fw_ver = info.get(
|
79
|
-
|
78
|
+
self._mac_address = info.get("mac_address")
|
79
|
+
self._model = info.get("model")
|
80
|
+
self._fw_ver = info.get("fw_ver")
|
81
|
+
|
80
82
|
def update_sensors(self, sensors: dict[str, None | str | int | float]) -> None:
|
81
83
|
"""Add or update all sensor values."""
|
82
84
|
for key, value in sensors.items():
|
@@ -108,7 +110,7 @@ class CCLDevice:
|
|
108
110
|
try:
|
109
111
|
for callback in self._update_callbacks:
|
110
112
|
callback()
|
111
|
-
except Exception as err:
|
113
|
+
except Exception as err: # pylint: disable=broad-exception-caught
|
112
114
|
_LOGGER.warning("Error while publishing sensor updates: %s", err)
|
113
115
|
|
114
116
|
def register_new_binary_sensor_cb(self, callback: Callable[[], None]) -> None:
|
@@ -139,5 +141,5 @@ class CCLDevice:
|
|
139
141
|
for callback in self._new_sensor_callbacks:
|
140
142
|
callback(sensor)
|
141
143
|
self._new_sensors.remove(sensor)
|
142
|
-
except Exception as err:
|
143
|
-
_LOGGER.warning("Error while publishing new sensors: %s", err)
|
144
|
+
except Exception as err: # pylint: disable=broad-exception-caught
|
145
|
+
_LOGGER.warning("Error while publishing new sensors: %s", err)
|
@@ -3,6 +3,7 @@
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
5
|
import logging
|
6
|
+
from typing import Callable
|
6
7
|
|
7
8
|
from aiohttp import web
|
8
9
|
|
@@ -20,47 +21,39 @@ class CCLServer:
|
|
20
21
|
devices: dict[str, CCLDevice] = {}
|
21
22
|
|
22
23
|
@staticmethod
|
23
|
-
def
|
24
|
-
"""
|
24
|
+
def register(device: CCLDevice) -> None:
|
25
|
+
"""Register a device with a passkey."""
|
25
26
|
CCLServer.devices.setdefault(device.passkey, device)
|
26
|
-
_LOGGER.debug(
|
27
|
-
|
28
|
-
# routes = web.RouteTableDef()
|
27
|
+
_LOGGER.debug("Device registered: %s", device)
|
29
28
|
|
29
|
+
@staticmethod
|
30
|
+
def get_handler() -> Callable[[web.BaseRequest], web.Response]:
|
31
|
+
"""Get the handler."""
|
32
|
+
return CCLServer._handler
|
33
|
+
|
30
34
|
@staticmethod
|
31
35
|
async def _handler(request: web.BaseRequest) -> web.Response:
|
32
36
|
"""Handle POST requests for data updating."""
|
33
|
-
|
34
|
-
class HandlerStorage:
|
35
|
-
"""Store data for a single request."""
|
36
|
-
|
37
|
-
body: dict[str, None | str | int | float]
|
38
|
-
info: dict[str, None | str]
|
39
|
-
sensors: dict[str, None | str | int | float]
|
40
|
-
|
41
|
-
_LOGGER.debug("Request received.")
|
42
|
-
|
43
|
-
# Resetting variables
|
37
|
+
_body: dict[str, None | str | int | float] = {}
|
44
38
|
_device: CCLDevice = None
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
HandlerStorage.sensors = {}
|
49
|
-
|
39
|
+
_info: dict[str, None | str] = {}
|
40
|
+
_passkey: str = ''
|
41
|
+
_sensors: dict[str, None | str | int | float] = {}
|
50
42
|
_status: None | int = None
|
51
43
|
_text: None | str = None
|
52
44
|
|
53
45
|
try:
|
54
|
-
for passkey
|
46
|
+
for passkey in CCLServer.devices:
|
55
47
|
if passkey == request.match_info["passkey"]:
|
48
|
+
_passkey = passkey
|
56
49
|
break
|
50
|
+
_device = CCLServer.devices[_passkey]
|
57
51
|
assert _device, 404
|
58
52
|
|
59
53
|
assert request.content_type == "application/json", 400
|
60
54
|
assert 0 < request.content_length <= 5000, 400
|
61
55
|
|
62
|
-
|
63
|
-
_LOGGER.debug(HandlerStorage.body)
|
56
|
+
_body = await request.json()
|
64
57
|
|
65
58
|
except Exception as err: # pylint: disable=broad-exception-caught
|
66
59
|
_status = err.args[0]
|
@@ -74,30 +67,29 @@ class CCLServer:
|
|
74
67
|
_LOGGER.debug("Request exception occured: %s", err)
|
75
68
|
return web.Response(status=_status, text=_text)
|
76
69
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
70
|
+
|
71
|
+
for key, value in _body.items():
|
72
|
+
if key in CCL_DEVICE_INFO_TYPES:
|
73
|
+
_info.setdefault(key, value)
|
74
|
+
elif key in CCL_SENSORS:
|
75
|
+
_sensors.setdefault(key, value)
|
76
|
+
|
77
|
+
_device.update_info(_info)
|
78
|
+
_device.update_sensors(_sensors)
|
79
|
+
_status = 200
|
80
|
+
_text = "200 OK"
|
81
|
+
_LOGGER.debug("Request processed: %s", _passkey)
|
82
|
+
return web.Response(status=_status, text=_text)
|
90
83
|
|
91
84
|
app = web.Application()
|
92
|
-
|
93
85
|
app.add_routes([web.get('/{passkey}', _handler)])
|
86
|
+
runner = web.AppRunner(app)
|
94
87
|
|
95
88
|
@staticmethod
|
96
89
|
async def run() -> None:
|
97
|
-
"""Try to run the API server
|
90
|
+
"""Try to run the API server."""
|
98
91
|
try:
|
99
92
|
_LOGGER.debug("Trying to start the API server.")
|
100
|
-
CCLServer.runner = web.AppRunner(CCLServer.app)
|
101
93
|
await CCLServer.runner.setup()
|
102
94
|
site = web.TCPSite(CCLServer.runner, port=CCLServer.LISTEN_PORT)
|
103
95
|
await site.start()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|