qolsys-controller 0.0.44__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 (81) 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 +1040 -20
  5. qolsys_controller/database/db.py +108 -29
  6. qolsys_controller/database/table.py +90 -60
  7. qolsys_controller/database/table_alarmedsensor.py +2 -2
  8. qolsys_controller/database/table_automation.py +0 -1
  9. qolsys_controller/database/table_country_locale.py +0 -1
  10. qolsys_controller/database/table_dashboard_msgs.py +1 -2
  11. qolsys_controller/database/table_dimmerlight.py +0 -1
  12. qolsys_controller/database/table_doorlock.py +0 -1
  13. qolsys_controller/database/table_eu_event.py +1 -2
  14. qolsys_controller/database/table_heat_map.py +0 -2
  15. qolsys_controller/database/table_history.py +4 -1
  16. qolsys_controller/database/table_iqremotesettings.py +0 -2
  17. qolsys_controller/database/table_iqrouter_network_config.py +0 -1
  18. qolsys_controller/database/table_iqrouter_user_device.py +0 -2
  19. qolsys_controller/database/table_master_slave.py +0 -1
  20. qolsys_controller/database/table_nest_device.py +0 -1
  21. qolsys_controller/database/table_output_rules.py +0 -1
  22. qolsys_controller/database/table_partition.py +0 -1
  23. qolsys_controller/database/table_pgm_outputs.py +0 -2
  24. qolsys_controller/database/table_powerg_device.py +0 -2
  25. qolsys_controller/database/table_qolsyssettings.py +0 -2
  26. qolsys_controller/database/table_scene.py +0 -2
  27. qolsys_controller/database/table_sensor.py +2 -2
  28. qolsys_controller/database/table_sensor_group.py +23 -0
  29. qolsys_controller/database/table_shades.py +0 -2
  30. qolsys_controller/database/table_smartsocket.py +12 -3
  31. qolsys_controller/database/table_state.py +0 -1
  32. qolsys_controller/database/table_tcc.py +0 -1
  33. qolsys_controller/database/table_thermostat.py +3 -1
  34. qolsys_controller/database/table_trouble_conditions.py +0 -2
  35. qolsys_controller/database/table_user.py +0 -2
  36. qolsys_controller/database/table_virtual_device.py +13 -3
  37. qolsys_controller/database/table_weather.py +0 -2
  38. qolsys_controller/database/table_zigbee_device.py +0 -1
  39. qolsys_controller/database/table_zwave_association_group.py +0 -1
  40. qolsys_controller/database/table_zwave_history.py +0 -1
  41. qolsys_controller/database/table_zwave_node.py +3 -1
  42. qolsys_controller/database/table_zwave_other.py +0 -1
  43. qolsys_controller/enum.py +42 -13
  44. qolsys_controller/enum_adc.py +28 -0
  45. qolsys_controller/enum_zwave.py +210 -36
  46. qolsys_controller/errors.py +14 -12
  47. qolsys_controller/mdns.py +7 -4
  48. qolsys_controller/mqtt_command.py +125 -0
  49. qolsys_controller/mqtt_command_queue.py +5 -4
  50. qolsys_controller/observable.py +2 -2
  51. qolsys_controller/panel.py +304 -156
  52. qolsys_controller/partition.py +149 -127
  53. qolsys_controller/pki.py +69 -97
  54. qolsys_controller/scene.py +30 -28
  55. qolsys_controller/settings.py +96 -50
  56. qolsys_controller/state.py +221 -34
  57. qolsys_controller/task_manager.py +11 -14
  58. qolsys_controller/users.py +25 -0
  59. qolsys_controller/utils_mqtt.py +8 -16
  60. qolsys_controller/weather.py +71 -0
  61. qolsys_controller/zone.py +243 -214
  62. qolsys_controller/zwave_device.py +234 -93
  63. qolsys_controller/zwave_dimmer.py +55 -49
  64. qolsys_controller/zwave_energy_clamp.py +15 -0
  65. qolsys_controller/zwave_garagedoor.py +3 -1
  66. qolsys_controller/zwave_generic.py +5 -3
  67. qolsys_controller/zwave_lock.py +51 -44
  68. qolsys_controller/zwave_outlet.py +3 -1
  69. qolsys_controller/zwave_service_meter.py +192 -0
  70. qolsys_controller/zwave_service_multilevelsensor.py +119 -0
  71. qolsys_controller/zwave_thermometer.py +21 -0
  72. qolsys_controller/zwave_thermostat.py +249 -143
  73. qolsys_controller-0.0.87.dist-info/METADATA +89 -0
  74. qolsys_controller-0.0.87.dist-info/RECORD +77 -0
  75. {qolsys_controller-0.0.44.dist-info → qolsys_controller-0.0.87.dist-info}/WHEEL +1 -1
  76. qolsys_controller/plugin.py +0 -34
  77. qolsys_controller/plugin_c4.py +0 -17
  78. qolsys_controller/plugin_remote.py +0 -1298
  79. qolsys_controller-0.0.44.dist-info/METADATA +0 -93
  80. qolsys_controller-0.0.44.dist-info/RECORD +0 -68
  81. {qolsys_controller-0.0.44.dist-info → qolsys_controller-0.0.87.dist-info}/licenses/LICENSE +0 -0
