aioccl 2025.3.1__py3-none-any.whl → 2025.4__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.
aioccl/device.py CHANGED
@@ -27,6 +27,11 @@ class CCLDevice:
27
27
  model: str | None
28
28
  passkey: str
29
29
  serial_no: str | None
30
+
31
+ class Data(TypedDict):
32
+ """Store sensor data."""
33
+ binary_sensors: dict[str, CCLSensor]
34
+ sensors: dict[str, CCLSensor]
30
35
 
31
36
  self._info: Info = {
32
37
  "fw_ver": None,
@@ -36,10 +41,13 @@ class CCLDevice:
36
41
  "passkey": passkey,
37
42
  "serial_no": None,
38
43
  }
39
-
40
- self._binary_sensors: dict[str, CCLSensor] | None = {}
41
- self._sensors: dict[str, CCLSensor] | None = {}
42
- self._update_callbacks = {}
44
+
45
+ self._data: Data = {
46
+ "binary_sensors": {},
47
+ "sensors": {}
48
+ }
49
+
50
+ self._update_callback = {}
43
51
 
44
52
  self._new_binary_sensor_callbacks = set()
45
53
  self._new_sensors: list[CCLSensor] | None = []
@@ -85,14 +93,9 @@ class CCLDevice:
85
93
  return self._info["fw_ver"]
86
94
 
87
95
  @property
88
- def binary_sensors(self) -> dict[str, CCLSensor] | None:
89
- """Store binary sensor data under this device."""
90
- return self._binary_sensors
91
-
92
- @property
93
- def sensors(self) -> dict[str, CCLSensor] | None:
94
- """Store sensor data under this device."""
95
- return self._sensors
96
+ def get_data(self) -> dict[str, dict[str, CCLSensor]]:
97
+ """Get all types of sensor data under this device."""
98
+ return self._data
96
99
 
97
100
  def update_info(self, new_info: dict[str, None | str]) -> None:
98
101
  """Add or update device info."""
@@ -101,19 +104,19 @@ class CCLDevice:
101
104
  self._info[key] = str(value)
102
105
  self._info["last_update_time"] = time.monotonic()
103
106
 
104
- def update_sensors(self, sensors: dict[str, None | str | int | float]) -> None:
107
+ def process_data(self, data: dict[str, None | str | int | float]) -> None:
105
108
  """Add or update all sensor values."""
106
- for key, value in sensors.items():
109
+ for key, value in data.items():
107
110
  if CCL_SENSORS.get(key).binary:
108
- if key not in self.binary_sensors:
109
- self._binary_sensors[key] = CCLSensor(key)
110
- self._new_sensors.append(self.binary_sensors[key])
111
- self._binary_sensors[key].value = value
111
+ if key not in self._data["binary_sensors"]:
112
+ self._data["binary_sensors"][key] = CCLSensor(key)
113
+ self._new_sensors.append(self._data["binary_sensors"][key])
114
+ self._data["binary_sensors"][key].value = value
112
115
  else:
113
- if key not in self.sensors:
114
- self._sensors[key] = CCLSensor(key)
115
- self._new_sensors.append(self.sensors[key])
116
- self._sensors[key].value = value
116
+ if key not in self._data["sensors"]:
117
+ self._data["sensors"][key] = CCLSensor(key)
118
+ self._new_sensors.append(self._data["sensors"][key])
119
+ self._data["sensors"][key].value = value
117
120
 
118
121
  add_count = self._publish_new_sensors()
119
122
  _LOGGER.debug(
@@ -123,65 +126,43 @@ class CCLDevice:
123
126
  self.last_update_time,
124
127
  )
125
128
 
126
- update_count = self._publish_updates()
129
+ self._publish_updates()
127
130
  _LOGGER.debug(
128
- "Updated %s sensors in total for device %s at %s.",
129
- update_count,
131
+ "Updating sensor data for device %s at %s.",
130
132
  self.device_id,
131
133
  self.last_update_time,
132
134
  )
133
135
 
134
- def register_update_cb(self, sensor_key, callback: Callable[[], None]) -> None:
135
- """Register callback, called when Sensor changes state."""
136
- self._update_callbacks[sensor_key] = callback
137
-
138
- def remove_update_cb(self, sensor_key, callback: Callable[[], None]) -> None:
139
- """Remove previously registered callback."""
140
- self._update_callbacks.pop(sensor_key, None)
141
-
142
- def _publish_updates(self) -> int:
143
- """Schedule call all registered callbacks."""
144
- count = 0
145
- for sensor_key, callback in self._update_callbacks.items():
146
- try:
147
- callback()
148
- count += 1
149
- except Exception as err: # pylint: disable=broad-exception-caught
150
- _LOGGER.warning(
151
- "Error while updating sensor %s for device %s: %s",
152
- sensor_key,
153
- self.device_id,
154
- err,
155
- )
156
- return count
157
-
158
- def register_new_binary_sensor_cb(self, callback: Callable[[], None]) -> None:
159
- """Register callback, called when Sensor changes state."""
160
- self._new_binary_sensor_callbacks.add(callback)
161
-
162
- def remove_new_binary_sensor_cb(self, callback: Callable[[], None]) -> None:
163
- """Remove previously registered callback."""
164
- self._new_binary_sensor_callbacks.discard(callback)
136
+ def set_update_callback(self, callback: Callable[[], None]) -> None:
137
+ """Set the callback function to update sensor data."""
138
+ self._update_callback = callback
139
+
140
+ def _publish_updates(self) -> None:
141
+ """Call the function to update sensor data."""
142
+ try:
143
+ self._update_callback(self._data)
144
+ except Exception as err: # pylint: disable=broad-exception-caught
145
+ _LOGGER.warning(
146
+ "Error while updating sensors for device %s: %s",
147
+ self.device_id,
148
+ err,
149
+ )
165
150
 
