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
@@ -1,5 +1,6 @@
1
1
  import logging # noqa: INP001
2
2
  import sqlite3
3
+ from typing import Any
3
4
 
4
5
  from .table import QolsysTable
5
6
  from .table_alarmedsensor import QolsysTableAlarmedSensor
@@ -23,6 +24,7 @@ from .table_powerg_device import QolsysTablePowerGDevice
23
24
  from .table_qolsyssettings import QolsysTableQolsysSettings
24
25
  from .table_scene import QolsysTableScene
25
26
  from .table_sensor import QolsysTableSensor
27
+ from .table_sensor_group import QolsysTableSensorGroup
26
28
  from .table_shades import QolsysTableShades
27
29
  from .table_smartsocket import QolsysTableSmartSocket
28
30
  from .table_state import QolsysTableState
@@ -42,9 +44,7 @@ LOGGER = logging.getLogger(__name__)
42
44
 
43
45
 
44
46
  class QolsysDB:
45
-
46
47
  def __init__(self) -> None: # noqa: PLR0915
47
-
48
48
  self._db: sqlite3.Connection = sqlite3.connect(":memory:")
49
49
  self._cursor: sqlite3.Cursor = self._db.cursor()
50
50
 
@@ -64,6 +64,7 @@ class QolsysDB:
64
64
  self.table_partition = QolsysTablePartition(self.db, self.cursor)
65
65
  self.table_powerg_device = QolsysTablePowerGDevice(self.db, self.cursor)
66
66
  self.table_sensor = QolsysTableSensor(self.db, self.cursor)
67
+ self.table_sensor_group = QolsysTableSensorGroup(self.db, self.cursor)
67
68
  self.table_smartsocket = QolsysTableSmartSocket(self.db, self.cursor)
68
69
  self.table_qolsyssettings = QolsysTableQolsysSettings(self.db, self.cursor)
69
70
  self.table_scene = QolsysTableScene(self.db, self.cursor)
@@ -84,8 +85,9 @@ class QolsysDB:
84
85
  self.table_shades = QolsysTableShades(self.db, self.cursor)
85
86
  self.table_nest_device = QolsysTableNestDevice(self.db, self.cursor)
86
87
 
87
- self._table_array = []
88
+ self._table_array: list[QolsysTable] = []
88
89
  self._table_array.append(self.table_sensor)
90
+ self._table_array.append(self.table_sensor_group)
89
91
  self._table_array.append(self.table_partition)
90
92
  self._table_array.append(self.table_qolsyssettings)
91
93
  self._table_array.append(self.table_alarmedsensor)
@@ -153,7 +155,43 @@ class QolsysDB:
153
155
  def cursor(self) -> sqlite3.Cursor:
154
156
  return self._cursor
155
157
 
156
- def get_scenes(self) -> list[dict]:
158
+ def get_users(self) -> list[dict[str, str]]:
159
+ self.cursor.execute(f"SELECT * FROM {self.table_user.table} ORDER BY _id")
160
+ self.db.commit()
161
+
162
+ users = []
163
+ columns = [description[0] for description in self.cursor.description]
164
+ for row in self.cursor.fetchall():
165
+ row_dict = dict(zip(columns, row, strict=True))
166
+ users.append(row_dict)
167
+
168
+ return users
169
+
170
+ def get_master_slave(self) -> list[dict[str, str]]:
171
+ self.cursor.execute(f"SELECT * FROM {self.table_master_slave.table}")
172
+ self.db.commit()
173
+
174
+ masterslave = []
175
+ columns = [description[0] for description in self.cursor.description]
176
+ for row in self.cursor.fetchall():
177
+ row_dict = dict(zip(columns, row, strict=True))
178
+ masterslave.append(row_dict)
179
+
180
+ return masterslave
181
+
182
+ def get_iqremote_settings(self) -> list[dict[str, str]]:
183
+ self.cursor.execute(f"SELECT * FROM {self.table_iqremotesettings.table}")
184
+ self.db.commit()
185
+
186
+ iqremote_settings = []
187
+ columns = [description[0] for description in self.cursor.description]
188
+ for row in self.cursor.fetchall():
189
+ row_dict = dict(zip(columns, row, strict=True))
190
+ iqremote_settings.append(row_dict)
191
+
192
+ return iqremote_settings
193
+
194
+ def get_scenes(self) -> list[dict[str, str]]:
157
195
  self.cursor.execute(f"SELECT * FROM {self.table_scene.table} ORDER BY scene_id")