@@ -11,19 +11,22 @@ LOGGER = logging.getLogger(__name__)
11
11
 
12
12
 
13
13
  class QolsysPartition(QolsysObservable):
14
-
15
14
  EXIT_SOUNDS_ARRAY = ["ON", "OFF", ""] # noqa: RUF012
16
15
  ENTRY_DELAYS_ARRAY = ["ON", "OFF", ""] # noqa: RUF012
17
16
 
18
- def __init__(self, partition_dict: dict, settings_dict: dict, alarm_state: PartitionAlarmState,
19
- alarm_type_array: list[PartitionAlarmType]) -> None:
20
-
17
+ def __init__(
18
+ self,
19
+ partition_dict: dict[str, str],
20
+ settings_dict: dict[str, str],
21
+ alarm_state: PartitionAlarmState,
22
+ alarm_type_array: list[PartitionAlarmType],
23
+ ) -> None:
21
24
  super().__init__()
22
25
 
23
26
  # Partition info (partition table)
24
- self._id: str = partition_dict.get("partition_id")
25
- self._name: str = partition_dict.get("name")
26
- self._devices = partition_dict.get("devices")
27
+ self._id: str = partition_dict.get("partition_id", "")
28
+ self._name: str = partition_dict.get("name", "")
29
+ self._devices = partition_dict.get("devices", "")
27
30
 
28
31
  # Partition Settings (qolsyssettings table)
29
32
  self._system_status: PartitionSystemStatus = PartitionSystemStatus(settings_dict.get("SYSTEM_STATUS", ""))
@@ -35,61 +38,94 @@ class QolsysPartition(QolsysObservable):
35
38
  self._alarm_state: PartitionAlarmState = alarm_state
36
39
 
37
40
  # Alarm Type (alarmedsensor table)
38
- self._alarm_type_array: list[PartitionAlarmType] = alarm_type_array
41
+ self._alarm_type_array: list[PartitionAlarmType] = []
42
+ self.append_alarm_type(alarm_type_array)
39
43
 
40
44
  # Other
41
- self._command_exit_sounds = True
42
- self._command_arm_stay_instant = True
43
- self._command_arm_stay_silent_disarming = False
44
- self._command_arm_entry_delay = True
45
+ self._command_exit_sounds: bool = True
46
+ self._command_arm_stay_instant: bool = True
47
+ self._command_arm_stay_silent_disarming: bool = False
48
+ self._command_arm_entry_delay: bool = True
45
49
 
