qolsys-controller 0.0.44__py3-none-any.whl → 0.0.62__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 (73) hide show
  1. qolsys_controller/controller.py +829 -20
  2. qolsys_controller/database/db.py +48 -29
  3. qolsys_controller/database/table.py +89 -60
  4. qolsys_controller/database/table_alarmedsensor.py +0 -2
  5. qolsys_controller/database/table_automation.py +0 -1
  6. qolsys_controller/database/table_country_locale.py +0 -1
  7. qolsys_controller/database/table_dashboard_msgs.py +1 -2
  8. qolsys_controller/database/table_dimmerlight.py +0 -1
  9. qolsys_controller/database/table_doorlock.py +0 -1
  10. qolsys_controller/database/table_eu_event.py +1 -2
  11. qolsys_controller/database/table_heat_map.py +0 -2
  12. qolsys_controller/database/table_history.py +4 -1
  13. qolsys_controller/database/table_iqremotesettings.py +0 -2
  14. qolsys_controller/database/table_iqrouter_network_config.py +0 -1
  15. qolsys_controller/database/table_iqrouter_user_device.py +0 -2
  16. qolsys_controller/database/table_master_slave.py +0 -1
  17. qolsys_controller/database/table_nest_device.py +0 -1
  18. qolsys_controller/database/table_output_rules.py +0 -1
  19. qolsys_controller/database/table_partition.py +0 -1
  20. qolsys_controller/database/table_pgm_outputs.py +0 -2
  21. qolsys_controller/database/table_powerg_device.py +0 -2
  22. qolsys_controller/database/table_qolsyssettings.py +0 -2
  23. qolsys_controller/database/table_scene.py +0 -2
  24. qolsys_controller/database/table_sensor.py +2 -2
  25. qolsys_controller/database/table_sensor_group.py +23 -0
  26. qolsys_controller/database/table_shades.py +0 -2
  27. qolsys_controller/database/table_smartsocket.py +0 -2
  28. qolsys_controller/database/table_state.py +0 -1
  29. qolsys_controller/database/table_tcc.py +0 -1
  30. qolsys_controller/database/table_thermostat.py +0 -1
  31. qolsys_controller/database/table_trouble_conditions.py +0 -2
  32. qolsys_controller/database/table_user.py +0 -2
  33. qolsys_controller/database/table_virtual_device.py +0 -2
  34. qolsys_controller/database/table_weather.py +0 -2
  35. qolsys_controller/database/table_zigbee_device.py +0 -1
  36. qolsys_controller/database/table_zwave_association_group.py +0 -1
  37. qolsys_controller/database/table_zwave_history.py +0 -1
  38. qolsys_controller/database/table_zwave_node.py +0 -1
  39. qolsys_controller/database/table_zwave_other.py +0 -1
  40. qolsys_controller/enum.py +37 -12
  41. qolsys_controller/enum_zwave.py +81 -36
  42. qolsys_controller/errors.py +9 -12
  43. qolsys_controller/mdns.py +7 -4
  44. qolsys_controller/mqtt_command.py +119 -0
  45. qolsys_controller/mqtt_command_queue.py +5 -4
  46. qolsys_controller/observable.py +2 -2
  47. qolsys_controller/panel.py +195 -151
  48. qolsys_controller/partition.py +129 -127
  49. qolsys_controller/pki.py +69 -97
  50. qolsys_controller/scene.py +30 -28
  51. qolsys_controller/settings.py +96 -50
  52. qolsys_controller/state.py +59 -34
  53. qolsys_controller/task_manager.py +8 -12
  54. qolsys_controller/users.py +25 -0
  55. qolsys_controller/utils_mqtt.py +8 -16
  56. qolsys_controller/weather.py +71 -0
  57. qolsys_controller/zone.py +242 -214
  58. qolsys_controller/zwave_device.py +108 -95
  59. qolsys_controller/zwave_dimmer.py +53 -50
  60. qolsys_controller/zwave_garagedoor.py +0 -1
  61. qolsys_controller/zwave_generic.py +2 -3
  62. qolsys_controller/zwave_lock.py +47 -44
  63. qolsys_controller/zwave_outlet.py +0 -1
  64. qolsys_controller/zwave_thermostat.py +112 -118
  65. qolsys_controller-0.0.62.dist-info/METADATA +89 -0
  66. qolsys_controller-0.0.62.dist-info/RECORD +69 -0
  67. {qolsys_controller-0.0.44.dist-info → qolsys_controller-0.0.62.dist-info}/WHEEL +1 -1
  68. qolsys_controller/plugin.py +0 -34
  69. qolsys_controller/plugin_c4.py +0 -17
  70. qolsys_controller/plugin_remote.py +0 -1298
  71. qolsys_controller-0.0.44.dist-info/METADATA +0 -93
  72. qolsys_controller-0.0.44.dist-info/RECORD +0 -68
  73. {qolsys_controller-0.0.44.dist-info → qolsys_controller-0.0.62.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,8 @@
1
- from hmac import new
1
+ from __future__ import annotations
2
+
2
3
  import json
3
4
  import logging
5
+ from typing import TYPE_CHECKING, Any
4
6
 
5
7
  from .database.db import QolsysDB
6
8
  from .enum import (
@@ -11,10 +13,9 @@ from .enum import (
11
13
  from .observable import QolsysObservable
12
14
  from .partition import QolsysPartition
13
15
  from .scene import QolsysScene
14
- from .settings import QolsysSettings
15
- from .state import QolsysState
16
+ from .users import QolsysUser
17
+ from .weather import QolsysForecast, QolsysWeather
16
18
  from .zone import QolsysZone
17
- from .zwave_device import QolsysZWaveDevice
18
19
  from .zwave_dimmer import QolsysDimmer
19
20
  from .zwave_generic import QolsysGeneric
20
21
  from .zwave_lock import QolsysLock
@@ -22,12 +23,14 @@ from .zwave_thermostat import QolsysThermostat
22
23
 
23
24
  LOGGER = logging.getLogger(__name__)
24
25
 
26
+ if TYPE_CHECKING:
27
+ from .controller import QolsysController
28
+ from .zwave_device import QolsysZWaveDevice
25
29
 
26
- class QolsysPanel(QolsysObservable):
27
- def __init__(self, settings: QolsysSettings, state: QolsysState) -> None:
28
30
 
29
- self._state = state
30
- self._settings = settings
31
+ class QolsysPanel(QolsysObservable):
32
+ def __init__(self, controller: QolsysController) -> None:
33
+ self._controller = controller
31
34
  self._db = QolsysDB()
32
35
 
33
36
  # Partition settings
@@ -37,73 +40,108 @@ class QolsysPanel(QolsysObservable):
37
40
  # Panel settings
38
41
  self.settings_panel_observer = QolsysObservable()
39
42
  self.settings_panel = [
40
- "PANEL_TAMPER_STATE", "AC_STATUS", "BATTERY_STATUS", "FAIL_TO_COMMUNICATE", "SECURE_ARMING", "AUTO_BYPASS",
41
- "AUTO_STAY", "AUTO_ARM_STAY", "AUTO_EXIT_EXTENSION", "FINAL_EXIT_DOOR_ARMING", "NO_ARM_LOW_BATTERY",
42
- "TEMPFORMAT", "LANGUAGE", "COUNTRY", "SYSTEM_TIME", "GSM_CONNECTION_STATUS", "GSM_SIGNAL_STRENGTH",
43
- "ANDROID_VERSION", "HARDWARE_VERSION", "TIMER_NORMAL_ENTRY_DELAY", "TIMER_NORMAL_EXIT_DELAY",
44
- "TIMER_LONG_ENTRY_DELAY", "TIMER_LONG_EXIT_DELAY", "ZWAVE_CONTROLLER", "ZWAVE_CARD", "POLICE_PANIC_ENABLED",
45
- "FIRE_PANIC_ENABLED", "AUXILIARY_PANIC_ENABLED", "NIGHTMODE_SETTINGS", "NIGHT_SETTINGS_STATE", "PARTITIONS",
46
- "SIX_DIGIT_USER_CODE", "SHOW_SECURITY_SENSORS", "SYSTEM_LOGGED_IN_USER", "PANEL_SCENES_SETTING", "CONTROL_4",
47
- "ZWAVE_FIRM_WARE_VERSION", "FINAL_EXIT_DOOR_ARMING", "NO_ARM_LOW_BATTERY", "MAC_ADDRESS",
43
+ "PANEL_TAMPER_STATE",
44
+ "AC_STATUS",
45
+ "BATTERY_STATUS",
46
+ "FAIL_TO_COMMUNICATE",
47
+ "SECURE_ARMING",
48
+ "AUTO_BYPASS",
49
+ "AUTO_STAY",
50
+ "AUTO_ARM_STAY",
51
+ "AUTO_EXIT_EXTENSION",
52
+ "FINAL_EXIT_DOOR_ARMING",
53
+ "NO_ARM_LOW_BATTERY",
54
+ "TEMPFORMAT",
55
+ "LANGUAGE",
56
+ "COUNTRY",
57
+ "SYSTEM_TIME",
58
+ "GSM_CONNECTION_STATUS",
59
+ "GSM_SIGNAL_STRENGTH",
60
+ "ANDROID_VERSION",
61
+ "HARDWARE_VERSION",
62
+ "TIMER_NORMAL_ENTRY_DELAY",
63
+ "TIMER_NORMAL_EXIT_DELAY",
64
+ "TIMER_LONG_ENTRY_DELAY",
65
+ "TIMER_LONG_EXIT_DELAY",
66
+ "ZWAVE_CONTROLLER",
67
+ "ZWAVE_CARD",
68
+ "POLICE_PANIC_ENABLED",
69
+ "FIRE_PANIC_ENABLED",
70
+ "AUXILIARY_PANIC_ENABLED",
71
+ "NIGHTMODE_SETTINGS",
72
+ "NIGHT_SETTINGS_STATE",
73
+ "PARTITIONS",
74
+ "SIX_DIGIT_USER_CODE",
75
+ "SHOW_SECURITY_SENSORS",
76
+ "SYSTEM_LOGGED_IN_USER",
77
+ "PANEL_SCENES_SETTING",
78
+ "CONTROL_4",
79
+ "ZWAVE_FIRM_WARE_VERSION",
80
+ "FINAL_EXIT_DOOR_ARMING",
81
+ "NO_ARM_LOW_BATTERY",
82
+ "MAC_ADDRESS",
48
83
  "LAST_UPDATE_IQ_REMOTE_PATCH_CKECKSUM_N",
49
84
  ]
50
85
 
51
- self._PANEL_TAMPER_STATE = ""
52
- self._AC_STATUS = ""
53
- self._BATTERY_STATUS = ""
54
- self._FAIL_TO_COMMUNICATE = ""
55
- self._SECURE_ARMING = ""
56
- self._AUTO_BYPASS = ""
57
- self._AUTO_STAY = ""
58
- self._AUTO_ARM_STAY = ""
59
- self._AUTO_EXIT_EXTENSION = ""
60
- self._FINAL_EXIT_DOOR_ARMING = ""
61
- self._NO_ARM_LOW_BATTERY = ""
62
- self._TEMPFORMAT = ""
63
- self._LANGUAGE = ""
64
- self._COUNTRY = ""
65
- self._SYSTEM_TIME = ""
66
- self._GSM_CONNECTION_STATUS = ""
67
- self._GSM_SIGNAL_STRENGTH = ""
68
- self._ANDROID_VERSION = ""
69
- self._HARDWARE_VERSION = ""
70
- self._TIMER_NORMAL_ENTRY_DELAY = ""
71
- self._TIMER_NORMAL_EXIT_DELAY = ""
72
- self._TIMER_LONG_ENTRY_DELAY = ""
73
- self._TIMER_LONG_EXIT_DELAY = ""
74
- self._ZWAVE_FIRM_WARE_VERSION = ""
75
- self._ZWAVE_CONTROLLER = ""
76
- self._ZWAVE_CARD = ""
77
- self._POLICE_PANIC_ENABLED = ""
78
- self._FIRE_PANIC_ENABLED = ""
79
- self._AUXILIARY_PANIC_ENABfLED = ""
80
- self._NIGHTMODE_SETTINGS = ""
81
- self._NIGHT_SETTINGS_STATE = ""
82
- self._PARTITIONS = ""
83
- self._SIX_DIGIT_USER_CODE = ""
84
- self._SHOW_SECURITY_SENSORS = ""
85
- self._CONTROL_4 = ""
86
- self._MAC_ADDRESS = ""
87
- self._SYSTEM_LOGGED_IN_USER = ""
88
- self._PANEL_SCENES_SETTING = ""
89
- self._LAST_UPDATE_IQ_REMOTE_PATCH_CKECKSUM_N = ""
90
-
91
- self._users = []
92
- self._unique_id = ""
93
-
94
- self._imei = ""
95
- self._product_type = ""
86
+ self._PANEL_TAMPER_STATE: str = ""
87
+ self._AC_STATUS: str = ""
88
+ self._BATTERY_STATUS: str = ""
89
+ self._FAIL_TO_COMMUNICATE: str = ""
90
+ self._SECURE_ARMING: str = ""
91
+ self._AUTO_BYPASS: str = ""
92
+ self._AUTO_STAY: str = ""
93
+ self._AUTO_ARM_STAY: str = ""
94
+ self._AUTO_EXIT_EXTENSION: str = ""
95
+ self._FINAL_EXIT_DOOR_ARMING: str = ""
96
+ self._NO_ARM_LOW_BATTERY: str = ""
97
+ self._TEMPFORMAT: str = ""
98
+ self._LANGUAGE: str = ""
99
+ self._COUNTRY: str = ""
100
+ self._SYSTEM_TIME: str = ""
101
+ self._GSM_CONNECTION_STATUS: str = ""
102
+ self._GSM_SIGNAL_STRENGTH: str = ""
103
+ self._ANDROID_VERSION: str = ""
104
+ self._HARDWARE_VERSION: str = ""
105
+ self._TIMER_NORMAL_ENTRY_DELAY: str = ""
106
+ self._TIMER_NORMAL_EXIT_DELAY: str = ""
107
+ self._TIMER_LONG_ENTRY_DELAY: str = ""
108
+ self._TIMER_LONG_EXIT_DELAY: str = ""
109
+ self._ZWAVE_FIRM_WARE_VERSION: str = ""
110
+ self._ZWAVE_CONTROLLER: str = ""
111
+ self._ZWAVE_CARD: str = ""
112
+ self._POLICE_PANIC_ENABLED: str = ""
113
+ self._FIRE_PANIC_ENABLED: str = ""
114
+ self._AUXILIARY_PANIC_ENABfLED: str = ""
115
+ self._NIGHTMODE_SETTINGS: str = ""
116
+ self._NIGHT_SETTINGS_STATE: str = ""
117
+ self._PARTITIONS: str = ""
118
+ self._SIX_DIGIT_USER_CODE: str = ""
119
+ self._SHOW_SECURITY_SENSORS: str = ""
120
+ self._CONTROL_4: str = ""
121
+ self._MAC_ADDRESS: str = ""
122
+ self._SYSTEM_LOGGED_IN_USER: str = ""
123
+ self._PANEL_SCENES_SETTING: str = ""
124
+ self._LAST_UPDATE_IQ_REMOTE_PATCH_CKECKSUM_N: str = ""
125
+
126
+ self._users: list[QolsysUser] = []
127
+ self._unique_id: str = ""
128
+
129
+ self._imei: str = ""
130
+ self._product_type: str = ""
96
131
 
97
132
  def read_users_file(self) -> bool:
98
133
  # Loading user_code data from users.conf file if exists
99
- if self._settings.users_file_path.is_file():
134
+ if self._controller.settings.users_file_path.is_file():
100
135
  try:
101
- path = self._settings.users_file_path
136
+ path = self._controller.settings.users_file_path
102
137
  with path.open("r", encoding="utf-8") as file:
103
138
  try:
104
139
  users = json.load(file)
105
140
  for user in users:
106
- self._users.append(user)
141
+ qolsys_user = QolsysUser()
142
+ qolsys_user.id = user.get("id")
143
+ qolsys_user.user_code = user.get("user_code")
144
+ self._users.append(qolsys_user)
107
145
 
108
146
  except json.JSONDecodeError:
109
147
  LOGGER.exception("users.conf file json error")
@@ -343,22 +381,21 @@ class QolsysPanel(QolsysObservable):
343
381
  self._PANEL_SCENES_SETTING = self.db.get_setting_panel("PANEL_SCENES_SETTING")
344
382
  return self.PANEL_SCENES_SETTING
345
383
 
346
- def load_database(self, database: dict) -> None:
384
+ def load_database(self, database: list[dict[str, Any]]) -> None:
347
385
  self.db.load_db(database)
348
- self._state.sync_partitions_data(self.get_partitions_from_db())
349
- self._state.sync_zones_data(self.get_zones_from_db())
350
- self._state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
351
- self._state.sync_scenes_data(self.get_scenes_from_db())
386
+ self._controller.state.sync_partitions_data(self.get_partitions_from_db())
387
+ self._controller.state.sync_zones_data(self.get_zones_from_db())
388
+ self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
389
+ self._controller.state.sync_scenes_data(self.get_scenes_from_db())
390
+ self._controller.state.sync_weather_data(self.get_weather_from_db())
352
391
 
353
392
  # Parse panel update to database
354
- def parse_iq2meid_message(self, data: dict) -> bool: # noqa: C901, PLR0912, PLR0915
355
-
393
+ def parse_iq2meid_message(self, data: dict[str, Any]) -> None: # noqa: C901, PLR0912, PLR0915
356
394
  eventName = data.get("eventName")
357
- dbOperation = data.get("dbOperation","")
395
+ dbOperation = data.get("dbOperation", "")
358
396
  uri = data.get("uri")
359
397
 
360
398
  match eventName:
361
-
362
399
  case "stopScreenCapture":
363
400
  pass
364
401
 
@@ -366,16 +403,13 @@ class QolsysPanel(QolsysObservable):
366
403
  LOGGER.info("Main Panel Disconnect")
367
404
 
368
405
  case "dbChanged":
369
-
370
406
  match dbOperation:
371
-
372
407
  case "update":
373
- content_values = data.get("contentValues")
408
+ content_values = data.get("contentValues", "")
374
409
  selection = data.get("selection")
375
410
  selection_argument = data.get("selectionArgs")
376
411
 
377
412
  match uri:
378
-
379
413
  # Update Settings Content Provider
380
414
  case self.db.table_qolsyssettings.uri:
381
415
  name = content_values.get("name", "")
@@ -391,7 +425,7 @@ class QolsysPanel(QolsysObservable):
391
425
  # Update Partition setting - Send notification if setting has changed
392
426
  if name in self.settings_partition:
393
427
  partition_id = content_values.get("partition_id", "")
394
- partition = self._state.partition(partition_id)
428
+ partition = self._controller.state.partition(partition_id)
395
429
  if partition is not None:
396
430
  match name:
397
431
  case "SYSTEM_STATUS":
@@ -407,7 +441,7 @@ class QolsysPanel(QolsysObservable):
407
441
  case self.db.table_sensor.uri:
408
442
  self.db.table_sensor.update(selection, selection_argument, content_values)
409
443
  zoneid = content_values.get("zoneid", "")
410
- zone = self._state.zone(zone_id=zoneid)
444
+ zone = self._controller.state.zone(zone_id=zoneid)
411
445
  if zone is not None:
412
446
  zone.update(content_values)
413
447
 
@@ -419,7 +453,7 @@ class QolsysPanel(QolsysObservable):
419
453
  self.db.table_state.update(selection, selection_argument, content_values)
420
454
 
421
455
  if name in self.state_partition:
422
- partition = self._state.partition(partition_id)
456
+ partition = self._controller.state.partition(partition_id)
423
457
  if partition is not None:
424
458
  match name:
425
459
  case "ALARM_STATE":
@@ -428,36 +462,32 @@ class QolsysPanel(QolsysObservable):
428
462
  # Update heat_map
429
463
  case self.db.table_heat_map.uri:
430
464
  self.db.table_heat_map.update(selection, selection_argument, content_values)
431
- # No action needed
432
465
 
433
466
  # Update master_slave
434
467
  case self.db.table_master_slave.uri:
435
468
  self.db.table_master_slave.update(selection, selection_argument, content_values)
436
- # No action needed
437
469
 
438
470
  # Update dashboard_msgs
439
471
  case self.db.table_dashboard_msgs.uri:
440
472
  self.db.table_dashboard_msgs.update(selection, selection_argument, content_values)
441
- # No action needed
442
473
 
443
474
  # Update PartitionContentProvider
444
475
  case self.db.table_partition.uri:
445
476
  self.db.table_partition.update(selection, selection_argument, content_values)
446
477
  partition_id = content_values.get("partition_id", "")
447
- partition = self._state.partition(partition_id)
478
+ partition = self._controller.state.partition(partition_id)
448
479
  if partition is not None:
449
480
  partition.update_partition(content_values)
450
481
 
451
482
  # Update History Content Provider
452
483
  case self.db.table_history.uri:
453
484
  self.db.table_history.update(selection, selection_argument, content_values)
454
- # No action needed
455
485
 
456
486
  # Update DimmerLightsContentProvider
457
487
  case self.db.table_dimmer.uri:
458
488
  self.db.table_dimmer.update(selection, selection_argument, content_values)
459
489
  node_id = content_values.get("node_id", "")
460
- node = self._state.zwave_device(node_id)
490
+ node = self._controller.state.zwave_device(node_id)
461
491
  if node is not None and isinstance(node, QolsysDimmer):
462
492
  node.update_dimmer(content_values)
463
493
 
@@ -465,7 +495,7 @@ class QolsysPanel(QolsysObservable):
465
495
  case self.db.table_thermostat.uri:
466
496
  self.db.table_thermostat.update(selection, selection_argument, content_values)
467
497
  node_id = content_values.get("node_id", "")
468
- node = self._state.zwave_device(node_id)
498
+ node = self._controller.state.zwave_device(node_id)
469
499
  if node is not None and isinstance(node, QolsysThermostat):
470
500
  node.update_thermostat(content_values)
471
501
 
@@ -473,7 +503,7 @@ class QolsysPanel(QolsysObservable):
473
503
  case self.db.table_doorlock.uri:
474
504
  self.db.table_doorlock.update(selection, selection_argument, content_values)
475
505
  node_id = content_values.get("node_id", "")
476
- node = self._state.zwave_device(node_id)
506
+ node = self._controller.state.zwave_device(node_id)
477
507
  if node is not None and isinstance(node, QolsysLock):
478
508
  node.update_lock(content_values)
479
509
 
@@ -481,19 +511,17 @@ class QolsysPanel(QolsysObservable):
481
511
  case self.db.table_zwave_node.uri:
482
512
  self.db.table_zwave_node.update(selection, selection_argument, content_values)
483
513
  node_id = content_values.get("node_id", "")
484
- node = self._state.zwave_device(node_id)
514
+ node = self._controller.state.zwave_device(node_id)
485
515
  if node is not None:
486
516
  node.update_base(content_values)
487
517
 
488
518
  # Update Z-Wave History Content Provier
489
519
  case self.db.table_zwave_history.uri:
490
520
  self.db.table_zwave_history.update(selection, selection_argument, content_values)
491
- # No action needed
492
521
 
493
522
  # Update AutomationDeviceContentProvider
494
523
  case self.db.table_automation.uri:
495
524
  self.db.table_automation.update(selection, selection_argument, content_values)
496
- # No action needed
497
525
 
498
526
  # Update Alarmed Sensor Content Provider
499
527
  case self.db.table_alarmedsensor.uri:
@@ -502,35 +530,40 @@ class QolsysPanel(QolsysObservable):
502
530
  # Update IQ Remote Settings Content Provider
503
531
  case self.db.table_iqremotesettings.uri:
504
532
  self.db.table_iqremotesettings.update(selection, selection_argument, content_values)
505
- # No action needed
506
533
 
507
534
  # Update Scene Content Provider
508
535
  case self.db.table_scene.uri:
509
536
  self.db.table_scene.update(selection, selection_argument, content_values)
510
537
  scene_id = content_values.get("scene_id", "")
511
- scene = self._state.scene(scene_id)
512
- if scene is not None and isinstance(node, QolsysScene):
538
+ scene = self._controller.state.scene(scene_id)
539
+ if scene is not None and isinstance(scene, QolsysScene):
513
540
  scene.update(content_values)
514
541
 
515
542
  # Update Trouble Conditions
516
543
  case self.db.table_trouble_conditions.uri:
517
- self.db.table_trouble_conditions.update(selection,selection_argument,content_values)
518
- # No action needed
544
+ self.db.table_trouble_conditions.update(selection, selection_argument, content_values)
519
545
 
520
546
  # Update EU_EVENT:
521
547
  case self.db.table_eu_event.uri:
522
- self.db.table_eu_event.update(selection,selection_argument,content_values)
523
- # No action needed
548
+ self.db.table_eu_event.update(selection, selection_argument, content_values)
524
549
 
525
550
  # Update PowerG Device
526
551
  case self.db.table_powerg_device.uri:
527
- self.db.table_powerg_device.update(selection,selection_argument,content_values)
552
+ self.db.table_powerg_device.update(selection, selection_argument, content_values)
528
553
  short_id = content_values.get("shortID", "")
529
- zone = self._state.zone_from_short_id(short_id)
554
+ zone = self._controller.state.zone_from_short_id(short_id)
530
555
  if zone is not None:
531
- LOGGER.debug("iq2meid updating powerg device for zoneid(%s):%s", zone.zone_id,content_values)
532
556
  zone.update_powerg(content_values)
533
557
 
558
+ # Update Weather
559
+ case self.db.table_weather.uri:
560
+ self.db.table_weather.update(selection, selection_argument, content_values)
561
+ self._controller.state.sync_weather_data(self.get_weather_from_db())
562
+
563
+ # Update Zwave Association Group
564
+ case self.db.table_zwave_association_goup.uri:
565
+ self.db.table_zwave_association_goup.update(selection, selection_argument, content_values)
566
+
534
567
  case _:
535
568
  LOGGER.debug("iq2meid updating unknow uri:%s", uri)
536
569
  LOGGER.debug(data)
@@ -540,87 +573,82 @@ class QolsysPanel(QolsysObservable):
540
573
  selection_argument = data.get("selectionArgs")
541
574
 
542
575
  match uri:
543
-
544
576
  case self.db.table_sensor.uri:
545
577
  self.db.table_sensor.delete(selection, selection_argument)
546
- self._state.sync_zones_data(self.get_zones_from_db())
547
- # Notify delete zone
578
+ self._controller.state.sync_zones_data(self.get_zones_from_db())
548
579
 
549
580
  case self.db.table_iqremotesettings.uri:
550
581
  self.db.table_iqremotesettings.delete(selection, selection_argument)
551
- # No action needed
552
582
 
553
583
  case self.db.table_state.uri:
554
584
  self.db.table_state.delete(selection, selection_argument)
555
- # No action needed
556
585
 
557
586
  case self.db.table_master_slave.uri:
558
587
  self.db.table_master_slave.delete(selection, selection_argument)
559
- # No action needed
560
588
 
561
589
  case self.db.table_qolsyssettings.uri:
562
590
  self.db.table_qolsyssettings.delete(selection, selection_argument)
563
- # No action needed
564
591
 
565
592
  case self.db.table_alarmedsensor.uri:
566
593
  self.db.table_alarmedsensor.delete(selection, selection_argument)
567
- self._state.sync_partitions_data(self.get_partitions_from_db())
594
+ self._controller.state.sync_partitions_data(self.get_partitions_from_db())
568
595
 
569
596
  case self.db.table_history.uri:
570
597
  self.db.table_history.delete(selection, selection_argument)
571
- # No action needed
572
598
 
573
599
  case self.db.table_zwave_history.uri:
574
600
  self.db.table_zwave_history.delete(selection, selection_argument)
575
- # No action needed
576
601
 
577
602
  case self.db.table_doorlock.uri:
578
603
  self.db.table_doorlock.delete(selection, selection_argument)
579
- self._state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
604
+ self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
580
605
 
581
606
  case self.db.table_dimmer.uri:
582
607
  self.db.table_dimmer.delete(selection, selection_argument)
583
- self._state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
608
+ self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
584
609
 
585
610
  case self.db.table_thermostat.uri:
586
611
  self.db.table_thermostat.delete(selection, selection_argument)
587
- self._state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
612
+ self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
588
613
 
589
614
  case self.db.table_zwave_node.uri:
590
615
  self.db.table_zwave_node.delete(selection, selection_argument)
591
- self._state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
616
+ self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
592
617
 
593
618
  case self.db.table_automation.uri:
594
619
  self.db.table_automation.delete(selection, selection_argument)
595
- # No action needed
596
620
 
597
621
  case self.db.table_partition.uri:
598
622
  self.db.table_partition.delete(selection, selection_argument)
599
- self._state.sync_partitions_data(self.get_partitions_from_db())
623
+ self._controller.state.sync_partitions_data(self.get_partitions_from_db())
600
624
 
601
625
  case self.db.table_user.uri:
602
626
  self.db.table_user.delete(selection, selection_argument)
603
- # No action needed
604
627
 
605
628
  case self.db.table_dashboard_msgs.uri:
606
629
  self.db.table_dashboard_msgs.delete(selection, selection_argument)
607
- # No action needed
608
630
 
609
631
  case self.db.table_eu_event.uri:
610
- self.db.table_eu_event.delete(selection,selection_argument)
632
+ self.db.table_eu_event.delete(selection, selection_argument)
611
633
 
612
634
  case self.db.table_powerg_device.uri:
613
- self.db.table_powerg_device.delete(selection,selection_argument)
635
+ self.db.table_powerg_device.delete(selection, selection_argument)
636
+
637
+ case self.db.table_weather.uri:
638
+ self.db.table_weather.delete(selection, selection_argument)
639
+ self._controller.state.sync_weather_data(self.get_weather_from_db())
640
+
641
+ case self.db.table_zwave_association_goup.uri:
642
+ self.db.table_zwave_association_goup.delete(selection, selection_argument)
614
643
 
615
644
  case _:
616
645
  LOGGER.debug("iq2meid deleting unknown uri:%s", uri)
617
646
  LOGGER.debug(data)
618
647
 
619
648
  case "insert":
620
- content_values = data.get("contentValues")
649
+ content_values = data.get("contentValues", {})
621
650
 
622
651
  match uri:
623
-
624
652
  # Inser State Content Provider
625
653
  case self.db.table_state.uri:
626
654
  self.db.table_state.insert(data=content_values)
@@ -629,16 +657,16 @@ class QolsysPanel(QolsysObservable):
629
657
  new_value = content_values.get("value", "")
630
658
  if name in self.state_partition:
631
659
  partition_id = content_values.get("partition_id", "")
632
- partition = self._state.partition(partition_id)
660
+ partition = self._controller.state.partition(partition_id)
633
661
  if partition is not None:
634
662
  match name:
635
663
  case "ALARM_STATE":
636
664
  partition.alarm_state = PartitionAlarmState(new_value)
637
665
 
638
666
  # Inser Partition Content Provider
639
- case self.db.table_partition:
667
+ case self.db.table_partition.uri:
640
668
  self.db.table_partition.insert(data=content_values)
641
- self._state.sync_partitions_data(self.get_partitions_from_db())
669
+ self._controller.state.sync_partitions_data(self.get_partitions_from_db())
642
670
 
643
671
  # Insert Settings Content Provider
644
672
  case self.db.table_qolsyssettings.uri:
@@ -649,7 +677,7 @@ class QolsysPanel(QolsysObservable):
649
677
  new_value = content_values.get("value", "")
650
678
  if name in self.settings_partition:
651
679
  partition_id = content_values.get("partition_id", "")
652
- partition = self._state.partition(partition_id)
680
+ partition = self._controller.state.partition(partition_id)
653
681
  if partition is not None:
654
682
  match name:
655
683
  case "SYSTEM_STATUS":
@@ -679,62 +707,56 @@ class QolsysPanel(QolsysObservable):
679
707
  # Sensor Content Provider
680
708
  case self.db.table_sensor.uri:
681
709
  self.db.table_sensor.insert(data=content_values)
682
- self._state.sync_zones_data(self.get_zones_from_db())
710
+ self._controller.state.sync_zones_data(self.get_zones_from_db())
683
711
 
684
712
  # Door Lock Content Provider
685
713
  case self.db.table_doorlock.uri:
686
714
  self.db.table_doorlock.insert(data=content_values)
687
- self._state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
715
+ self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
688
716
 
689
717
  # Dimmer Content Provider
690
718
  case self.db.table_dimmer.uri:
691
719
  self.db.table_dimmer.insert(data=content_values)
692
- self._state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
720
+ self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
693
721
 
694
722
  # Thermostat Content Provider
695
723
  case self.db.table_thermostat.uri:
696
724
  self.db.table_thermostat.insert(data=content_values)
697
- self._state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
725
+ self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
698
726
 
699
727
  # ZWave Node Content Provider
700
728
  case self.db.table_zwave_node.uri:
701
729
  self.db.table_zwave_node.insert(data=content_values)
702
- self._state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
730
+ self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
703
731
 
704
732
  # HistoryContentProvider
705
733
  case self.db.table_history.uri:
706
734
  self.db.table_history.insert(data=content_values)
707
- # No action needed
708
735
 
709
736
  # AlarmedSensorProvider
710
737
  case self.db.table_alarmedsensor.uri:
711
-
712
738
  partition_id = content_values.get("partition_id", "")
713
739
  self.db.table_alarmedsensor.insert(data=content_values)
714
740
 
715
- partition = self._state.partition(partition_id)
741
+ partition = self._controller.state.partition(partition_id)
716
742
  if partition is not None:
717
743
  partition.append_alarm_type([PartitionAlarmType(content_values.get("sgroup", ""))])
718
744
 
719
745
  # IQRemoteSettingsProvider
720
746
  case self.db.table_iqremotesettings.uri:
721
747
  self.db.table_iqremotesettings.insert(data=content_values)
722
- # No action needed
723
748
 
724
749
  # HeatMapContentProvider
725
750
  case self.db.table_heat_map.uri:
726
751
  self.db.table_heat_map.insert(data=content_values)
727
- # No action needed
728
752
 
729
753
  # ZDeviceHistoryContentProvider
730
754
  case self.db.table_zwave_history.uri:
731
755
  self.db.table_zwave_history.insert(data=content_values)
732
- # No action needed
733
756
 
734
757
  # Dashboard Message Content Provider
735
758
  case self.db.table_dashboard_msgs.uri:
736
759
  self.db.table_dashboard_msgs.insert(data=content_values)
737
- # No action needed
738
760
 
739
761
  # EU_EVENT
740
762
  case self.db.table_eu_event.uri:
@@ -744,6 +766,14 @@ class QolsysPanel(QolsysObservable):
744
766
  case self.db.table_powerg_device.uri:
745
767
  self.db.table_powerg_device.insert(data=content_values)
746
768
 
769
+ # Weather
770
+ case self.db.table_weather.uri:
771
+ self.db.table_weather.insert(data=content_values)
772
+ self._controller.state.sync_weather_data(self.get_weather_from_db())
773
+
774
+ case self.db.table_zwave_association_goup.uri:
775
+ self.db.table_zwave_association_goup.insert(data=content_values)
776
+
747
777
  case _:
748
778
  LOGGER.debug("iq2meid inserting unknow uri:%s", uri)
749
779
  LOGGER.debug(data)
@@ -757,21 +787,20 @@ class QolsysPanel(QolsysObservable):
757
787
 
758
788
  def check_user(self, user_code: str) -> int:
759
789
  for user in self._users:
760
- if user["user_code"] == user_code:
761
- return user["id"]
790
+ if user.user_code == user_code:
791
+ return user.id
762
792
 
763
793
  # No valid user code found
764
794
  return -1
765
795
 
766
796
  def get_zwave_devices_from_db(self) -> list[QolsysZWaveDevice]:
767
- devices = []
797
+ devices: list[QolsysZWaveDevice] = []
768
798
  devices_list = self.db.get_zwave_devices()
769
799
  dimmers_list = self.db.get_dimmers()
770
800
  thermostats_list = self.db.get_thermostats()
771
801
  locks_list = self.db.get_locks()
772
802
 
773
803
  for device in devices_list:
774
-
775
804
  device_added = False
776
805
 
777
806
  zwave_node_id = device.get("node_id", "")
@@ -821,7 +850,7 @@ class QolsysPanel(QolsysObservable):
821
850
 
822
851
  def get_scenes_from_db(self) -> list[QolsysScene]:
823
852
  scenes = []
824
- scenes_list: list[dict] = self.db.get_scenes()
853
+ scenes_list: list[dict[str, str]] = self.db.get_scenes()
825
854
 
826
855
  # Create scenes array
827
856
  for scene_info in scenes_list:
@@ -829,17 +858,30 @@ class QolsysPanel(QolsysObservable):
829
858
 
830
859
  return scenes
831
860
 
861
+ def get_weather_from_db(self) -> QolsysWeather:
862
+ weather = QolsysWeather()
863
+ forecast_dic_list: list[dict[str, str]] = self.db.get_weather()
864
+
865
+ forecast_obj_list = []
866
+ for forecast in forecast_dic_list:
867
+ forecast_obj_list.append(QolsysForecast(forecast))
868
+
869
+ # Create weather array
870
+ weather.update(forecast_obj_list)
871
+
872
+ return weather
873
+
832
874
  def get_zones_from_db(self) -> list[QolsysZone]:
833
875
  zones = []
834
- zones_list: list[dict] = self.db.get_zones()
876
+ zones_list: list[dict[str, str]] = self.db.get_zones()
835
877
 
836
878
  # Create sensors array
837
879
  for zone_info in zones_list:
838
- new_zone = QolsysZone(zone_info,self._settings)
880
+ new_zone = QolsysZone(zone_info, self._controller.settings)
839
881
 
840
882
  if new_zone.current_capability == "POWERG":
841
883
  LOGGER.debug("Loading PowerG device info for zone %s", new_zone.zone_id)
842
- powerg_dict = self.db.get_powerg(short_id= new_zone.shortID)
884
+ powerg_dict = self.db.get_powerg(short_id=new_zone.shortID)
843
885
  LOGGER.debug("PowerG device info: %s", powerg_dict)
844
886
  if powerg_dict is not None:
845
887
  new_zone.update_powerg(powerg_dict)
@@ -849,13 +891,11 @@ class QolsysPanel(QolsysObservable):
849
891
  return zones
850
892
 
851
893
  def get_partitions_from_db(self) -> list[QolsysPartition]:
852
-
853
894
  partitions = []
854
- partition_list: list[dict] = self.db.get_partitions()
895
+ partition_list: list[dict[str, str]] = self.db.get_partitions()
855
896
 
856
897
  # Create partitions array
857
898
  for partition_dict in partition_list:
858
-
859
899
  partition_id = partition_dict["partition_id"]
860
900
 
861
901
  settings_dict = {
@@ -921,4 +961,8 @@ class QolsysPanel(QolsysObservable):
921
961
 
922
962
  LOGGER.debug("Users list:")
923
963
  for user in self._users:
924
- LOGGER.debug("User: %s", user["id"])
964
+ LOGGER.debug("User: %s", user.id)
965
+
966
+ LOGGER.debug("*** Plugin Information ***")
967
+ LOGGER.debug("Motion Delay Enabled: %s", self._controller.settings.motion_sensor_delay)
968
+ LOGGER.debug("Motion Delay Value: %s", self._controller.settings.motion_sensor_delay_sec)