158
196
  self.db.commit()
159
197
 
@@ -165,7 +203,7 @@ class QolsysDB:
165
203
 
166
204
  return scenes
167
205
 
168
- def get_partitions(self) -> list[dict]:
206
+ def get_partitions(self) -> list[dict[str, str]]:
169
207
  self.cursor.execute(f"SELECT * FROM {self.table_partition.table} ORDER BY partition_id")
170
208
  self.db.commit()
171
209
 
@@ -177,7 +215,19 @@ class QolsysDB:
177
215
 
178
216
  return partitions
179
217
 
180
- def get_zwave_devices(self) -> list[dict]:
218
+ def get_adc_devices(self) -> list[dict[str, str]]:
219
+ self.cursor.execute(f"SELECT * FROM {self.table_virtual_device.table} ORDER BY device_id")
220
+ self.db.commit()
221
+
222
+ devices = []
223
+ columns = [description[0] for description in self.cursor.description]
224
+ for row in self.cursor.fetchall():
225
+ row_dict = dict(zip(columns, row, strict=True))
226
+ devices.append(row_dict)
227
+
228
+ return devices
229
+
230
+ def get_zwave_devices(self) -> list[dict[str, str]]:
181
231
  self.cursor.execute(f"SELECT * FROM {self.table_zwave_node.table} ORDER BY node_id")
182
232
  self.db.commit()
183
233
 
@@ -189,7 +239,19 @@ class QolsysDB:
189
239
 
190
240
  return devices
191
241
 
192
- def get_locks(self) -> list[dict]:
242
+ def get_zwave_other_devices(self) -> list[dict[str, str]]:
243
+ self.cursor.execute(f"SELECT * FROM {self.table_zwave_other.table} ORDER BY node_id")
244
+ self.db.commit()
245
+
246
+ devices = []
247
+ columns = [description[0] for description in self.cursor.description]
248
+ for row in self.cursor.fetchall():
249
+ row_dict = dict(zip(columns, row, strict=True))
250
+ devices.append(row_dict)
251
+
252
+ return devices
253
+
254
+ def get_locks(self) -> list[dict[str, str]]:
193
255
  self.cursor.execute(f"SELECT * FROM {self.table_doorlock.table} ORDER BY node_id")
194
256
  self.db.commit()
195
257
 
@@ -201,7 +263,7 @@ class QolsysDB:
201
263
 
202
264
  return locks
203
265
 
204
- def get_thermostats(self) -> list[dict]:
266
+ def get_thermostats(self) -> list[dict[str, str]]:
205
267
  self.cursor.execute(f"SELECT * FROM {self.table_thermostat.table} ORDER BY node_id")
206
268
  self.db.commit()
207
269
 
@@ -213,7 +275,7 @@ class QolsysDB:
213
275
 
214
276
  return thermostats
215
277
 
216
- def get_dimmers(self) -> list[dict]:
278
+ def get_dimmers(self) -> list[dict[str, str]]:
217
279
  self.cursor.execute(f"SELECT * FROM {self.table_dimmer.table} ORDER BY node_id")
218
280
  self.db.commit()
219
281
 
@@ -225,7 +287,7 @@ class QolsysDB:
225
287
 
226
288
  return dimmers
227
289
 
228
- def get_zones(self) -> list[dict]:
290
+ def get_zones(self) -> list[dict[str, str]]:
229
291
  self.cursor.execute(f"SELECT * FROM {self.table_sensor.table} ORDER BY zoneid")
230
292
  self.db.commit()
231
293
 
@@ -237,9 +299,21 @@ class QolsysDB:
237
299
 
238
300
  return zones
239
301
 
240
- def get_powerg(self, short_id: str) -> dict:
302
+ def get_weather(self) -> list[dict[str, str]]:
303
+ self.cursor.execute(f"SELECT * FROM {self.table_weather.table} ORDER BY _id")
304
+ self.db.commit()
305
+
306
+ weather_list = []
307
+ columns = [description[0] for description in self.cursor.description]
308
+ for row in self.cursor.fetchall():
309
+ row_dict = dict(zip(columns, row, strict=True))
310
+ weather_list.append(row_dict)
311
+
312
+ return weather_list
313
+
314
+ def get_powerg(self, short_id: str) -> dict[str, str] | None:
241
315
  try:
242
- self.cursor.execute(f"SELECT * FROM {self.table_powerg_device.table} WHERE shortID = ?",(short_id,))
316
+ self.cursor.execute(f"SELECT * FROM {self.table_powerg_device.table} WHERE shortID = ?", (short_id,))
243
317
  self.db.commit()
244
318
 
245
319
  row = self.cursor.fetchone()
@@ -249,45 +323,51 @@ class QolsysDB:
249
323
  return None
250
324
 
251
325
  columns = [description[0] for description in self.cursor.description]
252
- return dict(zip(columns, row, strict=True))
326
+ return dict(zip(columns, row, strict=True))
253
327
 
254
328
  except sqlite3.Error:
255
329
  LOGGER.exception("Error getting PowerG device info for shortID %s", short_id)
256
330
  return None
257
331
 
258
-
259
332
  def get_setting_panel(self, setting: str) -> str:
260
- self.cursor.execute(f"""SELECT value FROM {self.table_qolsyssettings.table}
261
- WHERE name = ? and partition_id = ? """, (setting, "0"))
333
+ self.cursor.execute(
334
+ f"""SELECT value FROM {self.table_qolsyssettings.table}
335
+ WHERE name = ? and partition_id = ? """,
336
+ (setting, "0"),
337
+ )
262
338
  row = self.cursor.fetchone()
263
339
 
264
340
  if row is None:
265
341
  LOGGER.debug("%s value not found", setting)
266
- return None
342
+ return ""
267
343
 
268
- return row[0]
344
+ return str(row[0])
269
345
 
270
- def get_setting_partition(self, setting: str, partition_id: str) -> str | None:
271
- self.cursor.execute(f"""SELECT value FROM {self.table_qolsyssettings.table}
272
- WHERE name = ? and partition_id = ? """, (setting, partition_id))
346
+ def get_setting_partition(self, setting: str, partition_id: str) -> str:
347
+ self.cursor.execute(
348
+ f"""SELECT value FROM {self.table_qolsyssettings.table}
349
+ WHERE name = ? and partition_id = ? """,
350
+ (setting, partition_id),
351
+ )
273
352
  row = self.cursor.fetchone()
274
353
 
275
354
  if row is None:
276
355
  LOGGER.debug("%s value not found", setting)
277
- return None
356
+ return ""
278
357
 
279
- return row[0]
358
+ return str(row[0])
280
359
 
281
360
  def get_state_partition(self, state: str, partition_id: str) -> str | None:
282
361
  self.cursor.execute(
283
- f"""SELECT value FROM {self.table_state.table} WHERE name = ? and partition_id = ? """, (state, partition_id))
362
+ f"""SELECT value FROM {self.table_state.table} WHERE name = ? and partition_id = ? """, (state, partition_id)
363
+ )
284
364
  row = self.cursor.fetchone()
285
365
 
286
366
  if row is None:
287
367
  LOGGER.debug("%s value not found", state)
288
368
  return None
289
369
 
290
- return row[0]
370
+ return str(row[0])
291
371
 
292
372
  def get_alarm_type(self, partition_id: str) -> list[str]:
293
373
  alarm_type = []
@@ -310,8 +390,7 @@ class QolsysDB:
310
390
 
311
391
  return None
312
392
 
313
- def load_db(self, database: dict) -> None:
314
-
393
+ def load_db(self, database: list[dict[str, Any]]) -> None:
315
394
  self.clear_db()
316
395
 
317
396
  if not database:
@@ -319,7 +398,7 @@ class QolsysDB:
319
398
  return
320
399
 
321
400
  for uri in database:
322
- table = self.get_table(uri.get("uri"))
401
+ table = self.get_table(uri.get("uri", ""))
323
402
 
324
403
  if table is None:
325
404
  LOGGER.error("Please Report")
@@ -327,5 +406,5 @@ class QolsysDB:
327
406
  LOGGER.error(uri)
328
407
  continue
329
408
 
330
- for u in uri.get("resultSet"):
409
+ for u in uri.get("resultSet", ""):
331
410
  table.insert(data=u)
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTable:
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  self._db: sqlite3.Connection = db
13
12
  self._cursor: sqlite3.Cursor = cursor
@@ -15,7 +14,7 @@ class QolsysTable:
15
14
  self._table: str = ""
16
15
  self._columns: list[str] = []
17
16
  self._abort_on_error: bool = False