46
- @property
47
- def id(self) -> int:
48
- return self._id
50
+ def update_partition(self, data: dict[str, str]) -> None:
51
+ # Check if we are updating same partition_id
52
+ partition_id_update = data.get("partition_id", "")
53
+ if partition_id_update != self.id:
54
+ LOGGER.error(
55
+ "Updating Partition%s (%s) with Partition '%s' (different id)", self._id, self._name, partition_id_update
56
+ )
57
+ return
49
58
 
50
- @property
51
- def name(self) -> str:
52
- return self._name
59
+ self.start_batch_update()
53
60
 
54
- @property
55
- def system_status(self) -> PartitionSystemStatus:
56
- return self._system_status
61
+ # Update Partition Name
62
+ if "name" in data:
63
+ self.name = data.get("name", "")
57
64
 
58
- @property
59
- def system_status_changed_time(self) -> str:
60
- return self._system_status_changed_time
65
+ # Update Partition Devices
66
+ if "devices" in data:
67
+ self._devices = data.get("devices", "")
61
68
 
62
- @property
63
- def alarm_state(self) -> PartitionAlarmState:
64
- return self._alarm_state
69
+ self.end_batch_update()
65
70
 
66
- @property
67
- def alarm_type_array(self) -> list[PartitionAlarmType]:
68
- return self._alarm_type_array
71
+ def update_settings(self, data: dict[str, str]) -> None:
72
+ self.start_batch_update()
69
73
 
70
- @property
71
- def exit_sounds(self) -> str:
72
- return self._exit_sounds
74
+ # Update system_status
75
+ if "SYSTEM_STATUS" in data:
76
+ self.system_status = PartitionSystemStatus(data.get("SYSTEM_STATUS", ""))
73
77
 
74
- @property
75
- def entry_delays(self) -> str:
76
- return self._entry_delays
78
+ # Update system_status_changed_time
79
+ if "SYSTEM_STATUS_CHANGED_TIME" in data:
80
+ self.system_status_changed_time = data.get("SYSTEM_STATUS_CHANGED_TIME", "")
77
81
 
78
- @property
79
- def command_exit_sounds(self) -> bool:
80
- return self._command_exit_sounds
82
+ # Update exit_sounds
83
+ if "EXIT_SOUNDS" in data:
84
+ self.exit_sounds = data.get("EXIT_SOUNDS", "")
85
+
86
+ # Update entry_delays
87
+ if "ENTRY_DELAYS" in data:
88
+ self.entry_delays = data.get("ENTRY_DELAYS", "")
89
+
90
+ self.end_batch_update()
91
+
92
+ def to_dict_partition(self) -> dict[str, str]:
93
+ return {
94
+ "partition_id": self.id,
95
+ "name": self.name,
96
+ "devices": self._devices,
97
+ }
98
+
99
+ def to_dict_settings(self) -> dict[str, str]:
100
+ return {
101
+ "SYSTEM_STATUS": self.system_status.value,
102
+ "SYSTEM_STATUS_CHANGED_TIME": self.system_status_changed_time,
103
+ "EXIT_SOUNDS": self.exit_sounds,
104
+ "ENTRY_DELAYS": self.entry_delays,
105
+ }
106
+
107
+ # -----------------------------
108
+ # properties + setters
109
+ # -----------------------------
81
110
 
82
111
  @property
83
- def command_arm_stay_instant(self) -> bool:
84
- return self._command_arm_stay_instant
112
+ def id(self) -> str:
113
+ return self._id
85
114
 
86
115
  @property
87
- def command_arm_stay_silent_disarming(self) -> bool:
88
- return self._command_arm_stay_silent_disarming
116
+ def name(self) -> str:
117
+ return self._name
118
+
119
+ @name.setter
120
+ def name(self, value: str) -> None:
121
+ if self._name != value:
122
+ LOGGER.debug("Partition%s (%s) - name: %s", self._id, self._name, value)
123
+ self._name = value
124
+ self.notify()
89
125
 
90
126
  @property
91
- def command_arm_entry_delay(self) -> bool:
92
- return self._command_arm_entry_delay
127
+ def system_status(self) -> PartitionSystemStatus:
128
+ return self._system_status
93
129
 