166
151
  def register_new_sensor_cb(self, callback: Callable[[], None]) -> None:
167
- """Register callback, called when Sensor changes state."""
152
+ """Register callback of adding a new sensor."""
168
153
  self._new_sensor_callbacks.add(callback)
169
154
 
170
155
  def remove_new_sensor_cb(self, callback: Callable[[], None]) -> None:
171
- """Remove previously registered callback."""
156
+ """Remove a registered callback."""
172
157
  self._new_sensor_callbacks.discard(callback)
173
158
 
174
159
  def _publish_new_sensors(self) -> None:
175
- """Schedule call all registered callbacks."""
160
+ """Schedule all registered callbacks to add new sensors."""
176
161
  count = 0
177
162
  for sensor in self._new_sensors[:]:
178
163
  try:
179
- if sensor.binary:
180
- for callback in self._new_binary_sensor_callbacks:
181
- callback(sensor)
182
- else:
183
- for callback in self._new_sensor_callbacks:
184
- callback(sensor)
164
+ for callback in self._new_sensor_callbacks:
165
+ callback(sensor)
185
166
  self._new_sensors.remove(sensor)
186
167
  count += 1
187
168
  except Exception as err: # pylint: disable=broad-exception-caught
aioccl/sensor.py CHANGED
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from dataclasses import dataclass
6
6
  import enum
7
-
7
+ from typing import Any
8
8
 
9
9
  class CCLSensor:
10
10
  """Class that represents a CCLSensor object in the aioCCL API."""
@@ -48,11 +48,6 @@ class CCLSensor:
48
48
  """Return the intrinsic sensor value."""
49
49
  if self.sensor_type.name in CCL_SENSOR_VALUES:
50
50
  return CCL_SENSOR_VALUES[self.sensor_type.name].get(self._value)
51
- if self.sensor_type == CCLSensorTypes.BATTERY_BINARY:
52
- try:
53
- return int(self._value) - 1
54
- except ValueError:
55
- pass
56
51
  return self._value
57
52
 
58
53
  @value.setter
@@ -108,16 +103,24 @@ class CCLDeviceCompartment(enum.Enum):
108
103
  STATUS = "Status"
109
104
 
110
105
 