18
- self._implemented:bool = False
17
+ self._implemented: bool = False
19
18
 
20
19
  @property
21
20
  def uri(self) -> str:
@@ -37,16 +36,18 @@ class QolsysTable:
37
36
  column_defs += [f"{col} TEXT" for col in other_columns]
38
37
 
39
38
  try:
40
- query = f"CREATE TABLE {self._table} ({', '.join(column_defs)})"
39
+ query: str = f"CREATE TABLE {self._table} ({', '.join(column_defs)})"
41
40
  self._cursor.execute(query)
42
41
  self._db.commit()
43
42
 
44
43
  except sqlite3.Error as err:
45
- error = QolsysSqlError({
46
- "table": self.table,
47
- "query": query,
48
- "columns": self._columns,
49
- })
44
+ error = QolsysSqlError(
45
+ {
46
+ "table": self.table,
47
+ "query": query,
48
+ "columns": self._columns,
49
+ }
50
+ )
50
51
 
51
52
  if self._abort_on_error:
52
53
  raise error from err
@@ -58,16 +59,18 @@ class QolsysTable:
58
59
  self._db.commit()
59
60
 
60
61
  except sqlite3.Error as err:
61
- error = QolsysSqlError({
62
- "table": self.table,
63
- "query": query,
64
- "columns": self._columns,
65
- })
62
+ error = QolsysSqlError(
63
+ {
64
+ "table": self.table,
65
+ "query": query,
66
+ "columns": self._columns,
67
+ }
68
+ )
66
69
 
67
70
  if self._abort_on_error:
68
71
  raise error from err
69
72
 
70
- def insert(self, data: dict) -> None:
73
+ def insert(self, data: dict[str, str]) -> None:
71
74
  try:
72
75
  if not self._implemented and data is not None:
73
76
  LOGGER.warning("New Table format: %s", self.uri)
@@ -76,6 +79,7 @@ class QolsysTable:
76
79
  LOGGER.warning("Please Report")
77
80
  return
78
81
 
82
+ # Select only known columns
79
83
  full_data = {col: data.get(col, "") for col in self._columns}
80
84
 
81
85
  new_columns = []
@@ -92,97 +96,123 @@ class QolsysTable:
92
96
 
93
97
  col_str = ", ".join(full_data.keys())
94
98
  placeholder_str = ", ".join([f":{key}" for key in full_data])
99
+
95
100
  query = f"INSERT OR IGNORE INTO {self.table} ({col_str}) VALUES ({placeholder_str})"
96
101
  self._cursor.execute(query, full_data)
97
102
  self._db.commit()
98
103
 
99
104
  except sqlite3.Error as err:
100
- error = QolsysSqlError({
101
- "table": self.table,
102
- "query": query,
103
- "columns": self._columns,
104
- })
105
+ error = QolsysSqlError(
106
+ {
107
+ "table": self.table,
108
+ "query": query,
109
+ "columns": self._columns,
110
+ }
111
+ )
105
112
 
106
113
  if self._abort_on_error:
107
114
  raise error from err
108
115
 
109
- def update(self, selection: str, selection_argument: str, content_value: str) -> None:
116
+ def update(
117
+ self, selection: str | None, selection_argument: list[str] | str | None, content_value: dict[str, str] | None
118
+ ) -> None:
110
119
  # selection: 'zone_id=?, parition_id=?'
111
-
112
- # selection_argument:
113
120
  # Firmware 4.4.1: selection_argument: '[3,1]'
114
121
  # Firmware 4.6.1: selection_argument: ['3','1']
115
122
 
116
- # contentValues:{"partition_id":"0","sensorgroup":"safetymotion","sensorstatus":"Idle"}"
117
-
118
-
119
- # Selection Argument
120
- # Panel send selection_argument as list in Firmware 4.6.1
121
- if(type(selection_argument) is not list):
122
- #Firmware 4.4.1, seletion_argument is sent as a string
123
+ # Firmware 4.4.1: seletion_argument is sent as a string and needs to be converted to an array
124
+ if isinstance(selection_argument, str):
123
125
  selection_argument = selection_argument.strip("[]")
124
126
  selection_argument = [item.strip() for item in selection_argument.split(",")]
125
127
 
128
+ if selection_argument is None:
129
+ selection_argument = []
130
+
126
131
  try:
127
132
  full_data = {}
128
133
  new_columns = []
129
134
 