94
130
  @system_status.setter
95
131
  def system_status(self, new_value: PartitionSystemStatus) -> None:
@@ -98,6 +134,10 @@ class QolsysPartition(QolsysObservable):
98
134
  self._system_status = new_value
99
135
  self.notify()
100
136
 
137
+ @property
138
+ def system_status_changed_time(self) -> str:
139
+ return self._system_status_changed_time
140
+
101
141
  @system_status_changed_time.setter
102
142
  def system_status_changed_time(self, value: str) -> None:
103
143
  if self._system_status_changed_time != value:
@@ -105,6 +145,10 @@ class QolsysPartition(QolsysObservable):
105
145
  self._system_status_changed_time = value
106
146
  self.notify()
107
147
 
148
+ @property
149
+ def alarm_state(self) -> PartitionAlarmState:
150
+ return self._alarm_state
151
+
108
152
  @alarm_state.setter
109
153
  def alarm_state(self, new_value: PartitionAlarmState) -> None:
110
154
  if self._alarm_state != new_value:
@@ -112,9 +156,12 @@ class QolsysPartition(QolsysObservable):
112
156
  self._alarm_state = new_value
113
157
  self.notify()
114
158
 
159
+ @property
160
+ def alarm_type_array(self) -> list[PartitionAlarmType]:
161
+ return self._alarm_type_array
162
+
115
163
  @alarm_type_array.setter
116
164
  def alarm_type_array(self, new_alarm_type_array: list[PartitionAlarmType]) -> None:
117
-
118
165
  # If no changes are detected: return without notification
119
166
  if sorted(new_alarm_type_array, key=lambda c: c.value) == sorted(self.alarm_type_array, key=lambda c: c.value):
120
167
  return
@@ -130,30 +177,9 @@ class QolsysPartition(QolsysObservable):
130
177
 
131
178
  self.append_alarm_type(new_alarm_type_array)
132
179
 
133
- @name.setter
134
- def name(self, value: str) -> None:
135
- if self._name != value:
136
- LOGGER.debug("Partition%s (%s) - name: %s", self._id, self._name, value)
137
- self._name = value
138
- self.notify()
139
-
140
- def append_alarm_type(self, new_alarm_type_array: list[PartitionAlarmType]) -> None:
141
-
142
- data_changed = False
143
-
144
- for new_alarm_type in new_alarm_type_array:
145
-
146
- # Value already in array
147
- if new_alarm_type in self._alarm_type_array:
148
- continue
149
-
150
- self._alarm_type_array.append(new_alarm_type)
151
- data_changed = True
152
-
153
- if data_changed:
154
- self.notify()
155
- for alarm in self._alarm_type_array:
156
- LOGGER.debug("Partition%s (%s) - alarm_type: %s", self._id, self._name, alarm)
180
+ @property
181
+ def exit_sounds(self) -> str:
182
+ return self._exit_sounds
157
183
 
158
184
  @exit_sounds.setter
159
185
  def exit_sounds(self, value: str) -> None:
@@ -166,6 +192,10 @@ class QolsysPartition(QolsysObservable):
166
192
  self._exit_sounds = value
167
193
  self.notify()
168
194
 
195
+ @property
196
+ def entry_delays(self) -> str:
197
+ return self._entry_delays
198
+
169
199
  @entry_delays.setter
170
200
  def entry_delays(self, value: str) -> None:
171
201
  if value not in self.ENTRY_DELAYS_ARRAY:
@@ -177,85 +207,77 @@ class QolsysPartition(QolsysObservable):
177
207
  self._entry_delays = value
178
208
  self.notify()
179
209
 
210
+ @property
211
+ def command_exit_sounds(self) -> bool:
212
+ return self._command_exit_sounds
213
+
180
214
  @command_exit_sounds.setter
181
- def command_exit_sounds(self, value: str) -> None:
215
+ def command_exit_sounds(self, value: bool) -> None:
182
216
  self._command_exit_sounds = value
