qolsys-controller 0.0.62__py3-none-any.whl → 0.0.87__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.

Potentially problematic release.


This version of qolsys-controller might be problematic. Click here for more details.

Files changed (37) hide show
  1. qolsys_controller/adc_device.py +202 -0
  2. qolsys_controller/adc_service.py +139 -0
  3. qolsys_controller/adc_service_garagedoor.py +35 -0
  4. qolsys_controller/controller.py +245 -34
  5. qolsys_controller/database/db.py +60 -0
  6. qolsys_controller/database/table.py +1 -0
  7. qolsys_controller/database/table_alarmedsensor.py +2 -0
  8. qolsys_controller/database/table_history.py +2 -2
  9. qolsys_controller/database/table_smartsocket.py +12 -1
  10. qolsys_controller/database/table_thermostat.py +3 -0
  11. qolsys_controller/database/table_virtual_device.py +13 -1
  12. qolsys_controller/database/table_zwave_node.py +3 -0
  13. qolsys_controller/enum.py +5 -1
  14. qolsys_controller/enum_adc.py +28 -0
  15. qolsys_controller/enum_zwave.py +158 -29
  16. qolsys_controller/errors.py +5 -0
  17. qolsys_controller/mqtt_command.py +6 -0
  18. qolsys_controller/panel.py +109 -5
  19. qolsys_controller/partition.py +22 -2
  20. qolsys_controller/state.py +163 -1
  21. qolsys_controller/task_manager.py +4 -3
  22. qolsys_controller/zone.py +2 -1
  23. qolsys_controller/zwave_device.py +132 -4
  24. qolsys_controller/zwave_dimmer.py +3 -0
  25. qolsys_controller/zwave_energy_clamp.py +15 -0
  26. qolsys_controller/zwave_garagedoor.py +3 -0
  27. qolsys_controller/zwave_generic.py +3 -0
  28. qolsys_controller/zwave_lock.py +4 -0
  29. qolsys_controller/zwave_outlet.py +3 -0
  30. qolsys_controller/zwave_service_meter.py +192 -0
  31. qolsys_controller/zwave_service_multilevelsensor.py +119 -0
  32. qolsys_controller/zwave_thermometer.py +21 -0
  33. qolsys_controller/zwave_thermostat.py +150 -38
  34. {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/METADATA +1 -1
  35. {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/RECORD +37 -29
  36. {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/WHEEL +0 -0
  37. {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,202 @@
1
+ import json
2
+ import logging
3
+ from typing import TYPE_CHECKING
4
+
5
+ from .adc_service import QolsysAdcService
6
+ from .adc_service_garagedoor import QolsysAdcGarageDoorService
7
+ from .enum_adc import vdFuncLocalControl, vdFuncName, vdFuncState, vdFuncType
8
+ from .observable import QolsysObservable
9
+
10
+ if TYPE_CHECKING:
11
+ from .adc_service import QolsysAdcService
12
+
13
+ LOGGER = logging.getLogger(__name__)
14
+
15
+
16
+ class QolsysAdcDevice(QolsysObservable):
17
+ def __init__(self, adc_dict: dict[str, str]) -> None:
18
+ super().__init__()
19
+
20
+ self._services: list[QolsysAdcService] = []
21
+
22
+ self._id: str = adc_dict.get("_id", "")
23
+ self._partition_id: str = adc_dict.get("partition_id", "")
24
+ self._device_id: str = adc_dict.get("device_id", "")
25
+ self._name: str = adc_dict.get("name", "")
26
+ self._type: str = adc_dict.get("type", "")
27
+ self._create_time: str = adc_dict.get("create_time", "")
28
+ self._created_by: str = adc_dict.get("created_by", "")
29
+ self._update_time: str = adc_dict.get("update_time", "")
30
+ self._updated_by: str = adc_dict.get("updated_by", "")
31
+ self._device_zone_list: str = adc_dict.get("device_zone_list", "")
32
+ self._func_list = ""
33
+ self.func_list = adc_dict.get("func_list", "")
34
+
35
+ def update_adc_device(self, data: dict[str, str]) -> None:
36
+ # Check if we are updating same device_id
37
+ device_id_update = data.get("device_id", "")
38
+ if device_id_update != self._device_id:
39
+ LOGGER.error(
40
+ "Updating ADC%s (%s) with ADC%s (different device_id)",
41
+ self._device_id,
42
+ self._name,
43
+ device_id_update,
44
+ )
45
+ return
46
+
47
+ self.start_batch_update()
48
+
49
+ if "partition_id" in data:
50
+ self.partition_id = data.get("partition_id", "")
51
+
52
+ if "name" in data:
53
+ self.name = data.get("name", "")
54
+
55
+ if "type" in data:
56
+ self.type = data.get("type", "")
57
+
58
+ self.end_batch_update()
59
+
60
+ if "func_list" in data:
61
+ self.func_list = data.get("func_list", "")
62
+
63
+ def get_adc_service(self, id: int) -> QolsysAdcService | None:
64
+ for service in self._services:
65
+ if service.id == id:
66
+ return service
67
+ return None
68
+
69
+ def add_adc_service(
70
+ self,
71
+ id: int,
72
+ local_control: vdFuncLocalControl,
73
+ func_name: vdFuncName,
74
+ func_type: vdFuncType,
75
+ func_state: vdFuncState,
76
+ timestamp: str,
77
+ ) -> None:
78
+ # Garage Door
79
+ if func_name == vdFuncName.OPEN_CLOSE and func_type == vdFuncType.BINARY_ACTUATOR:
80
+ LOGGER.debug("ADC%s (%s) - Adding garage door service", self.device_id, self.name)
81
+ self._services.append(
82
+ QolsysAdcGarageDoorService(self, id, func_name, local_control, func_type, func_state, timestamp)
83
+ )
84
+ self.notify()
85
+ return
86
+
87
+ # Add generic service if other services have beed identified
88
+ LOGGER.debug("ADC%s (%s) - Adding generic service", self.device_id, self.name)
89
+ self._services.append(QolsysAdcService(self, id, func_name, local_control, func_type, func_state, timestamp))
90
+ self.notify()
91
+ return
92
+
93
+ # -----------------------------
94
+ # properties + setters
95
+ # -----------------------------
96
+
97
+ @property
98
+ def device_id(self) -> str:
99
+ return self._device_id
100
+
101
+ @device_id.setter
102
+ def device_id(self, value: str) -> None:
103
+ self._device_id = value
104
+
105
+ @property
106
+ def services(self) -> list[QolsysAdcService]:
107
+ return self._services
108
+
109
+ @property
110
+ def partition_id(self) -> str:
111
+ return self._partition_id
112
+
113
+ @partition_id.setter
114
+ def partition_id(self, value: str) -> None:
115
+ if self._partition_id != value:
116
+ LOGGER.debug("ADC%s (%s) - partition_id: %s", self.device_id, self.name, value)
117
+ self._partition_id = value
118
+ self.notify()
119
+
120
+ @property
121
+ def name(self) -> str:
122
+ return self._name
123
+
124
+ @name.setter
125
+ def name(self, value: str) -> None:
126
+ if self._name != value:
127
+ LOGGER.debug("ADC%s (%s) - name: %s", self.device_id, self.name, value)
128
+ self._name = value
129
+ self.notify()
130
+
131
+ @property
132
+ def type(self) -> str:
133
+ return self._type
134
+
135
+ @type.setter
136
+ def type(self, value: str) -> None:
137
+ if self._type != value:
138
+ LOGGER.debug("ADC%s (%s) - type: %s", self.device_id, self.name, value)
139
+ self._type = value
140
+ self.notify()
141
+
142
+ @property
143
+ def func_list(self) -> str:
144
+ return self._func_list
145
+
146
+ @func_list.setter
147
+ def func_list(self, value: str) -> None:
148
+ if self._func_list != value:
149
+ LOGGER.debug("ADC%s (%s) - func_list: %s", self.device_id, self.name, value)
150
+ self._func_list = value
151
+
152
+ try:
153
+ json_func_list = json.loads(self._func_list)
154
+ new_service_id: list[int] = []
155
+ self.start_batch_update()
156
+
157
+ for function in json_func_list:
158
+ try:
159
+ id = function.get("vdFuncId")
160
+ local_control = vdFuncLocalControl(function.get("vdFuncLocalControl"))
161
+ func_name = vdFuncName(function.get("vdFuncName"))
162
+ func_type = vdFuncType(function.get("vdFuncType"))
163
+ func_state = vdFuncState(function.get("vdFuncState"))
164
+ timestamp = function.get("vdFuncBackendTimestamp")
165
+ new_service_id.append(id)
166
+
167
+ service = self.get_adc_service(id)
168
+ if service is not None:
169
+ service.update_adc_service(func_name, local_control, func_type, func_state, timestamp)
170
+
171
+ if service is None:
172
+ self.add_adc_service(id, local_control, func_name, func_type, func_state, timestamp)
173
+
174
+ except ValueError as e:
175
+ LOGGER.error("Error converting value:", e)
176
+ continue
177
+
178
+ # Check if service have been removed
179
+ for service in self._services:
180
+ if service.id not in new_service_id:
181
+ self._services.remove(service)
182
+ self.notify()
183
+
184
+ self.end_batch_update()
185
+
186
+ except json.JSONDecodeError as e:
187
+ LOGGER.error("ADC%s - Error parsing JSON:", self.device_id, e)
188
+
189
+ def to_dict_adc(self) -> dict[str, str]:
190
+ return {
191
+ "_id": self._id,
192
+ "partition_id": self.partition_id,
193
+ "device_id": self.device_id,
194
+ "name": self.name,
195
+ "type": self.type,
196
+ "func_list": self.func_list,
197
+ "create_time": self._create_time,
198
+ "created_by": self._created_by,
199
+ "update_time": self._update_time,
200
+ "updated_by": self._updated_by,
201
+ "device_zone_list": self._device_zone_list,
202
+ }
@@ -0,0 +1,139 @@
1
+ import logging
2
+ from typing import TYPE_CHECKING
3
+
4
+ from .enum_adc import vdFuncLocalControl, vdFuncName, vdFuncState, vdFuncType
5
+
6
+ if TYPE_CHECKING:
7
+ from .adc_device import QolsysAdcDevice
8
+
9
+ LOGGER = logging.getLogger(__name__)
10
+
11
+
12
+ class QolsysAdcService:
13
+ def __init__(
14
+ self,
15
+ parent_device: "QolsysAdcDevice",
16
+ id: int,
17
+ func_name: vdFuncName,
18
+ local_control: vdFuncLocalControl,
19
+ func_type: vdFuncType,
20
+ func_state: vdFuncState,
21
+ timestamp: str,
22
+ ) -> None:
23
+ super().__init__()
24
+ self._parent_device: QolsysAdcDevice = parent_device
25
+ self._id: int = id
26
+ self._func_name: vdFuncName = func_name
27
+ self._local_control: vdFuncLocalControl = local_control
28
+ self._func_type: vdFuncType = func_type
29
+ self._func_state: vdFuncState = func_state
30
+ self._timestamp: str = timestamp
31
+
32
+ def update_adc_service(
33
+ self,
34
+ func_name: vdFuncName,
35
+ local_control: vdFuncLocalControl,
36
+ func_type: vdFuncType,
37
+ func_state: vdFuncState,
38
+ timestamp: str,
39
+ ) -> None:
40
+ self.name = func_name
41
+ self.local_control = local_control
42
+ self.func_type = func_type
43
+ self.func_state = func_state
44
+ self.timestamp = timestamp
45
+
46
+ # -----------------------------
47
+ # properties + setters
48
+ # -----------------------------
49
+
50
+ @property
51
+ def id(self) -> int:
52
+ return self._id
53
+
54
+ @property
55
+ def func_name(self) -> vdFuncName:
56
+ return self._func_name
57
+
58
+ @func_name.setter
59
+ def func_name(self, value: vdFuncName) -> None:
60
+ if value != self._func_name:
61
+ self._func_name = value
62
+ LOGGER.debug(
63
+ "ADC%s (%s) - Func%s - func_name:%s",
64
+ self._parent_device.device_id,
65
+ self._parent_device.name,
66
+ self.id,
67
+ self.func_name,
68
+ )
69
+ LOGGER.debug("Warning - Changing func_name will change device type - Not supported")
70
+ self._parent_device.notify()
71
+
72
+ @property
73
+ def local_control(self) -> vdFuncLocalControl:
74
+ return self._local_control
75
+
76
+ @local_control.setter
77
+ def local_control(self, value: vdFuncLocalControl) -> None:
78
+ if value != self.local_control:
79
+ self._local_control = value
80
+ LOGGER.debug(
81
+ "ADC%s (%s) - Func%s - local_control:%s",
82
+ self._parent_device.device_id,
83
+ self._parent_device.name,
84
+ self.id,
85
+ self.local_control,
86
+ )
87
+ self._parent_device.notify()
88
+
89
+ @property
90
+ def func_type(self) -> vdFuncType:
91
+ return self._func_type
92
+
93
+ @func_type.setter
94
+ def func_type(self, value: vdFuncType) -> None:
95
+ if value != self._func_type:
96
+ self._func_type = value
97
+ LOGGER.debug(
98
+ "ADC%s (%s) - Func%s - func_type:%s",
99
+ self._parent_device.device_id,
100
+ self._parent_device.name,
101
+ self.id,
102
+ self.func_type,
103
+ )
104
+ LOGGER.debug("Warning - Changing func_type will change device type - Not supported")
105
+ self._parent_device.notify()
106
+
107
+ @property
108
+ def func_state(self) -> vdFuncState:
109
+ return self._func_state
110
+
111
+ @func_state.setter
112
+ def func_state(self, value: vdFuncState) -> None:
113
+ if value != self._func_state:
114
+ self._func_state = value
115
+ LOGGER.debug(
116
+ "ADC%s (%s) - Func%s - func_state:%s",
117
+ self._parent_device.device_id,
118
+ self._parent_device.name,
119
+ self.id,
120
+ self.func_state,
121
+ )
122
+ self._parent_device.notify()
123
+
124
+ @property
125
+ def timestamp(self) -> str:
126
+ return self._timestamp
127
+
128
+ @timestamp.setter
129
+ def timestamp(self, value: str) -> None:
130
+ if value != self._timestamp:
131
+ self._timestamp = value
132
+ LOGGER.debug(
133
+ "ADC%s (%s) - Func%s - timestamp:%s",
134
+ self._parent_device.device_id,
135
+ self._parent_device.name,
136
+ self.id,
137
+ self.timestamp,
138
+ )
139
+ self._parent_device.notify()
@@ -0,0 +1,35 @@
1
+ import logging
2
+ from typing import TYPE_CHECKING
3
+
4
+ from .adc_service import QolsysAdcService
5
+ from .enum_adc import vdFuncLocalControl, vdFuncName, vdFuncState, vdFuncType
6
+
7
+ if TYPE_CHECKING:
8
+ from .adc_device import QolsysAdcDevice
9
+
10
+ LOGGER = logging.getLogger(__name__)
11
+
12
+
13
+ class QolsysAdcGarageDoorService(QolsysAdcService):
14
+ def __init__(
15
+ self,
16
+ parent_device: "QolsysAdcDevice",
17
+ id: int,
18
+ func_name: vdFuncName,
19
+ local_control: vdFuncLocalControl,
20
+ func_type: vdFuncType,
21
+ func_state: vdFuncState,
22
+ timestamp: str,
23
+ ) -> None:
24
+ super().__init__(
25
+ parent_device,
26
+ id,
27
+ func_name,
28
+ local_control,
29
+ func_type,
30
+ func_state,
31
+ timestamp,
32
+ )
33
+
34
+ def is_open(self) -> bool:
35
+ return self.func_state == vdFuncState.ON