130
- for key, value in content_value.items():
131
- if key in self._columns:
132
- full_data[key] = value
133
- else:
134
- new_columns.append(key)
135
-
136
- db_value = ",".join([f"{key}='{value}'" for key, value in full_data.items()])
135
+ # Separate valid and unknown columns
136
+ if content_value is not None:
137
+ for key, value in content_value.items():
138
+ if key in self._columns:
139
+ full_data[key] = value
140
+ else:
141
+ new_columns.append(key)
137
142
 
138
- # Warn if new column found in iq2meid database
143
+ # Warn for unknown columns
139
144
  if new_columns:
140
145
  LOGGER.warning("New column found in iq2meid database")
141
146
  LOGGER.warning("Table: %s", self.table)
142
147
  LOGGER.warning("New Columns: %s", new_columns)
143
148
  LOGGER.warning("Please Report")
144
149
 
145
- query = f"UPDATE {self.table} SET {db_value} WHERE {selection}"
146
- self._cursor.execute(query, selection_argument)
150
+ set_clause = ", ".join([f"{key} = ?" for key in full_data])
151
+ set_values = list(full_data.values())
152
+
153
+ if selection:
154
+ query = f"UPDATE {self.table} SET {set_clause} WHERE {selection}"
155
+ params = set_values + selection_argument
156
+ else:
157
+ query = f"UPDATE {self.table} SET {set_clause}"
158
+ params = set_values
159
+
160
+ self._cursor.execute(query, params)
147
161
  self._db.commit()
148
162
 
149
163
  except sqlite3.Error as err:
150
- error = QolsysSqlError({
151
- "table": self.table,
152
- "query": query,
153
- "columns": self._columns,
154
- "content_value": content_value,
155
- "selection": selection,
156
- "selection_argument": selection_argument,
157
- })
164
+ error = QolsysSqlError(
165
+ {
166
+ "table": self.table,
167
+ "query": query,
168
+ "columns": self._columns,
169
+ "content_value": content_value,
170
+ "selection": selection,
171
+ "selection_argument": selection_argument,
172
+ }
173
+ )
158
174
 
159
175
  if self._abort_on_error:
160
176
  raise error from err
161
177
 
162
- def delete(self, selection: str, selection_argument: str) -> None:
178
+ def delete(self, selection: str | None, selection_argument: list[str] | str | None) -> None:
163
179
  # selection: 'zone_id=?, parition_id=?'
164
180
  # Firmware 4.4.1: selection_argument: '[3,1]'
165
181
  # Firmware 4.6.1: selection_argument: ['3','1']
166
182
 
167
- # Selection Argument
168
- if(type(selection_argument) is not list):
169
- #Firmware 4.4.1, seletion_argument is sent as a string
183
+ # Firmware 4.4.1: seletion_argument is sent as a string and needs to be converted to an array
184
+ if type(selection_argument) is str:
170
185
  selection_argument = selection_argument.strip("[]")
171
186
  selection_argument = [item.strip() for item in selection_argument.split(",")]
172
187
 
188
+ if selection_argument is None:
189
+ selection_argument = []
190
+
173
191
  try:
174
- query = f"DELETE FROM {self.table} WHERE {selection}"
175
- self._cursor.execute(query, selection_argument)
192
+ if selection:
193
+ query = f"DELETE FROM {self.table} WHERE {selection}"
194
+
195
+ if "?" in selection:
196
+ # Query expects parameters → must pass the list
197
+ self._cursor.execute(query, selection_argument)
198
+ else:
199
+ # Query has no ? , do not pass arguments
200
+ self._cursor.execute(query)
201
+ else:
202
+ self.clear()
203
+
176
204
  self._db.commit()
177
205
 
178
206
  except sqlite3.Error as err:
179
- error = QolsysSqlError({
180
- "table": self.table,
181
- "query": query,
182
- "columns": self._columns,
183
- "selection": selection,
184
- "selection_argument": selection_argument,
185
- })
207
+ error = QolsysSqlError(
208
+ {
209
+ "table": self.table,
210
+ "query": query,
211
+ "columns": self._columns,
212
+ "selection": selection,
213
+ "selection_argument": selection_argument,
214
+ }
215
+ )
186
216
 
187
217
  if self._abort_on_error:
188
218
  raise error from err
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTableAlarmedSensor(QolsysTable):
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  super().__init__(db, cursor)
13
12
  self._uri = "content://com.qolsys.qolsysprovider.AlarmedSensorProvider/alarmedsensor"