183
217
  LOGGER.debug("Partition%s (%s) - command_exit_sounds: %s", self._id, self._name, value)
184
218
  self.notify()
185
219
 
220
+ @property
221
+ def command_arm_stay_instant(self) -> bool:
222
+ return self._command_arm_stay_instant
223
+
186
224
  @command_arm_stay_instant.setter
187
- def command_arm_stay_instant(self, value: str) -> None:
225
+ def command_arm_stay_instant(self, value: bool) -> None:
188
226
  self._command_arm_stay_instant = value
189
227
  LOGGER.debug("Partition%s (%s) - arm_stay_instant: %s", self._id, self._name, value)
190
228
  self.notify()
191
229
 
230
+ @property
231
+ def command_arm_stay_silent_disarming(self) -> bool:
232
+ return self._command_arm_stay_silent_disarming
233
+
192
234
  @command_arm_stay_silent_disarming.setter
193
235
  def command_arm_stay_silent_disarming(self, value: bool) -> None:
194
236
  self._command_arm_stay_silent_disarming = value
195
237
  LOGGER.debug("Partition%s (%s) - arm_stay_silent_disarming: %s", self._id, self._name, value)
196
238
  self.notify()
197
239
 
240
+ @property
241
+ def command_arm_entry_delay(self) -> bool:
242
+ return self._command_arm_entry_delay
243
+
198
244
  @command_arm_entry_delay.setter
199
- def command_arm_entry_delay(self, value:bool) -> None:
245
+ def command_arm_entry_delay(self, value: bool) -> None:
200
246
  self._command_arm_entry_delay = value
201
247
  LOGGER.debug("Partition%s (%s) - command_arm_entry_delay: %s", self._id, self._name, value)
202
248
  self.notify()
203
249
 
250
+ def append_alarm_type(self, new_alarm_type_array: list[PartitionAlarmType]) -> None:
251
+ data_changed = False
204
252
 
253
+ for new_alarm_type in new_alarm_type_array:
254
+ # Map values to Police Emergency if needed
255
+ if new_alarm_type in {
256
+ PartitionAlarmType.GLASS_BREAK,
257
+ PartitionAlarmType.GLASS_BREAK_AWAY_ONLY,
258
+ PartitionAlarmType.ENTRY_EXIT_LONG_DELAY,
259
+ PartitionAlarmType.ENTRY_EXIT_NORMAL_DELAY,
260
+ PartitionAlarmType.INSTANT_PERIMETER_DW,
261
+ PartitionAlarmType.INSTANT_INTERIOR_DOOR,
262
+ PartitionAlarmType.AWAY_DELAY_MOTION,
263
+ PartitionAlarmType.AWAY_INSTANT_MOTION,
264
+ PartitionAlarmType.REPORTING_SAFETY_SENSOR,
265
+ PartitionAlarmType.DELAYED_REPORTING_SAFETY_SENSOR,
266
+ PartitionAlarmType.AWAY_INSTANT_FOLLOWER_DELAY,
267
+ PartitionAlarmType.STAY_INSTANT_MOTION,
268
+ PartitionAlarmType.STAY_DELAY_MOTION,
269
+ PartitionAlarmType.EMPTY,
270
+ }:
271
+ new_alarm_type = PartitionAlarmType.POLICE_EMERGENCY
205
272
 
