qolsys-controller 0.0.2__py3-none-any.whl → 0.0.5__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.
- qolsys_controller/controller.py +6 -8
- qolsys_controller/database/db.py +62 -58
- qolsys_controller/database/table.py +24 -25
- qolsys_controller/database/table_alarmedsensor.py +15 -14
- qolsys_controller/database/table_automation.py +32 -28
- qolsys_controller/database/table_country_locale.py +23 -20
- qolsys_controller/database/table_dashboard_msgs.py +6 -5
- qolsys_controller/database/table_dimmerlight.py +22 -20
- qolsys_controller/database/table_doorlock.py +22 -20
- qolsys_controller/database/table_eu_event.py +5 -5
- qolsys_controller/database/table_heat_map.py +14 -13
- qolsys_controller/database/table_history.py +16 -15
- qolsys_controller/database/table_iqremotesettings.py +13 -12
- qolsys_controller/database/table_iqrouter_network_config.py +5 -5
- qolsys_controller/database/table_iqrouter_user_device.py +5 -5
- qolsys_controller/database/table_master_slave.py +28 -25
- qolsys_controller/database/table_partition.py +10 -10
- qolsys_controller/database/table_powerg_device.py +5 -5
- qolsys_controller/database/table_qolsyssettings.py +10 -10
- qolsys_controller/database/table_scene.py +20 -17
- qolsys_controller/database/table_sensor.py +56 -47
- qolsys_controller/database/table_smartsocket.py +5 -5
- qolsys_controller/database/table_state.py +12 -11
- qolsys_controller/database/table_tcc.py +6 -5
- qolsys_controller/database/table_thermostat.py +41 -34
- qolsys_controller/database/table_trouble_conditions.py +14 -13
- qolsys_controller/database/table_user.py +17 -16
- qolsys_controller/database/table_virtual_device.py +5 -5
- qolsys_controller/database/table_weather.py +16 -15
- qolsys_controller/database/table_zigbee_device.py +5 -5
- qolsys_controller/database/table_zwave_association_group.py +19 -17
- qolsys_controller/database/table_zwave_history.py +22 -20
- qolsys_controller/database/table_zwave_node.py +73 -68
- qolsys_controller/database/table_zwave_other.py +5 -5
- qolsys_controller/enum.py +44 -41
- qolsys_controller/errors.py +13 -13
- qolsys_controller/mdns.py +3 -3
- qolsys_controller/mqtt_command_queue.py +2 -3
- qolsys_controller/observable.py +3 -2
- qolsys_controller/panel.py +163 -161
- qolsys_controller/partition.py +46 -43
- qolsys_controller/pki.py +72 -65
- qolsys_controller/plugin.py +5 -4
- qolsys_controller/plugin_c4.py +8 -9
- qolsys_controller/plugin_remote.py +237 -228
- qolsys_controller/settings.py +104 -8
- qolsys_controller/state.py +68 -65
- qolsys_controller/task_manager.py +3 -3
- qolsys_controller/utils_mqtt.py +14 -11
- qolsys_controller/zone.py +69 -68
- qolsys_controller/zwave_device.py +46 -43
- qolsys_controller/zwave_dimmer.py +28 -26
- qolsys_controller/zwave_garagedoor.py +1 -0
- qolsys_controller/zwave_generic.py +2 -1
- qolsys_controller/zwave_lock.py +28 -30
- qolsys_controller/zwave_outlet.py +1 -0
- qolsys_controller/zwave_thermostat.py +58 -55
- {qolsys_controller-0.0.2.dist-info → qolsys_controller-0.0.5.dist-info}/METADATA +7 -3
- qolsys_controller-0.0.5.dist-info/RECORD +62 -0
- qolsys_controller-0.0.2.dist-info/RECORD +0 -62
- {qolsys_controller-0.0.2.dist-info → qolsys_controller-0.0.5.dist-info}/WHEEL +0 -0
- {qolsys_controller-0.0.2.dist-info → qolsys_controller-0.0.5.dist-info}/licenses/LICENSE +0 -0
qolsys_controller/partition.py
CHANGED
@@ -9,31 +9,33 @@ from .observable import QolsysObservable
|
|
9
9
|
|
10
10
|
LOGGER = logging.getLogger(__name__)
|
11
11
|
|
12
|
+
|
12
13
|
class QolsysPartition(QolsysObservable):
|
13
14
|
|
14
|
-
EXIT_SOUNDS_ARRAY = ["ON","OFF",""] # noqa: RUF012
|
15
|
-
ENTRY_DELAYS_ARRAY = ["ON","OFF",""] # noqa: RUF012
|
15
|
+
EXIT_SOUNDS_ARRAY = ["ON", "OFF", ""] # noqa: RUF012
|
16
|
+
ENTRY_DELAYS_ARRAY = ["ON", "OFF", ""] # noqa: RUF012
|
16
17
|
|
17
|
-
def __init__(self,partition_dict:dict,settings_dict:dict,alarm_state:PartitionAlarmState,
|
18
|
+
def __init__(self, partition_dict: dict, settings_dict: dict, alarm_state: PartitionAlarmState,
|
19
|
+
alarm_type_array: list[PartitionAlarmType]) -> None:
|
18
20
|
|
19
21
|
super().__init__()
|
20
22
|
|
21
23
|
# Partition info (partition table)
|
22
|
-
self._id:str = partition_dict.get("partition_id")
|
23
|
-
self._name:str = partition_dict.get("name")
|
24
|
+
self._id: str = partition_dict.get("partition_id")
|
25
|
+
self._name: str = partition_dict.get("name")
|
24
26
|
self._devices = partition_dict.get("devices")
|
25
27
|
|
26
28
|
# Partition Settings (qolsyssettings table)
|
27
|
-
self._system_status:PartitionSystemStatus = PartitionSystemStatus(settings_dict.get("SYSTEM_STATUS",""))
|
28
|
-
self._system_status_changed_time:str = settings_dict.get("SYSTEM_STATUS_CHANGED_TIME","")
|
29
|
-
self._exit_sounds:str = settings_dict.get("EXIT_SOUNDS","")
|
30
|
-
self._entry_delays:str = settings_dict.get("ENTRY_DELAYS","")
|
29
|
+
self._system_status: PartitionSystemStatus = PartitionSystemStatus(settings_dict.get("SYSTEM_STATUS", ""))
|
30
|
+
self._system_status_changed_time: str = settings_dict.get("SYSTEM_STATUS_CHANGED_TIME", "")
|
31
|
+
self._exit_sounds: str = settings_dict.get("EXIT_SOUNDS", "")
|
32
|
+
self._entry_delays: str = settings_dict.get("ENTRY_DELAYS", "")
|
31
33
|
|
32
34
|
# Alarm State (state table)
|
33
|
-
self._alarm_state:PartitionAlarmState = alarm_state
|
35
|
+
self._alarm_state: PartitionAlarmState = alarm_state
|
34
36
|
|
35
37
|
# Alarm Type (alarmedsensor table)
|
36
|
-
self._alarm_type_array:list[PartitionAlarmType] = alarm_type_array
|
38
|
+
self._alarm_type_array: list[PartitionAlarmType] = alarm_type_array
|
37
39
|
|
38
40
|
# Other
|
39
41
|
self._command_exit_sounds = True
|
@@ -80,31 +82,31 @@ class QolsysPartition(QolsysObservable):
|
|
80
82
|
return self._command_arm_stay_instant
|
81
83
|
|
82
84
|
@system_status.setter
|
83
|
-
def system_status(self, new_value:PartitionSystemStatus) -> None:
|
85
|
+
def system_status(self, new_value: PartitionSystemStatus) -> None:
|
84
86
|
if self._system_status != new_value:
|
85
|
-
LOGGER.debug("Partition%s (%s) - system_status: %s",self.id,self.name,new_value)
|
87
|
+
LOGGER.debug("Partition%s (%s) - system_status: %s", self.id, self.name, new_value)
|
86
88
|
self._system_status = new_value
|
87
89
|
self.notify()
|
88
90
|
|
89
91
|
@system_status_changed_time.setter
|
90
|
-
def system_status_changed_time(self,value:str) -> None:
|
92
|
+
def system_status_changed_time(self, value: str) -> None:
|
91
93
|
if self._system_status_changed_time != value:
|
92
|
-
LOGGER.debug("Partition%s (%s) - system_status_changed_time: %s",self._id,self._name,value)
|
94
|
+
LOGGER.debug("Partition%s (%s) - system_status_changed_time: %s", self._id, self._name, value)
|
93
95
|
self._system_status_changed_time = value
|
94
96
|
self.notify()
|
95
97
|
|
96
98
|
@alarm_state.setter
|
97
|
-
def alarm_state(self,new_value:PartitionAlarmState) -> None:
|
99
|
+
def alarm_state(self, new_value: PartitionAlarmState) -> None:
|
98
100
|
if self._alarm_state != new_value:
|
99
|
-
LOGGER.debug("Partition%s (%s) - alarm_state: %s",self.id,self.name,new_value)
|
101
|
+
LOGGER.debug("Partition%s (%s) - alarm_state: %s", self.id, self.name, new_value)
|
100
102
|
self._alarm_state = new_value
|
101
103
|
self.notify()
|
102
104
|
|
103
105
|
@alarm_type_array.setter
|
104
|
-
def alarm_type_array(self,new_alarm_type_array:list[PartitionAlarmType]) -> None:
|
106
|
+
def alarm_type_array(self, new_alarm_type_array: list[PartitionAlarmType]) -> None:
|
105
107
|
|
106
108
|
# If no changes are detected: return without notification
|
107
|
-
if sorted(new_alarm_type_array, key=lambda c: c.value) == sorted(self.alarm_type_array,key=lambda c: c.value):
|
109
|
+
if sorted(new_alarm_type_array, key=lambda c: c.value) == sorted(self.alarm_type_array, key=lambda c: c.value):
|
108
110
|
return
|
109
111
|
|
110
112
|
# alarm_type_array are different:
|
@@ -112,20 +114,20 @@ class QolsysPartition(QolsysObservable):
|
|
112
114
|
|
113
115
|
# If all alarm have been cleared
|
114
116
|
if new_alarm_type_array == []:
|
115
|
-
LOGGER.debug("Partition%s (%s) - alarm_type: %s",self._id,self._name,"None")
|
117
|
+
LOGGER.debug("Partition%s (%s) - alarm_type: %s", self._id, self._name, "None")
|
116
118
|
self.notify()
|
117
119
|
return
|
118
120
|
|
119
121
|
self.append_alarm_type(new_alarm_type_array)
|
120
122
|
|
121
123
|
@name.setter
|
122
|
-
def name(self,value:str) -> None:
|
123
|
-
|
124
|
-
LOGGER.debug("Partition%s (%s) - name: %s",self._id,self._name,value)
|
124
|
+
def name(self, value: str) -> None:
|
125
|
+
if self._name != value:
|
126
|
+
LOGGER.debug("Partition%s (%s) - name: %s", self._id, self._name, value)
|
125
127
|
self._name = value
|
126
128
|
self.notify()
|
127
129
|
|
128
|
-
def append_alarm_type(self,new_alarm_type_array:list[PartitionAlarmType]) -> None:
|
130
|
+
def append_alarm_type(self, new_alarm_type_array: list[PartitionAlarmType]) -> None:
|
129
131
|
|
130
132
|
data_changed = False
|
131
133
|
|
@@ -141,47 +143,48 @@ class QolsysPartition(QolsysObservable):
|
|
141
143
|
if data_changed:
|
142
144
|
self.notify()
|
143
145
|
for alarm in self._alarm_type_array:
|
144
|
-
LOGGER.debug("Partition%s (%s) - alarm_type: %s",self._id,self._name,alarm)
|
146
|
+
LOGGER.debug("Partition%s (%s) - alarm_type: %s", self._id, self._name, alarm)
|
145
147
|
|
146
148
|
@exit_sounds.setter
|
147
|
-
def exit_sounds(self,value:str) -> None:
|
149
|
+
def exit_sounds(self, value: str) -> None:
|
148
150
|
if value not in self.EXIT_SOUNDS_ARRAY:
|
149
|
-
LOGGER.debug("Partition%s (%s) - Unknow exit_sounds %s",self._id,self._name,value)
|
151
|
+
LOGGER.debug("Partition%s (%s) - Unknow exit_sounds %s", self._id, self._name, value)
|
150
152
|
return
|
151
153
|
|
152
154
|
if self._exit_sounds != value:
|
153
|
-
LOGGER.debug("Partition%s (%s) - exit_sound: %s",self._id,self._name,value)
|
155
|
+
LOGGER.debug("Partition%s (%s) - exit_sound: %s", self._id, self._name, value)
|
154
156
|
self._exit_sounds = value
|
155
157
|
self.notify()
|
156
158
|
|
157
159
|
@entry_delays.setter
|
158
|
-
def entry_delays(self,value:str) -> None:
|
160
|
+
def entry_delays(self, value: str) -> None:
|
159
161
|
if value not in self.ENTRY_DELAYS_ARRAY:
|
160
|
-
LOGGER.debug("Partition%s (%s) - Unknow entry_delays %s",self._id,self._name,value)
|
162
|
+
LOGGER.debug("Partition%s (%s) - Unknow entry_delays %s", self._id, self._name, value)
|
161
163
|
return
|
162
164
|
|
163
165
|
if self._entry_delays != value:
|
164
|
-
LOGGER.debug("Partition%s (%s) - entry_delays: %s",self._id,self._name,value)
|
166
|
+
LOGGER.debug("Partition%s (%s) - entry_delays: %s", self._id, self._name, value)
|
165
167
|
self._entry_delays = value
|
166
168
|
self.notify()
|
167
169
|
|
168
170
|
@command_exit_sounds.setter
|
169
|
-
def command_exit_sounds(self,value:str) -> None:
|
171
|
+
def command_exit_sounds(self, value: str) -> None:
|
170
172
|
self._command_exit_sounds = value
|
171
|
-
LOGGER.debug("Partition%s (%s) - command_exit_sounds: %s",self._id,self._name,value)
|
173
|
+
LOGGER.debug("Partition%s (%s) - command_exit_sounds: %s", self._id, self._name, value)
|
172
174
|
self.notify()
|
173
175
|
|
174
176
|
@command_arm_stay_instant.setter
|
175
|
-
def command_arm_stay_instant(self,value:str) -> None:
|
177
|
+
def command_arm_stay_instant(self, value: str) -> None:
|
176
178
|
self._command_arm_stay_instant = value
|
177
|
-
LOGGER.debug("Partition%s (%s) - arm_stay_instant: %s",self._id,self._name,value)
|
179
|
+
LOGGER.debug("Partition%s (%s) - arm_stay_instant: %s", self._id, self._name, value)
|
178
180
|
self.notify()
|
179
181
|
|
180
|
-
def update_partition(self,data:dict) -> None:
|
182
|
+
def update_partition(self, data: dict) -> None:
|
181
183
|
# Check if we are updating same partition_id
|
182
|
-
partition_id_update = data.get("partition_id","")
|
184
|
+
partition_id_update = data.get("partition_id", "")
|
183
185
|
if int(partition_id_update) != int(self.id):
|
184
|
-
LOGGER.error(
|
186
|
+
LOGGER.error(
|
187
|
+
"Updating Partition%s (%s) with Partition '%s' (different id)", self._id, self._name, partition_id_update)
|
185
188
|
return
|
186
189
|
|
187
190
|
self.start_batch_update()
|
@@ -196,7 +199,7 @@ class QolsysPartition(QolsysObservable):
|
|
196
199
|
|
197
200
|
self.end_batch_update()
|
198
201
|
|
199
|
-
def update_settings(self,data:dict) -> None:
|
202
|
+
def update_settings(self, data: dict) -> None:
|
200
203
|
|
201
204
|
self.start_batch_update()
|
202
205
|
|
@@ -227,8 +230,8 @@ class QolsysPartition(QolsysObservable):
|
|
227
230
|
|
228
231
|
def to_dict_settings(self) -> dict:
|
229
232
|
return {
|
230
|
-
"SYSTEM_STATUS":self.system_status.value,
|
231
|
-
"SYSTEM_STATUS_CHANGED_TIME"
|
232
|
-
"EXIT_SOUNDS":self.exit_sounds,
|
233
|
-
"ENTRY_DELAYS":self.entry_delays,
|
233
|
+
"SYSTEM_STATUS": self.system_status.value,
|
234
|
+
"SYSTEM_STATUS_CHANGED_TIME": self.system_status_changed_time,
|
235
|
+
"EXIT_SOUNDS": self.exit_sounds,
|
236
|
+
"ENTRY_DELAYS": self.entry_delays,
|
234
237
|
}
|
qolsys_controller/pki.py
CHANGED
@@ -2,6 +2,7 @@ import logging
|
|
2
2
|
import os
|
3
3
|
import re
|
4
4
|
from datetime import datetime, timedelta
|
5
|
+
from pathlib import Path
|
5
6
|
|
6
7
|
from cryptography import x509
|
7
8
|
from cryptography.hazmat.primitives import hashes, serialization
|
@@ -9,13 +10,15 @@ from cryptography.hazmat.primitives.asymmetric import rsa
|
|
9
10
|
from cryptography.x509 import load_pem_x509_csr
|
10
11
|
from cryptography.x509.oid import NameOID
|
11
12
|
|
13
|
+
from .settings import QolsysSettings
|
14
|
+
|
12
15
|
LOGGER = logging.getLogger(__name__)
|
13
16
|
|
17
|
+
|
14
18
|
class QolsysPKI:
|
15
|
-
def __init__(self,
|
19
|
+
def __init__(self, settings: QolsysSettings) -> None:
|
16
20
|
self._id = ""
|
17
|
-
self.
|
18
|
-
self._subkeys_directory = ""
|
21
|
+
self._subkeys_directory: Path = Path
|
19
22
|
|
20
23
|
self._key = None
|
21
24
|
self._cer = None
|
@@ -23,6 +26,8 @@ class QolsysPKI:
|
|
23
26
|
self._secure = None
|
24
27
|
self._qolsys = None
|
25
28
|
|
29
|
+
self._settings = settings
|
30
|
+
|
26
31
|
@property
|
27
32
|
def id(self) -> str:
|
28
33
|
return self._id
|
@@ -30,173 +35,176 @@ class QolsysPKI:
|
|
30
35
|
def formatted_id(self) -> str:
|
31
36
|
return ":".join(self.id[i:i+2] for i in range(0, len(self.id), 2))
|
32
37
|
|
33
|
-
def set_id(self,pki_id:str) -> None:
|
34
|
-
self._id = pki_id.replace(":","").upper()
|
35
|
-
LOGGER.debug("Using PKI: %s",self.formatted_id())
|
36
|
-
self._subkeys_directory = self.
|
38
|
+
def set_id(self, pki_id: str) -> None:
|
39
|
+
self._id = pki_id.replace(":", "").upper()
|
40
|
+
LOGGER.debug("Using PKI: %s", self.formatted_id())
|
41
|
+
self._subkeys_directory = self._settings.pki_directory.joinpath(Path(self.id))
|
37
42
|
|
38
43
|
@property
|
39
|
-
def key(self):
|
44
|
+
def key(self) -> str:
|
40
45
|
return self._key
|
41
46
|
|
42
47
|
@property
|
43
|
-
def cer(self):
|
48
|
+
def cer(self) -> str:
|
44
49
|
return self._cer
|
45
50
|
|
46
51
|
@property
|
47
|
-
def csr(self):
|
52
|
+
def csr(self) -> str:
|
48
53
|
return self._csr
|
49
54
|
|
50
55
|
@property
|
51
|
-
def secure(self):
|
56
|
+
def secure(self) -> str:
|
52
57
|
return self._secure
|
53
58
|
|
54
59
|
@property
|
55
|
-
def qolsys(self):
|
60
|
+
def qolsys(self) -> str:
|
56
61
|
return self._qolsys
|
57
62
|
|
58
63
|
def auto_discover_pki(self) -> bool:
|
59
64
|
pattern = r"^[A-Fa-f0-9]{12}$"
|
60
65
|
|
61
66
|
LOGGER.debug("Auto Discovery Enabled")
|
62
|
-
with os.scandir(self.
|
67
|
+
with os.scandir(self._settings.pki_directory) as entries:
|
63
68
|
for entry in entries:
|
64
|
-
if entry.is_dir():
|
65
|
-
|
66
|
-
|
67
|
-
return True
|
69
|
+
if entry.is_dir() and re.fullmatch(pattern, entry.name):
|
70
|
+
self.set_id(entry.name)
|
71
|
+
return True
|
68
72
|
|
69
73
|
return False
|
70
74
|
|
71
|
-
def load_private_key(self,key:str) -> bool:
|
75
|
+
def load_private_key(self, key: str) -> bool:
|
72
76
|
try:
|
73
|
-
self._key = serialization.load_pem_private_key(key.encode(),password=None)
|
74
|
-
return True
|
77
|
+
self._key = serialization.load_pem_private_key(key.encode(), password=None)
|
75
78
|
except ValueError:
|
76
79
|
LOGGER.debug("Private Key Value Error")
|
77
80
|
return False
|
78
81
|
|
79
|
-
|
82
|
+
return True
|
83
|
+
|
84
|
+
def load_certificate(self, cer: str) -> bool:
|
80
85
|
try:
|
81
|
-
self._cer = x509.load_pem_x509_certificate(cer.encode(),None)
|
82
|
-
return True
|
86
|
+
self._cer = x509.load_pem_x509_certificate(cer.encode(), None)
|
83
87
|
except ValueError:
|
84
88
|
LOGGER.debug("Certificate Value Error")
|
85
89
|
return False
|
86
90
|
|
87
|
-
|
91
|
+
return True
|
92
|
+
|
93
|
+
def load_certificate_signing_request(self, csr: str) -> bool:
|
88
94
|
try:
|
89
95
|
self._csr = load_pem_x509_csr(csr.encode())
|
90
|
-
return True
|
91
96
|
except ValueError:
|
92
97
|
LOGGER.debug("Certificate Signing Request Value Error")
|
93
98
|
return False
|
94
99
|
|
95
|
-
|
100
|
+
return True
|
101
|
+
|
102
|
+
def load_qolsys_certificate(self, qolsys: str) -> bool:
|
96
103
|
try:
|
97
|
-
self._qolsys = x509.load_pem_x509_certificate(qolsys.encode(),None)
|
98
|
-
return True
|
104
|
+
self._qolsys = x509.load_pem_x509_certificate(qolsys.encode(), None)
|
99
105
|
except ValueError:
|
100
106
|
LOGGER.debug("Qolsys Certificate Value Error")
|
101
107
|
return False
|
102
108
|
|
103
|
-
|
109
|
+
return True
|
110
|
+
|
111
|
+
def load_signed_client_certificate(self, secure: str) -> bool:
|
104
112
|
try:
|
105
|
-
self._secure = x509.load_pem_x509_certificate(secure.encode(),None)
|
106
|
-
return True
|
113
|
+
self._secure = x509.load_pem_x509_certificate(secure.encode(), None)
|
107
114
|
except ValueError:
|
108
115
|
LOGGER.debug("Client Signed Certificate Value Error")
|
109
116
|
return False
|
110
117
|
|
111
|
-
|
112
|
-
|
118
|
+
return True
|
119
|
+
|
120
|
+
def check_key_file(self) -> bool:
|
121
|
+
if self._subkeys_directory.joinpath(self.id + ".key").resolve().exists():
|
113
122
|
LOGGER.debug("Found KEY")
|
114
123
|
return True
|
115
124
|
LOGGER.debug("No KEY File")
|
116
125
|
return False
|
117
126
|
|
118
|
-
def check_cer_file(self)->bool:
|
119
|
-
if
|
127
|
+
def check_cer_file(self) -> bool:
|
128
|
+
if self._subkeys_directory.joinpath(self.id + ".cer").resolve().exists():
|
120
129
|
LOGGER.debug("Found CER")
|
121
130
|
return True
|
122
131
|
LOGGER.debug("No CER File")
|
123
132
|
return False
|
124
133
|
|
125
|
-
def check_csr_file(self)->bool:
|
126
|
-
if
|
134
|
+
def check_csr_file(self) -> bool:
|
135
|
+
if self._subkeys_directory.joinpath(self.id + ".csr").resolve().exists():
|
127
136
|
LOGGER.debug("Found CSR")
|
128
137
|
return True
|
129
138
|
LOGGER.debug("No CSR File")
|
130
139
|
return False
|
131
140
|
|
132
|
-
def check_secure_file(self)->bool:
|
133
|
-
if
|
141
|
+
def check_secure_file(self) -> bool:
|
142
|
+
if self._subkeys_directory.joinpath(self.id + ".secure").resolve().exists():
|
134
143
|
LOGGER.debug("Found Signed Client Certificate")
|
135
144
|
return True
|
136
145
|
LOGGER.debug("No Signed Client Certificate File")
|
137
146
|
return False
|
138
147
|
|
139
|
-
def check_qolsys_cer_file(self)->bool:
|
140
|
-
if
|
148
|
+
def check_qolsys_cer_file(self) -> bool:
|
149
|
+
if self._subkeys_directory.joinpath(self.id + ".qolsys").resolve().exists():
|
141
150
|
LOGGER.debug("Found Qolsys Certificate")
|
142
151
|
return True
|
143
|
-
|
144
152
|
LOGGER.debug("No Qolsys Certificate File")
|
145
153
|
return False
|
146
154
|
|
147
155
|
@property
|
148
|
-
def key_file_path(self) ->
|
149
|
-
return self._subkeys_directory
|
156
|
+
def key_file_path(self) -> Path:
|
157
|
+
return self._subkeys_directory.joinpath(self.id + ".key")
|
150
158
|
|
151
159
|
@property
|
152
160
|
def csr_file_path(self) -> str:
|
153
|
-
return self._subkeys_directory
|
161
|
+
return self._subkeys_directory.joinpath(self.id + ".csr")
|
154
162
|
|
155
163
|
@property
|
156
164
|
def cer_file_path(self) -> str:
|
157
|
-
return self._subkeys_directory
|
165
|
+
return self._subkeys_directory.joinpath(self.id + ".cer")
|
158
166
|
|
159
167
|
@property
|
160
168
|
def secure_file_path(self) -> str:
|
161
|
-
return self._subkeys_directory
|
169
|
+
return self._subkeys_directory.joinpath(self.id + ".secure")
|
162
170
|
|
163
171
|
@property
|
164
172
|
def qolsys_cer_file_path(self) -> str:
|
165
|
-
return self._subkeys_directory
|
173
|
+
return self._subkeys_directory.joinpath(self.id + ".qolsys")
|
166
174
|
|
167
|
-
def create(self,mac:str,key_size:int)->bool:
|
175
|
+
def create(self, mac: str, key_size: int) -> bool:
|
168
176
|
|
169
177
|
self.set_id(mac)
|
170
178
|
|
171
179
|
# Check if directory exist
|
172
|
-
if
|
180
|
+
if self._subkeys_directory.resolve().exists():
|
173
181
|
LOGGER.error("Create Directory Colision")
|
174
182
|
return False
|
175
183
|
|
176
184
|
# Check for private key colision
|
177
|
-
if
|
185
|
+
if self._subkeys_directory.joinpath(self.id + ".key").resolve().exists():
|
178
186
|
LOGGER.error("Create KEY File Colision")
|
179
187
|
return False
|
180
188
|
|
181
189
|
# Check for CER file colision
|
182
|
-
if
|
190
|
+
if self._subkeys_directory.joinpath(self.id + ".cer").resolve().exists():
|
183
191
|
LOGGER.error("Create CER File Colision")
|
184
192
|
return False
|
185
193
|
|
186
194
|
# Check for CSR file colision
|
187
|
-
if
|
195
|
+
if self._subkeys_directory.joinpath(self.id + ".csr").resolve().exists():
|
188
196
|
LOGGER.error("Create CSR File Colision")
|
189
197
|
return False
|
190
198
|
|
191
199
|
# Check for CER file colision
|
192
|
-
if
|
200
|
+
if self._subkeys_directory.joinpath(self.id + ".secure").resolve().exists():
|
193
201
|
LOGGER.error("Create Signed Certificate File Colision")
|
194
202
|
return False
|
195
203
|
|
196
|
-
LOGGER.debug("Creating PKI: %s",
|
204
|
+
LOGGER.debug("Creating PKI: %s", self.formatted_id())
|
197
205
|
|
198
206
|
LOGGER.debug("Creating PKI Directory")
|
199
|
-
|
207
|
+
self._subkeys_directory.resolve().mkdir(parents=True)
|
200
208
|
|
201
209
|
LOGGER.debug("Creating KEY")
|
202
210
|
private_key = rsa.generate_private_key(public_exponent=65537,
|
@@ -204,8 +212,8 @@ class QolsysPKI:
|
|
204
212
|
private_pem = private_key.private_bytes(encoding=serialization.Encoding.PEM,
|
205
213
|
format=serialization.PrivateFormat.PKCS8,
|
206
214
|
encryption_algorithm=serialization.NoEncryption())
|
207
|
-
with
|
208
|
-
|
215
|
+
with self._subkeys_directory.joinpath(self.id + ".key").open("wb") as file:
|
216
|
+
file.write(private_pem)
|
209
217
|
|
210
218
|
LOGGER.debug("Creating CER")
|
211
219
|
subject = issuer = x509.Name([
|
@@ -214,7 +222,7 @@ class QolsysPKI:
|
|
214
222
|
x509.NameAttribute(NameOID.LOCALITY_NAME, ""),
|
215
223
|
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Qolsys Inc."),
|
216
224
|
x509.NameAttribute(NameOID.COMMON_NAME, "www.qolsys.com "),
|
217
|
-
]
|
225
|
+
])
|
218
226
|
cert = x509.CertificateBuilder().subject_name(
|
219
227
|
subject,
|
220
228
|
).issuer_name(
|
@@ -232,20 +240,19 @@ class QolsysPKI:
|
|
232
240
|
).sign(private_key, hashes.SHA256())
|
233
241
|
cert_pem = cert.public_bytes(encoding=serialization.Encoding.PEM)
|
234
242
|
|
235
|
-
with
|
236
|
-
|
243
|
+
with self._subkeys_directory.joinpath(self.id + ".cer").open("wb") as file:
|
244
|
+
file.write(cert_pem)
|
237
245
|
|
238
246
|
LOGGER.debug("Creating CSR")
|
239
247
|
csr = x509.CertificateSigningRequestBuilder().subject_name(
|
240
|
-
subject
|
248
|
+
subject,
|
241
249
|
).add_extension(
|
242
250
|
x509.BasicConstraints(ca=False, path_length=None), critical=True,
|
243
251
|
).sign(private_key, hashes.SHA256())
|
244
252
|
|
245
253
|
# Save CSR to file
|
246
254
|
csr_pem = csr.public_bytes(encoding=serialization.Encoding.PEM)
|
247
|
-
with
|
248
|
-
|
255
|
+
with self._subkeys_directory.joinpath(self.id + ".csr").open("wb") as file:
|
256
|
+
file.write(csr_pem)
|
249
257
|
|
250
258
|
return True
|
251
|
-
|
qolsys_controller/plugin.py
CHANGED
@@ -7,12 +7,13 @@ from .state import QolsysState
|
|
7
7
|
|
8
8
|
LOGGER = logging.getLogger(__name__)
|
9
9
|
|
10
|
+
|
10
11
|
class QolsysPlugin:
|
11
|
-
def __init__(self,state:QolsysState,panel:QolsysPanel,settings:QolsysSettings) -> None:
|
12
|
+
def __init__(self, state: QolsysState, panel: QolsysPanel, settings: QolsysSettings) -> None:
|
12
13
|
|
13
|
-
self._state = state
|
14
|
-
self._panel = panel
|
15
|
-
self._settings = settings
|
14
|
+
self._state: QolsysState = state
|
15
|
+
self._panel: QolsysPanel = panel
|
16
|
+
self._settings: QolsysSettings = settings
|
16
17
|
|
17
18
|
self.connected = False
|
18
19
|
self.connected_observer = QolsysObservable()
|
qolsys_controller/plugin_c4.py
CHANGED
@@ -4,15 +4,14 @@ from .plugin import QolsysPlugin
|
|
4
4
|
|
5
5
|
LOGGER = logging.getLogger(__name__)
|
6
6
|
|
7
|
-
class QolsysPluginC4(QolsysPlugin):
|
8
|
-
def __init__(self) -> None:
|
9
|
-
|
10
|
-
# C4 Integration
|
11
|
-
self._token = ""
|
12
7
|
|
13
|
-
|
14
|
-
|
15
|
-
super().config()
|
16
|
-
return True
|
8
|
+
class QolsysPluginC4(QolsysPlugin):
|
9
|
+
def __init__(self) -> None:
|
17
10
|
|
11
|
+
# C4 Integration
|
12
|
+
self._token = ""
|
18
13
|
|
14
|
+
def config(self, panel_ip: str, token: str) -> bool: # noqa: ARG002
|
15
|
+
LOGGER.warning("C4Plugin: Configuring Plugin")
|
16
|
+
super().config()
|
17
|
+
return True
|