@@ -15,7 +14,6 @@ class QolsysTableAlarmedSensor(QolsysTable):
15
14
  self._abort_on_error = True
16
15
  self._implemented = True
17
16
 
18
-
19
17
  self._columns = [
20
18
  "_id",
21
19
  "partition_id",
@@ -28,6 +26,8 @@ class QolsysTableAlarmedSensor(QolsysTable):
28
26
  "priority",
29
27
  "aseb_type",
30
28
  "alarm_time",
29
+ "version",
30
+ "opr",
31
31
  ]
32
32
 
33
33
  self._create_table()
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTableAutomation(QolsysTable):
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  super().__init__(db, cursor)
13
12
  self._uri = "content://com.qolsys.qolsysprovider.AutomationDeviceContentProvider/automation"
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTableCountryLocale(QolsysTable):
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  super().__init__(db, cursor)
13
12
  self._uri = "content://com.qolsys.qolsysprovider.CountryLocaleContentProvider/country_locale"
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTableDashboardMsgs(QolsysTable):
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  super().__init__(db, cursor)
13
12
  self._uri = "content://com.qolsys.qolsysprovider.DashboardMessagesContentProvider/dashboard_msgs"
@@ -15,7 +14,6 @@ class QolsysTableDashboardMsgs(QolsysTable):
15
14
  self._abort_on_error = False
16
15
  self._implemented = True
17
16
 
18
-
19
17
  self._columns = [
20
18
  "_id",
21
19
  "version",
@@ -29,6 +27,7 @@ class QolsysTableDashboardMsgs(QolsysTable):
29
27
  "end_time",
30
28
  "read",
31
29
  "mime_type",
30
+ "type",
32
31
  ]
33
32
 
34
33
  self._create_table()
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTableDimmerLight(QolsysTable):
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  super().__init__(db, cursor)
13
12
  self._uri = "content://com.qolsys.qolsysprovider.DimmerLightsContentProvider/dimmerlight"
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTableDoorLock(QolsysTable):
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  super().__init__(db, cursor)
13
12
  self._uri = "content://com.qolsys.qolsysprovider.DoorLocksContentProvider/doorlock"
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTableEuEvent(QolsysTable):
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  super().__init__(db, cursor)
13
12
  self._uri = "content://com.qolsys.qolsysprovider.EUEventContentProvider/eu_event"
@@ -15,7 +14,6 @@ class QolsysTableEuEvent(QolsysTable):
15
14
  self._abort_on_error = False
16
15
  self._implemented = True
17
16
 
18
-
19
17
  self._columns = [
20
18
  "_id",
21
19
  "version",
@@ -28,6 +26,7 @@ class QolsysTableEuEvent(QolsysTable):
28
26
  "time",
29
27
  "ack",
30
28
  "type",
29
+ "feature2",
31
30
  ]
32
31
 
33
32
  self._create_table()
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTableHeatMap(QolsysTable):
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  super().__init__(db, cursor)
13
12
  self._uri = "content://com.qolsys.qolsysprovider.HeatMapContentProvider/heat_map"
@@ -28,4 +27,3 @@ class QolsysTableHeatMap(QolsysTable):
28
27
  ]
29
28
 
30
29
  self._create_table()
31
-
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTableHistory(QolsysTable):
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  super().__init__(db, cursor)
13
12
  self._uri = "content://com.qolsys.qolsysprovider.HistoryContentProvider/history"
@@ -28,6 +27,10 @@ class QolsysTableHistory(QolsysTable):
28
27
  "feature1",
29
28
  "feature2",
30
29
  "device_id",
30
+ # "history_bulk_insert",
31
+ "Partition",
32
+ # "History_Device_Names_List",
33
+ # "History Bypass Event",
31
34
  ]
32
35
 
33
36
  self._create_table()
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
7
7
 
8
8
 
9
9
  class QolsysTableIqRemoteSettings(QolsysTable):
10
-
11
10
  def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
12
11
  super().__init__(db, cursor)
13
12
  self._uri = "content://com.qolsys.qolsysprovider.IQRemoteSettingsContentProvider/iqremotesettings"
@@ -27,4 +26,3 @@ class QolsysTableIqRemoteSettings(QolsysTable):
27
26
  ]
28
27
 
29
28
  self._create_table()
30
-