206
- def update_partition(self, data: dict) -> None:
207
- # Check if we are updating same partition_id
208
- partition_id_update = data.get("partition_id", "")
209
- if int(partition_id_update) != int(self.id):
210
- LOGGER.error(
211
- "Updating Partition%s (%s) with Partition '%s' (different id)", self._id, self._name, partition_id_update)
212
- return
213
-
214
- self.start_batch_update()
215
-
216
- # Update Partition Name
217
- if "name" in data:
218
- self.name = data.get("name")
219
-
220
- # Update Partition Devices
221
- if "devices" in data:
222
- self._devices = data.get("devices")
223
-
224
- self.end_batch_update()
225
-
226
- def update_settings(self, data: dict) -> None:
227
-
228
- self.start_batch_update()
229
-
230
- # Update system_status
231
- if "SYSTEM_STATUS" in data:
232
- self.system_status = data.get("SYSTEM_STATUS")
233
-
234
- # Update system_status_changed_time
235
- if "SYSTEM_STATUS_CHANGED_TIME" in data:
236
- self.system_status_changed_time = data.get("SYSTEM_STATUS_CHANGED_TIME")
237
-
238
- # Update exit_sounds
239
- if "EXIT_SOUNDS" in data:
240
- self.exit_sounds = data.get("EXIT_SOUNDS")
241
-
242
- # Update entry_delays
243
- if "ENTRY_DELAYS" in data:
244
- self.entry_delays = data.get("ENTRY_DELAYS")
245
-
246
- self.end_batch_update()
273
+ # Value already in array
274
+ if new_alarm_type in self._alarm_type_array:
275
+ continue
247
276
 
248
- def to_dict_partition(self) -> dict:
249
- return {
250
- "partition_id": self.id,
251
- "name": self.name,
252
- "devices": self._devices,
253
- }
277
+ self._alarm_type_array.append(new_alarm_type)
278
+ data_changed = True
254
279
 
255
- def to_dict_settings(self) -> dict:
256
- return {
257
- "SYSTEM_STATUS": self.system_status.value,
258
- "SYSTEM_STATUS_CHANGED_TIME": self.system_status_changed_time,
259
- "EXIT_SOUNDS": self.exit_sounds,
260
- "ENTRY_DELAYS": self.entry_delays,
261
- }
280
+ if data_changed:
281
+ self.notify()
282
+ for alarm in self._alarm_type_array:
283
+ LOGGER.debug("Partition%s (%s) - alarm_type: %s", self._id, self._name, alarm)
qolsys_controller/pki.py CHANGED
@@ -1,13 +1,12 @@
1
1
  import logging
2
2
  import os
3
3
  import re
4
- from datetime import datetime, timedelta
4
+ from datetime import datetime, timedelta, timezone
5
5
  from pathlib import Path
6
6
 
7
7
  from cryptography import x509
8
8
  from cryptography.hazmat.primitives import hashes, serialization
9
9
  from cryptography.hazmat.primitives.asymmetric import rsa
10
- from cryptography.x509 import load_pem_x509_csr
11
10
  from cryptography.x509.oid import NameOID
12
11
 
13
12
  from .settings import QolsysSettings
@@ -18,13 +17,12 @@ LOGGER = logging.getLogger(__name__)
18
17
  class QolsysPKI:
19
18
  def __init__(self, settings: QolsysSettings) -> None:
20
19
  self._id = ""
21
- self._subkeys_directory: Path = Path
22
-
23
- self._key = None
24
- self._cer = None
25
- self._csr = None
26
- self._secure = None
27
- self._qolsys = None
20
+ self._subkeys_directory: Path = Path()
21
+ self._key: Path = Path()
22
+ self._cer: Path = Path()
23
+ self._csr: Path = Path()
24
+ self._secure: Path = Path()
25
+ self._qolsys: Path = Path()
28
26
 
29
27
  self._settings = settings
30
28
 
@@ -33,7 +31,7 @@ class QolsysPKI:
33
31
  return self._id
34
32
 
35
33
  def formatted_id(self) -> str:
36
- return ":".join(self.id[i:i+2] for i in range(0, len(self.id), 2))
34
+ return ":".join(self.id[i : i + 2] for i in range(0, len(self.id), 2))
37
35
 
38
36
  def set_id(self, pki_id: str) -> None:
39
37
  self._id = pki_id.replace(":", "").lower()
@@ -41,23 +39,23 @@ class QolsysPKI:
41
39
  self._subkeys_directory = self._settings.pki_directory.joinpath(Path(self.id))
42
40
 
43
41
  @property
44
- def key(self) -> str:
42
+ def key(self) -> Path:
45
43
  return self._key
46
44
 
47
45
  @property