111
- CCL_SENSOR_VALUES: dict[str, dict[str, str]] = {
106
+ CCL_SENSOR_VALUES: dict[str, dict[int, Any]] = {
112
107
  "CH_SENSOR_TYPE": {
113
- 2: "thermo-hygro",
114
- 3: "pool",
115
- 4: "soil",
108
+ 2: "Thermo-Hygro",
109
+ 3: "Pool",
110
+ 4: "Soil",
116
111
  },
117
- "LEAKAGE": {
118
- 0: "no_leak",
119
- 1: "leaking",
112
+ "BATTERY_BINARY": {
113
+ 0: 1,
114
+ 1: 0,
120
115
  },
116
+ "BATTERY": {
117
+ 0: 0,
118
+ 1: 0.2,
119
+ 2: 0.4,
120
+ 3: 0.6,
121
+ 4: 0.8,
122
+ 5: 1,
123
+ }
121
124
  }
122
125
 
123
126
  CCL_SENSORS: dict[str, CCLSensorPreset] = {
@@ -280,25 +283,25 @@ CCL_SENSORS: dict[str, CCLSensorPreset] = {
280
283
  "CH7 Type", CCLSensorTypes.CH_SENSOR_TYPE, CCLDeviceCompartment.OTHER
281
284
  ),
282
285
  "t6c1wls": CCLSensorPreset(
283
- "Leakage CH1", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER
286
+ "Leakage CH1", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER, True
284
287
  ),
285
288
  "t6c2wls": CCLSensorPreset(
286
- "Leakage CH2", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER
289
+ "Leakage CH2", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER, True
287
290
  ),
288
291
  "t6c3wls": CCLSensorPreset(
289
- "Leakage CH3", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER
292
+ "Leakage CH3", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER, True
290
293
  ),
291
294
  "t6c4wls": CCLSensorPreset(
292
- "Leakage CH4", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER
295
+ "Leakage CH4", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER, True
293
296
  ),
294
297
  "t6c5wls": CCLSensorPreset(
295
- "Leakage CH5", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER
298
+ "Leakage CH5", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER, True
296
299
  ),
297
300
  "t6c6wls": CCLSensorPreset(
298
- "Leakage CH6", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER
301
+ "Leakage CH6", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER, True
299
302
  ),
300
303
  "t6c7wls": CCLSensorPreset(
301
- "Leakage CH7", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER
304
+ "Leakage CH7", CCLSensorTypes.LEAKAGE, CCLDeviceCompartment.OTHER, True
302
305
  ),
303
306
  "t5lskm": CCLSensorPreset(
304
307
  "Lightning Distance",
aioccl/server.py CHANGED
@@ -29,10 +29,10 @@ class CCLServer:
29
29
  async def handler(request: web.BaseRequest | web.Request) -> web.Response:
30
30
  """Handle POST requests for data updating."""
31
31
  body: dict[str, None | str | int | float] = {}
32
+ data: dict[str, None | str | int | float] = {}
32
33
  device: CCLDevice = None
33
34
  info: dict[str, None | str] = {}
34
35
  passkey: str = ""
35
- sensors: dict[str, None | str | int | float] = {}
36
36
  status: None | int = None
37
37
  text: None | str = None
38
38
 
@@ -66,10 +66,10 @@ class CCLServer:
66
66
  if key in CCL_DEVICE_INFO_TYPES:
67
67
  info.setdefault(key, value)
68
68
  elif key in CCL_SENSORS:
69
- sensors.setdefault(key, value)
69
+ data.setdefault(key, value)
70
70
 
71
71
  device.update_info(info)
72
- device.update_sensors(sensors)
72
+ device.process_data(data)
73
73
  status = 200
74
74
  text = "200 OK"
75
75
  _LOGGER.debug("Request processed: %s", passkey)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aioccl
3
- Version: 2025.3.1
3
+ Version: 2025.4
4
4
  Summary: A Python library for CCL API server
5
5
  Home-page: https://github.com/CCL-Electronics-Ltd/aioccl
6
6
  Download-URL: https://github.com/CCL-Electronics-Ltd/aioccl
@@ -0,0 +1,9 @@
1
+ aioccl/__init__.py,sha256=XnegKtbvHvUTwVuuWNLb4LB9ZuGGar0xrZYOqk7scyg,133
2
+ aioccl/device.py,sha256=7UUEcg__1Q-gug8E5nuTAP_TWVeyoeuZSvNNUjIwJ1g,5691
3
+ aioccl/sensor.py,sha256=-yWdgBzOzLPHP2GBqvhVVGbIlt17y_3OSHibhB_DsQ8,16905
4
+ aioccl/server.py,sha256=RvWH6hqlQDq82u_8oO69SA0qeCDWGdVoi0wb5uYKQrs,3216
5
+ aioccl-2025.4.dist-info/licenses/LICENSE,sha256=PBRsTHchx7o0TQ2R2ktEAfFmn1iNHTxcOP_xaeuSAuo,11349
6
+ aioccl-2025.4.dist-info/METADATA,sha256=e5mkGmPL4RnVj1XCNqXRW8NOybwroWVyhlezyIe6yCY,989
7
+ aioccl-2025.4.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
8
+ aioccl-2025.4.dist-info/top_level.txt,sha256=-xIJfyfXTaW_EH7XCIHyxjSSSwjLmawa2qhsrHZH1vA,7
9
+ aioccl-2025.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.3)
2
+ Generator: setuptools (78.1.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- aioccl/__init__.py,sha256=XnegKtbvHvUTwVuuWNLb4LB9ZuGGar0xrZYOqk7scyg,133
2
- aioccl/device.py,sha256=TCp4QAP89ZHMNF3RqDMtCfTNRNqFGji_EiID3CtyJjs,6644
3
- aioccl/sensor.py,sha256=k89-wHjhYN2yv1bJYn8J26KqB8YHE7zlSTPpHW8CjDA,16910
4
- aioccl/server.py,sha256=ih1qHmXirQ5I79g7HTV7GaUgcakvK8WShA_N0IPIeQg,3227
5
- aioccl-2025.3.1.dist-info/licenses/LICENSE,sha256=PBRsTHchx7o0TQ2R2ktEAfFmn1iNHTxcOP_xaeuSAuo,11349
6
- aioccl-2025.3.1.dist-info/METADATA,sha256=37KTFEcKjUg8QGKK4uWUT0TfUVjOxHp9ywQw_mrmGeQ,991
7
- aioccl-2025.3.1.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
8
- aioccl-2025.3.1.dist-info/top_level.txt,sha256=-xIJfyfXTaW_EH7XCIHyxjSSSwjLmawa2qhsrHZH1vA,7
9
- aioccl-2025.3.1.dist-info/RECORD,,