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.
- qolsys_controller/adc_device.py +202 -0
- qolsys_controller/adc_service.py +139 -0
- qolsys_controller/adc_service_garagedoor.py +35 -0
- qolsys_controller/controller.py +245 -34
- qolsys_controller/database/db.py +60 -0
- qolsys_controller/database/table.py +1 -0
- qolsys_controller/database/table_alarmedsensor.py +2 -0
- qolsys_controller/database/table_history.py +2 -2
- qolsys_controller/database/table_smartsocket.py +12 -1
- qolsys_controller/database/table_thermostat.py +3 -0
- qolsys_controller/database/table_virtual_device.py +13 -1
- qolsys_controller/database/table_zwave_node.py +3 -0
- qolsys_controller/enum.py +5 -1
- qolsys_controller/enum_adc.py +28 -0
- qolsys_controller/enum_zwave.py +158 -29
- qolsys_controller/errors.py +5 -0
- qolsys_controller/mqtt_command.py +6 -0
- qolsys_controller/panel.py +109 -5
- qolsys_controller/partition.py +22 -2
- qolsys_controller/state.py +163 -1
- qolsys_controller/task_manager.py +4 -3
- qolsys_controller/zone.py +2 -1
- qolsys_controller/zwave_device.py +132 -4
- qolsys_controller/zwave_dimmer.py +3 -0
- qolsys_controller/zwave_energy_clamp.py +15 -0
- qolsys_controller/zwave_garagedoor.py +3 -0
- qolsys_controller/zwave_generic.py +3 -0
- qolsys_controller/zwave_lock.py +4 -0
- qolsys_controller/zwave_outlet.py +3 -0
- qolsys_controller/zwave_service_meter.py +192 -0
- qolsys_controller/zwave_service_multilevelsensor.py +119 -0
- qolsys_controller/zwave_thermometer.py +21 -0
- qolsys_controller/zwave_thermostat.py +150 -38
- {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/METADATA +1 -1
- {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/RECORD +37 -29
- {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/WHEEL +0 -0
- {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
|