48
- def cer(self) -> str:
46
+ def cer(self) -> Path:
49
47
  return self._cer
50
48
 
51
49
  @property
52
- def csr(self) -> str:
50
+ def csr(self) -> Path:
53
51
  return self._csr
54
52
 
55
53
  @property
56
- def secure(self) -> str:
54
+ def secure(self) -> Path:
57
55
  return self._secure
58
56
 
59
57
  @property
60
- def qolsys(self) -> str:
58
+ def qolsys(self) -> Path:
61
59
  return self._qolsys
62
60
 
63
61
  def auto_discover_pki(self) -> bool:
@@ -72,51 +70,6 @@ class QolsysPKI:
72
70
 
73
71
  return False
74
72
 
75
- def load_private_key(self, key: str) -> bool:
76
- try:
77
- self._key = serialization.load_pem_private_key(key.encode(), password=None)
78
- except ValueError:
79
- LOGGER.debug("Private Key Value Error")
80
- return False
81
-
82
- return True
83
-
84
- def load_certificate(self, cer: str) -> bool:
85
- try:
86
- self._cer = x509.load_pem_x509_certificate(cer.encode(), None)
87
- except ValueError:
88
- LOGGER.debug("Certificate Value Error")
89
- return False
90
-
91
- return True
92
-
93
- def load_certificate_signing_request(self, csr: str) -> bool:
94
- try:
95
- self._csr = load_pem_x509_csr(csr.encode())
96
- except ValueError:
97
- LOGGER.debug("Certificate Signing Request Value Error")
98
- return False
99
-
100
- return True
101
-
102
- def load_qolsys_certificate(self, qolsys: str) -> bool:
103
- try:
104
- self._qolsys = x509.load_pem_x509_certificate(qolsys.encode(), None)
105
- except ValueError:
106
- LOGGER.debug("Qolsys Certificate Value Error")
107
- return False
108
-
109
- return True
110
-
111
- def load_signed_client_certificate(self, secure: str) -> bool:
112
- try:
113
- self._secure = x509.load_pem_x509_certificate(secure.encode(), None)
114
- except ValueError:
115
- LOGGER.debug("Client Signed Certificate Value Error")
116
- return False
117
-
118
- return True
119
-
120
73
  def check_key_file(self) -> bool:
121
74
  if self._subkeys_directory.joinpath(self.id + ".key").resolve().exists():
122
75
  LOGGER.debug("Found KEY")
@@ -157,23 +110,22 @@ class QolsysPKI:
157
110
  return self._subkeys_directory.joinpath(self.id + ".key")
158
111
 
159
112
  @property
160
- def csr_file_path(self) -> str:
113
+ def csr_file_path(self) -> Path:
161
114
  return self._subkeys_directory.joinpath(self.id + ".csr")
162
115
 
163
116
  @property
164
- def cer_file_path(self) -> str:
117
+ def cer_file_path(self) -> Path:
165
118
  return self._subkeys_directory.joinpath(self.id + ".cer")
166
119
 
167
120
  @property
168
- def secure_file_path(self) -> str:
121
+ def secure_file_path(self) -> Path:
169
122
  return self._subkeys_directory.joinpath(self.id + ".secure")
170
123
 
171
124
  @property
172
- def qolsys_cer_file_path(self) -> str:
125
+ def qolsys_cer_file_path(self) -> Path:
173
126
  return self._subkeys_directory.joinpath(self.id + ".qolsys")
174
127
 
175
128
  def create(self, mac: str, key_size: int) -> bool:
176
-
177
129
  self.set_id(mac)
178
130
 
179
131
  # Check if directory exist
@@ -207,48 +159,68 @@ class QolsysPKI:
207
159
  self._subkeys_directory.resolve().mkdir(parents=True)
208
160
 
209
161
  LOGGER.debug("Creating KEY")
210
- private_key = rsa.generate_private_key(public_exponent=65537,
211
- key_size=key_size)
212
- private_pem = private_key.private_bytes(encoding=serialization.Encoding.PEM,
213
- format=serialization.PrivateFormat.PKCS8,
214
- encryption_algorithm=serialization.NoEncryption())
162
+ private_key = rsa.generate_private_key(public_exponent=65537, key_size=key_size)
163
+ private_pem = private_key.private_bytes(
164
+ encoding=serialization.Encoding.PEM,
165
+ format=serialization.PrivateFormat.PKCS8,
166
+ encryption_algorithm=serialization.NoEncryption(),
167
+ )
215
168
  with self._subkeys_directory.joinpath(self.id + ".key").open("wb") as file:
216
169
  file.write(private_pem)
217
170
 
218
171
  LOGGER.debug("Creating CER")
219
- subject = issuer = x509.Name([
220
- x509.NameAttribute(NameOID.COUNTRY_NAME, "US"),
221
- x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "SanJose"),
222
- x509.NameAttribute(NameOID.LOCALITY_NAME, ""),
223
- x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Qolsys Inc."),
224
- x509.NameAttribute(NameOID.COMMON_NAME, "www.qolsys.com "),
225
- ])
226
- cert = x509.CertificateBuilder().subject_name(
227
- subject,
228
- ).issuer_name(
229
- issuer,
230
- ).public_key(
231
- private_key.public_key(),
232
- ).serial_number(
233
- x509.random_serial_number(),
234
- ).not_valid_before(
235
- datetime.utcnow(),
236
- ).not_valid_after(
237
- datetime.utcnow() + timedelta(days=365),
238
- ).add_extension(
239
- x509.BasicConstraints(ca=False, path_length=None), critical=True,
240
- ).sign(private_key, hashes.SHA256())
172
+ subject = issuer = x509.Name(
173
+ [
174
+ x509.NameAttribute(NameOID.COUNTRY_NAME, "US"),
175
+ x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "SanJose"),
176
+ x509.NameAttribute(NameOID.LOCALITY_NAME, ""),
177
+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Qolsys Inc."),
178
+ x509.NameAttribute(NameOID.COMMON_NAME, "www.qolsys.com "),
179
+ ]
180
+ )
181
+ cert = (
182
+ x509.CertificateBuilder()
183
+ .subject_name(
184
+ subject,
185
+ )
186
+ .issuer_name(
187
+ issuer,
188
+ )
189
+ .public_key(
190
+ private_key.public_key(),
191
+ )
192
+ .serial_number(
193
+ x509.random_serial_number(),
194
+ )
195
+ .not_valid_before(
196
+ datetime.now(timezone.utc), # noqa: UP017
197
+ )
198
+ .not_valid_after(
199
+ datetime.now(timezone.utc) + timedelta(days=3650), # noqa: UP017
200
+ )
201
+ .add_extension(
202
+ x509.BasicConstraints(ca=False, path_length=None),
203
+ critical=True,
204
+ )
205
+ .sign(private_key, hashes.SHA256())
206
+ )
241
207
  cert_pem = cert.public_bytes(encoding=serialization.Encoding.PEM)
242
208
 
243
209
  with self._subkeys_directory.joinpath(self.id + ".cer").open("wb") as file:
244
210
  file.write(cert_pem)
245
211
 
246
212
  LOGGER.debug("Creating CSR")
247
- csr = x509.CertificateSigningRequestBuilder().subject_name(
248
- subject,
249
- ).add_extension(
250
- x509.BasicConstraints(ca=False, path_length=None), critical=True,
251
- ).sign(private_key, hashes.SHA256())
213
+ csr = (
214
+ x509.CertificateSigningRequestBuilder()
215
+ .subject_name(
216
+ subject,
217
+ )
218
+ .add_extension(
219
+ x509.BasicConstraints(ca=False, path_length=None),
220
+ critical=True,
221
+ )
222
+ .sign(private_key, hashes.SHA256())
223
+ )
252
224
 
253
225
  # Save CSR to file
254
226
  csr_pem = csr.public_bytes(encoding=serialization.Encoding.PEM)