qolsys-controller 0.0.40__py3-none-any.whl → 0.0.51__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of qolsys-controller might be problematic. Click here for more details.
- qolsys_controller/controller.py +19 -7
- qolsys_controller/database/db.py +31 -0
- qolsys_controller/database/table.py +16 -1
- qolsys_controller/database/table_powerg_device.py +1 -1
- qolsys_controller/enum.py +0 -1
- qolsys_controller/enum_zwave.py +0 -1
- qolsys_controller/mdns.py +8 -3
- qolsys_controller/panel.py +116 -48
- qolsys_controller/partition.py +1 -1
- qolsys_controller/plugin.py +10 -20
- qolsys_controller/plugin_c4.py +1 -1
- qolsys_controller/plugin_remote.py +110 -115
- qolsys_controller/settings.py +24 -15
- qolsys_controller/state.py +43 -7
- qolsys_controller/weather.py +74 -0
- qolsys_controller/zone.py +120 -10
- {qolsys_controller-0.0.40.dist-info → qolsys_controller-0.0.51.dist-info}/METADATA +1 -1
- {qolsys_controller-0.0.40.dist-info → qolsys_controller-0.0.51.dist-info}/RECORD +20 -19
- {qolsys_controller-0.0.40.dist-info → qolsys_controller-0.0.51.dist-info}/WHEEL +0 -0
- {qolsys_controller-0.0.40.dist-info → qolsys_controller-0.0.51.dist-info}/licenses/LICENSE +0 -0
qolsys_controller/controller.py
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
2
4
|
import logging
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from qolsys_controller.plugin import QolsysPlugin
|
|
3
8
|
|
|
4
9
|
from .panel import QolsysPanel
|
|
5
10
|
from .plugin_c4 import QolsysPluginC4
|
|
@@ -9,20 +14,27 @@ from .state import QolsysState
|
|
|
9
14
|
|
|
10
15
|
LOGGER = logging.getLogger(__name__)
|
|
11
16
|
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from .plugin import QolsysPlugin
|
|
19
|
+
|
|
12
20
|
class QolsysController:
|
|
13
21
|
|
|
14
22
|
def __init__(self) -> None:
|
|
15
23
|
|
|
16
24
|
# QolsysController Information
|
|
17
|
-
self.
|
|
18
|
-
self._state = QolsysState()
|
|
19
|
-
self._settings = QolsysSettings()
|
|
20
|
-
self._panel = QolsysPanel(
|
|
25
|
+
self._plugin: QolsysPlugin | None = None
|
|
26
|
+
self._state = QolsysState(self)
|
|
27
|
+
self._settings = QolsysSettings(self)
|
|
28
|
+
self._panel = QolsysPanel(self)
|
|
21
29
|
|
|
22
30
|
@property
|
|
23
31
|
def state(self) -> QolsysState:
|
|
24
32
|
return self._state
|
|
25
33
|
|
|
34
|
+
@property
|
|
35
|
+
def plugin(self) -> QolsysPlugin:
|
|
36
|
+
return self._plugin
|
|
37
|
+
|
|
26
38
|
@property
|
|
27
39
|
def panel(self) -> QolsysPanel:
|
|
28
40
|
return self._panel
|
|
@@ -37,13 +49,13 @@ class QolsysController:
|
|
|
37
49
|
|
|
38
50
|
case "c4":
|
|
39
51
|
LOGGER.debug("C4 Plugin Selected")
|
|
40
|
-
self.
|
|
52
|
+
self._plugin = QolsysPluginC4(self)
|
|
41
53
|
return
|
|
42
54
|
|
|
43
55
|
case "remote":
|
|
44
56
|
LOGGER.debug("Remote Plugin Selected")
|
|
45
|
-
self.
|
|
57
|
+
self._plugin = QolsysPluginRemote(self)
|
|
46
58
|
return
|
|
47
59
|
|
|
48
60
|
case _:
|
|
49
|
-
LOGGER.
|
|
61
|
+
LOGGER.error("Unknow Plugin Selected")
|
qolsys_controller/database/db.py
CHANGED
|
@@ -237,6 +237,37 @@ class QolsysDB:
|
|
|
237
237
|
|
|
238
238
|
return zones
|
|
239
239
|
|
|
240
|
+
def get_weather(self) -> list[dict]:
|
|
241
|
+
self.cursor.execute(f"SELECT * FROM {self.table_weather.table} ORDER BY _id")
|
|
242
|
+
self.db.commit()
|
|
243
|
+
|
|
244
|
+
weather_list = []
|
|
245
|
+
columns = [description[0] for description in self.cursor.description]
|
|
246
|
+
for row in self.cursor.fetchall():
|
|
247
|
+
row_dict = dict(zip(columns, row, strict=True))
|
|
248
|
+
weather_list.append(row_dict)
|
|
249
|
+
|
|
250
|
+
return weather_list
|
|
251
|
+
|
|
252
|
+
def get_powerg(self, short_id: str) -> dict:
|
|
253
|
+
try:
|
|
254
|
+
self.cursor.execute(f"SELECT * FROM {self.table_powerg_device.table} WHERE shortID = ?",(short_id,))
|
|
255
|
+
self.db.commit()
|
|
256
|
+
|
|
257
|
+
row = self.cursor.fetchone()
|
|
258
|
+
|
|
259
|
+
if row is None:
|
|
260
|
+
LOGGER.debug("%s value not found", short_id)
|
|
261
|
+
return None
|
|
262
|
+
|
|
263
|
+
columns = [description[0] for description in self.cursor.description]
|
|
264
|
+
return dict(zip(columns, row, strict=True))
|
|
265
|
+
|
|
266
|
+
except sqlite3.Error:
|
|
267
|
+
LOGGER.exception("Error getting PowerG device info for shortID %s", short_id)
|
|
268
|
+
return None
|
|
269
|
+
|
|
270
|
+
|
|
240
271
|
def get_setting_panel(self, setting: str) -> str:
|
|
241
272
|
self.cursor.execute(f"""SELECT value FROM {self.table_qolsyssettings.table}
|
|
242
273
|
WHERE name = ? and partition_id = ? """, (setting, "0"))
|
|
@@ -68,6 +68,7 @@ class QolsysTable:
|
|
|
68
68
|
raise error from err
|
|
69
69
|
|
|
70
70
|
def insert(self, data: dict) -> None:
|
|
71
|
+
|
|
71
72
|
try:
|
|
72
73
|
if not self._implemented and data is not None:
|
|
73
74
|
LOGGER.warning("New Table format: %s", self.uri)
|
|
@@ -92,6 +93,7 @@ class QolsysTable:
|
|
|
92
93
|
|
|
93
94
|
col_str = ", ".join(full_data.keys())
|
|
94
95
|
placeholder_str = ", ".join([f":{key}" for key in full_data])
|
|
96
|
+
|
|
95
97
|
query = f"INSERT OR IGNORE INTO {self.table} ({col_str}) VALUES ({placeholder_str})"
|
|
96
98
|
self._cursor.execute(query, full_data)
|
|
97
99
|
self._db.commit()
|
|
@@ -112,9 +114,14 @@ class QolsysTable:
|
|
|
112
114
|
# selection_argument:
|
|
113
115
|
# Firmware 4.4.1: selection_argument: '[3,1]'
|
|
114
116
|
# Firmware 4.6.1: selection_argument: ['3','1']
|
|
115
|
-
|
|
116
117
|
# contentValues:{"partition_id":"0","sensorgroup":"safetymotion","sensorstatus":"Idle"}"
|
|
117
118
|
|
|
119
|
+
if selection_argument == "":
|
|
120
|
+
LOGGER.debug("Update called with empty selection_argument")
|
|
121
|
+
LOGGER.debug("Table: %s", self.table)
|
|
122
|
+
LOGGER.debug("Selection: %s", selection)
|
|
123
|
+
LOGGER.debug("selection_argument: %s", selection_argument)
|
|
124
|
+
return
|
|
118
125
|
|
|
119
126
|
# Selection Argument
|
|
120
127
|
# Panel send selection_argument as list in Firmware 4.6.1
|
|
@@ -164,6 +171,14 @@ class QolsysTable:
|
|
|
164
171
|
# Firmware 4.4.1: selection_argument: '[3,1]'
|
|
165
172
|
# Firmware 4.6.1: selection_argument: ['3','1']
|
|
166
173
|
|
|
174
|
+
|
|
175
|
+
if selection_argument == "":
|
|
176
|
+
LOGGER.debug("Delete called with empty selection_argument")
|
|
177
|
+
LOGGER.debug("Table: %s", self.table)
|
|
178
|
+
LOGGER.debug("Selection: %s", selection)
|
|
179
|
+
LOGGER.debug("selection_argument: %s", selection_argument)
|
|
180
|
+
return
|
|
181
|
+
|
|
167
182
|
# Selection Argument
|
|
168
183
|
if(type(selection_argument) is not list):
|
|
169
184
|
#Firmware 4.4.1, seletion_argument is sent as a string
|
|
@@ -13,7 +13,7 @@ class QolsysTablePowerGDevice(QolsysTable):
|
|
|
13
13
|
self._uri = "content://com.qolsys.qolsysprovider.PowerGDeviceContentProvider/powerg_device"
|
|
14
14
|
self._table = "powerg_device"
|
|
15
15
|
self._abort_on_error = False
|
|
16
|
-
self._implemented =
|
|
16
|
+
self._implemented = True
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
self._columns = [
|
qolsys_controller/enum.py
CHANGED
qolsys_controller/enum_zwave.py
CHANGED
qolsys_controller/mdns.py
CHANGED
|
@@ -6,9 +6,14 @@ from zeroconf.asyncio import AsyncZeroconf
|
|
|
6
6
|
|
|
7
7
|
class QolsysMDNS:
|
|
8
8
|
|
|
9
|
-
def __init__(self, ip: str, port: int) -> None:
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
def __init__(self, ip: str, port: int, external_zero_conf: AsyncZeroconf | None = None) -> None:
|
|
10
|
+
|
|
11
|
+
# Add possible external zeroconf instance provided by Home Assistant by example
|
|
12
|
+
# If no external instance is provided, create our own
|
|
13
|
+
if external_zero_conf:
|
|
14
|
+
self.azc = external_zero_conf
|
|
15
|
+
else:
|
|
16
|
+
self.azc = AsyncZeroconf()
|
|
12
17
|
|
|
13
18
|
self.mdns_info = ServiceInfo(
|
|
14
19
|
"_http._tcp.local.",
|
qolsys_controller/panel.py
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import json
|
|
2
4
|
import logging
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
3
6
|
|
|
4
7
|
from .database.db import QolsysDB
|
|
5
8
|
from .enum import (
|
|
@@ -10,10 +13,8 @@ from .enum import (
|
|
|
10
13
|
from .observable import QolsysObservable
|
|
11
14
|
from .partition import QolsysPartition
|
|
12
15
|
from .scene import QolsysScene
|
|
13
|
-
from .
|
|
14
|
-
from .state import QolsysState
|
|
16
|
+
from .weather import QolsysForecast, QolsysWeather
|
|
15
17
|
from .zone import QolsysZone
|
|
16
|
-
from .zwave_device import QolsysZWaveDevice
|
|
17
18
|
from .zwave_dimmer import QolsysDimmer
|
|
18
19
|
from .zwave_generic import QolsysGeneric
|
|
19
20
|
from .zwave_lock import QolsysLock
|
|
@@ -21,12 +22,15 @@ from .zwave_thermostat import QolsysThermostat
|
|
|
21
22
|
|
|
22
23
|
LOGGER = logging.getLogger(__name__)
|
|
23
24
|
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from .controller import QolsysController
|
|
27
|
+
from .zwave_device import QolsysZWaveDevice
|
|
28
|
+
|
|
24
29
|
|
|
25
30
|
class QolsysPanel(QolsysObservable):
|
|
26
|
-
def __init__(self,
|
|
31
|
+
def __init__(self, controller: QolsysController) -> None:
|
|
27
32
|
|
|
28
|
-
self.
|
|
29
|
-
self._settings = settings
|
|
33
|
+
self._controller = controller
|
|
30
34
|
self._db = QolsysDB()
|
|
31
35
|
|
|
32
36
|
# Partition settings
|
|
@@ -95,9 +99,9 @@ class QolsysPanel(QolsysObservable):
|
|
|
95
99
|
|
|
96
100
|
def read_users_file(self) -> bool:
|
|
97
101
|
# Loading user_code data from users.conf file if exists
|
|
98
|
-
if self.
|
|
102
|
+
if self._controller.settings.users_file_path.is_file():
|
|
99
103
|
try:
|
|
100
|
-
path = self.
|
|
104
|
+
path = self._controller.settings.users_file_path
|
|
101
105
|
with path.open("r", encoding="utf-8") as file:
|
|
102
106
|
try:
|
|
103
107
|
users = json.load(file)
|
|
@@ -344,10 +348,12 @@ class QolsysPanel(QolsysObservable):
|
|
|
344
348
|
|
|
345
349
|
def load_database(self, database: dict) -> None:
|
|
346
350
|
self.db.load_db(database)
|
|
347
|
-
self.
|
|
348
|
-
self.
|
|
349
|
-
self.
|
|
350
|
-
self.
|
|
351
|
+
self._controller.state.sync_partitions_data(self.get_partitions_from_db())
|
|
352
|
+
self._controller.state.sync_zones_data(self.get_zones_from_db())
|
|
353
|
+
self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
|
|
354
|
+
self._controller.state.sync_scenes_data(self.get_scenes_from_db())
|
|
355
|
+
self._controller.state.sync_weather_data(self.get_weather_from_db())
|
|
356
|
+
|
|
351
357
|
|
|
352
358
|
# Parse panel update to database
|
|
353
359
|
def parse_iq2meid_message(self, data: dict) -> bool: # noqa: C901, PLR0912, PLR0915
|
|
@@ -369,9 +375,13 @@ class QolsysPanel(QolsysObservable):
|
|
|
369
375
|
match dbOperation:
|
|
370
376
|
|
|
371
377
|
case "update":
|
|
372
|
-
content_values = data.get("contentValues")
|
|
373
|
-
selection = data.get("selection")
|
|
374
|
-
selection_argument = data.get("selectionArgs")
|
|
378
|
+
content_values = data.get("contentValues","")
|
|
379
|
+
selection = data.get("selection","")
|
|
380
|
+
selection_argument = data.get("selectionArgs","")
|
|
381
|
+
|
|
382
|
+
if selection_argument == "" or selection == "":
|
|
383
|
+
LOGGER.debug("iq2meid invalid update selection or selectionArgs")
|
|
384
|
+
LOGGER.debug("data:%s", data)
|
|
375
385
|
|
|
376
386
|
match uri:
|
|
377
387
|
|
|
@@ -390,7 +400,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
390
400
|
# Update Partition setting - Send notification if setting has changed
|
|
391
401
|
if name in self.settings_partition:
|
|
392
402
|
partition_id = content_values.get("partition_id", "")
|
|
393
|
-
partition = self.
|
|
403
|
+
partition = self._controller.state.partition(partition_id)
|
|
394
404
|
if partition is not None:
|
|
395
405
|
match name:
|
|
396
406
|
case "SYSTEM_STATUS":
|
|
@@ -406,7 +416,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
406
416
|
case self.db.table_sensor.uri:
|
|
407
417
|
self.db.table_sensor.update(selection, selection_argument, content_values)
|
|
408
418
|
zoneid = content_values.get("zoneid", "")
|
|
409
|
-
zone = self.
|
|
419
|
+
zone = self._controller.state.zone(zone_id=zoneid)
|
|
410
420
|
if zone is not None:
|
|
411
421
|
zone.update(content_values)
|
|
412
422
|
|
|
@@ -418,7 +428,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
418
428
|
self.db.table_state.update(selection, selection_argument, content_values)
|
|
419
429
|
|
|
420
430
|
if name in self.state_partition:
|
|
421
|
-
partition = self.
|
|
431
|
+
partition = self._controller.state.partition(partition_id)
|
|
422
432
|
if partition is not None:
|
|
423
433
|
match name:
|
|
424
434
|
case "ALARM_STATE":
|
|
@@ -443,7 +453,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
443
453
|
case self.db.table_partition.uri:
|
|
444
454
|
self.db.table_partition.update(selection, selection_argument, content_values)
|
|
445
455
|
partition_id = content_values.get("partition_id", "")
|
|
446
|
-
partition = self.
|
|
456
|
+
partition = self._controller.state.partition(partition_id)
|
|
447
457
|
if partition is not None:
|
|
448
458
|
partition.update_partition(content_values)
|
|
449
459
|
|
|
@@ -456,7 +466,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
456
466
|
case self.db.table_dimmer.uri:
|
|
457
467
|
self.db.table_dimmer.update(selection, selection_argument, content_values)
|
|
458
468
|
node_id = content_values.get("node_id", "")
|
|
459
|
-
node = self.
|
|
469
|
+
node = self._controller.state.zwave_device(node_id)
|
|
460
470
|
if node is not None and isinstance(node, QolsysDimmer):
|
|
461
471
|
node.update_dimmer(content_values)
|
|
462
472
|
|
|
@@ -464,7 +474,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
464
474
|
case self.db.table_thermostat.uri:
|
|
465
475
|
self.db.table_thermostat.update(selection, selection_argument, content_values)
|
|
466
476
|
node_id = content_values.get("node_id", "")
|
|
467
|
-
node = self.
|
|
477
|
+
node = self._controller.state.zwave_device(node_id)
|
|
468
478
|
if node is not None and isinstance(node, QolsysThermostat):
|
|
469
479
|
node.update_thermostat(content_values)
|
|
470
480
|
|
|
@@ -472,7 +482,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
472
482
|
case self.db.table_doorlock.uri:
|
|
473
483
|
self.db.table_doorlock.update(selection, selection_argument, content_values)
|
|
474
484
|
node_id = content_values.get("node_id", "")
|
|
475
|
-
node = self.
|
|
485
|
+
node = self._controller.state.zwave_device(node_id)
|
|
476
486
|
if node is not None and isinstance(node, QolsysLock):
|
|
477
487
|
node.update_lock(content_values)
|
|
478
488
|
|
|
@@ -480,7 +490,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
480
490
|
case self.db.table_zwave_node.uri:
|
|
481
491
|
self.db.table_zwave_node.update(selection, selection_argument, content_values)
|
|
482
492
|
node_id = content_values.get("node_id", "")
|
|
483
|
-
node = self.
|
|
493
|
+
node = self._controller.state.zwave_device(node_id)
|
|
484
494
|
if node is not None:
|
|
485
495
|
node.update_base(content_values)
|
|
486
496
|
|
|
@@ -507,35 +517,51 @@ class QolsysPanel(QolsysObservable):
|
|
|
507
517
|
case self.db.table_scene.uri:
|
|
508
518
|
self.db.table_scene.update(selection, selection_argument, content_values)
|
|
509
519
|
scene_id = content_values.get("scene_id", "")
|
|
510
|
-
scene = self.
|
|
520
|
+
scene = self._controller.state.scene(scene_id)
|
|
511
521
|
if scene is not None and isinstance(node, QolsysScene):
|
|
512
522
|
scene.update(content_values)
|
|
513
523
|
|
|
514
524
|
# Update Trouble Conditions
|
|
515
|
-
case self.db.table_trouble_conditions:
|
|
525
|
+
case self.db.table_trouble_conditions.uri:
|
|
516
526
|
self.db.table_trouble_conditions.update(selection,selection_argument,content_values)
|
|
517
527
|
# No action needed
|
|
518
528
|
|
|
519
529
|
# Update EU_EVENT:
|
|
520
|
-
case self.db.table_eu_event:
|
|
530
|
+
case self.db.table_eu_event.uri:
|
|
521
531
|
self.db.table_eu_event.update(selection,selection_argument,content_values)
|
|
522
532
|
# No action needed
|
|
523
533
|
|
|
534
|
+
# Update PowerG Device
|
|
535
|
+
case self.db.table_powerg_device.uri:
|
|
536
|
+
self.db.table_powerg_device.update(selection,selection_argument,content_values)
|
|
537
|
+
short_id = content_values.get("shortID", "")
|
|
538
|
+
zone = self._controller.state.zone_from_short_id(short_id)
|
|
539
|
+
if zone is not None:
|
|
540
|
+
LOGGER.debug("iq2meid updating powerg device for zoneid(%s):%s", zone.zone_id,content_values)
|
|
541
|
+
zone.update_powerg(content_values)
|
|
524
542
|
|
|
543
|
+
# Update Weather
|
|
544
|
+
case self.db.table_weather.uri:
|
|
545
|
+
self.db.table_weather.update(selection,selection_argument,content_values)
|
|
546
|
+
self._controller.state.sync_weather_data(self.get_weather_from_db())
|
|
525
547
|
|
|
526
548
|
case _:
|
|
527
549
|
LOGGER.debug("iq2meid updating unknow uri:%s", uri)
|
|
528
550
|
LOGGER.debug(data)
|
|
529
551
|
|
|
530
552
|
case "delete":
|
|
531
|
-
selection = data.get("selection")
|
|
532
|
-
selection_argument = data.get("selectionArgs")
|
|
553
|
+
selection = data.get("selection","")
|
|
554
|
+
selection_argument = data.get("selectionArgs","")
|
|
555
|
+
|
|
556
|
+
if selection_argument == "" or selection == "":
|
|
557
|
+
LOGGER.debug("iq2meid invalid delete selection or selectionArgs")
|
|
558
|
+
LOGGER.debug("data:%s", data)
|
|
533
559
|
|
|
534
560
|
match uri:
|
|
535
561
|
|
|
536
562
|
case self.db.table_sensor.uri:
|
|
537
563
|
self.db.table_sensor.delete(selection, selection_argument)
|
|
538
|
-
self.
|
|
564
|
+
self._controller.state.sync_zones_data(self.get_zones_from_db())
|
|
539
565
|
# Notify delete zone
|
|
540
566
|
|
|
541
567
|
case self.db.table_iqremotesettings.uri:
|
|
@@ -556,7 +582,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
556
582
|
|
|
557
583
|
case self.db.table_alarmedsensor.uri:
|
|
558
584
|
self.db.table_alarmedsensor.delete(selection, selection_argument)
|
|
559
|
-
self.
|
|
585
|
+
self._controller.state.sync_partitions_data(self.get_partitions_from_db())
|
|
560
586
|
|
|
561
587
|
case self.db.table_history.uri:
|
|
562
588
|
self.db.table_history.delete(selection, selection_argument)
|
|
@@ -568,19 +594,19 @@ class QolsysPanel(QolsysObservable):
|
|
|
568
594
|
|
|
569
595
|
case self.db.table_doorlock.uri:
|
|
570
596
|
self.db.table_doorlock.delete(selection, selection_argument)
|
|
571
|
-
self.
|
|
597
|
+
self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
|
|
572
598
|
|
|
573
599
|
case self.db.table_dimmer.uri:
|
|
574
600
|
self.db.table_dimmer.delete(selection, selection_argument)
|
|
575
|
-
self.
|
|
601
|
+
self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
|
|
576
602
|
|
|
577
603
|
case self.db.table_thermostat.uri:
|
|
578
604
|
self.db.table_thermostat.delete(selection, selection_argument)
|
|
579
|
-
self.
|
|
605
|
+
self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
|
|
580
606
|
|
|
581
607
|
case self.db.table_zwave_node.uri:
|
|
582
608
|
self.db.table_zwave_node.delete(selection, selection_argument)
|
|
583
|
-
self.
|
|
609
|
+
self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
|
|
584
610
|
|
|
585
611
|
case self.db.table_automation.uri:
|
|
586
612
|
self.db.table_automation.delete(selection, selection_argument)
|
|
@@ -588,7 +614,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
588
614
|
|
|
589
615
|
case self.db.table_partition.uri:
|
|
590
616
|
self.db.table_partition.delete(selection, selection_argument)
|
|
591
|
-
self.
|
|
617
|
+
self._controller.state.sync_partitions_data(self.get_partitions_from_db())
|
|
592
618
|
|
|
593
619
|
case self.db.table_user.uri:
|
|
594
620
|
self.db.table_user.delete(selection, selection_argument)
|
|
@@ -598,9 +624,16 @@ class QolsysPanel(QolsysObservable):
|
|
|
598
624
|
self.db.table_dashboard_msgs.delete(selection, selection_argument)
|
|
599
625
|
# No action needed
|
|
600
626
|
|
|
601
|
-
case self.db.table_eu_event:
|
|
627
|
+
case self.db.table_eu_event.uri:
|
|
602
628
|
self.db.table_eu_event.delete(selection,selection_argument)
|
|
603
629
|
|
|
630
|
+
case self.db.table_powerg_device.uri:
|
|
631
|
+
self.db.table_powerg_device.delete(selection,selection_argument)
|
|
632
|
+
|
|
633
|
+
case self.db.table_weather.uri:
|
|
634
|
+
self.db.table_weather.delete(selection,selection_argument)
|
|
635
|
+
self._controller.state.sync_weather_data(self.get_weather_from_db())
|
|
636
|
+
|
|
604
637
|
case _:
|
|
605
638
|
LOGGER.debug("iq2meid deleting unknown uri:%s", uri)
|
|
606
639
|
LOGGER.debug(data)
|
|
@@ -618,16 +651,16 @@ class QolsysPanel(QolsysObservable):
|
|
|
618
651
|
new_value = content_values.get("value", "")
|
|
619
652
|
if name in self.state_partition:
|
|
620
653
|
partition_id = content_values.get("partition_id", "")
|
|
621
|
-
partition = self.
|
|
654
|
+
partition = self._controller.state.partition(partition_id)
|
|
622
655
|
if partition is not None:
|
|
623
656
|
match name:
|
|
624
657
|
case "ALARM_STATE":
|
|
625
658
|
partition.alarm_state = PartitionAlarmState(new_value)
|
|
626
659
|
|
|
627
660
|
# Inser Partition Content Provider
|
|
628
|
-
case self.db.table_partition:
|
|
661
|
+
case self.db.table_partition.uri:
|
|
629
662
|
self.db.table_partition.insert(data=content_values)
|
|
630
|
-
self.
|
|
663
|
+
self._controller.state.sync_partitions_data(self.get_partitions_from_db())
|
|
631
664
|
|
|
632
665
|
# Insert Settings Content Provider
|
|
633
666
|
case self.db.table_qolsyssettings.uri:
|
|
@@ -638,7 +671,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
638
671
|
new_value = content_values.get("value", "")
|
|
639
672
|
if name in self.settings_partition:
|
|
640
673
|
partition_id = content_values.get("partition_id", "")
|
|
641
|
-
partition = self.
|
|
674
|
+
partition = self._controller.state.partition(partition_id)
|
|
642
675
|
if partition is not None:
|
|
643
676
|
match name:
|
|
644
677
|
case "SYSTEM_STATUS":
|
|
@@ -668,27 +701,27 @@ class QolsysPanel(QolsysObservable):
|
|
|
668
701
|
# Sensor Content Provider
|
|
669
702
|
case self.db.table_sensor.uri:
|
|
670
703
|
self.db.table_sensor.insert(data=content_values)
|
|
671
|
-
self.
|
|
704
|
+
self._controller.state.sync_zones_data(self.get_zones_from_db())
|
|
672
705
|
|
|
673
706
|
# Door Lock Content Provider
|
|
674
707
|
case self.db.table_doorlock.uri:
|
|
675
708
|
self.db.table_doorlock.insert(data=content_values)
|
|
676
|
-
self.
|
|
709
|
+
self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
|
|
677
710
|
|
|
678
711
|
# Dimmer Content Provider
|
|
679
712
|
case self.db.table_dimmer.uri:
|
|
680
713
|
self.db.table_dimmer.insert(data=content_values)
|
|
681
|
-
self.
|
|
714
|
+
self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
|
|
682
715
|
|
|
683
716
|
# Thermostat Content Provider
|
|
684
717
|
case self.db.table_thermostat.uri:
|
|
685
718
|
self.db.table_thermostat.insert(data=content_values)
|
|
686
|
-
self.
|
|
719
|
+
self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
|
|
687
720
|
|
|
688
721
|
# ZWave Node Content Provider
|
|
689
722
|
case self.db.table_zwave_node.uri:
|
|
690
723
|
self.db.table_zwave_node.insert(data=content_values)
|
|
691
|
-
self.
|
|
724
|
+
self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
|
|
692
725
|
|
|
693
726
|
# HistoryContentProvider
|
|
694
727
|
case self.db.table_history.uri:
|
|
@@ -701,7 +734,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
701
734
|
partition_id = content_values.get("partition_id", "")
|
|
702
735
|
self.db.table_alarmedsensor.insert(data=content_values)
|
|
703
736
|
|
|
704
|
-
partition = self.
|
|
737
|
+
partition = self._controller.state.partition(partition_id)
|
|
705
738
|
if partition is not None:
|
|
706
739
|
partition.append_alarm_type([PartitionAlarmType(content_values.get("sgroup", ""))])
|
|
707
740
|
|
|
@@ -726,9 +759,18 @@ class QolsysPanel(QolsysObservable):
|
|
|
726
759
|
# No action needed
|
|
727
760
|
|
|
728
761
|
# EU_EVENT
|
|
729
|
-
case self.db.table_eu_event:
|
|
762
|
+
case self.db.table_eu_event.uri:
|
|
730
763
|
self.db.table_eu_event.insert(data=content_values)
|
|
731
764
|
|
|
765
|
+
# PowerG Device
|
|
766
|
+
case self.db.table_powerg_device.uri:
|
|
767
|
+
self.db.table_powerg_device.insert(data=content_values)
|
|
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
|
+
|
|
732
774
|
case _:
|
|
733
775
|
LOGGER.debug("iq2meid inserting unknow uri:%s", uri)
|
|
734
776
|
LOGGER.debug(data)
|
|
@@ -814,13 +856,35 @@ class QolsysPanel(QolsysObservable):
|
|
|
814
856
|
|
|
815
857
|
return scenes
|
|
816
858
|
|
|
859
|
+
def get_weather_from_db(self) -> QolsysWeather:
|
|
860
|
+
weather = QolsysWeather()
|
|
861
|
+
forecast_dic_list: list[dict] = self.db.get_weather()
|
|
862
|
+
|
|
863
|
+
forecast_obj_list = []
|
|
864
|
+
for forecast in forecast_dic_list:
|
|
865
|
+
forecast_obj_list.append(QolsysForecast(forecast))
|
|
866
|
+
|
|
867
|
+
# Create weather array
|
|
868
|
+
weather.update(forecast_obj_list)
|
|
869
|
+
|
|
870
|
+
return weather
|
|
871
|
+
|
|
817
872
|
def get_zones_from_db(self) -> list[QolsysZone]:
|
|
818
873
|
zones = []
|
|
819
874
|
zones_list: list[dict] = self.db.get_zones()
|
|
820
875
|
|
|
821
876
|
# Create sensors array
|
|
822
877
|
for zone_info in zones_list:
|
|
823
|
-
|
|
878
|
+
new_zone = QolsysZone(zone_info,self._controller.settings)
|
|
879
|
+
|
|
880
|
+
if new_zone.current_capability == "POWERG":
|
|
881
|
+
LOGGER.debug("Loading PowerG device info for zone %s", new_zone.zone_id)
|
|
882
|
+
powerg_dict = self.db.get_powerg(short_id= new_zone.shortID)
|
|
883
|
+
LOGGER.debug("PowerG device info: %s", powerg_dict)
|
|
884
|
+
if powerg_dict is not None:
|
|
885
|
+
new_zone.update_powerg(powerg_dict)
|
|
886
|
+
|
|
887
|
+
zones.append(new_zone)
|
|
824
888
|
|
|
825
889
|
return zones
|
|
826
890
|
|
|
@@ -898,3 +962,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
898
962
|
LOGGER.debug("Users list:")
|
|
899
963
|
for user in self._users:
|
|
900
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)
|
qolsys_controller/partition.py
CHANGED
qolsys_controller/plugin.py
CHANGED
|
@@ -1,34 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import logging
|
|
4
|
+
from abc import abstractmethod
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
2
6
|
|
|
3
7
|
from .observable import QolsysObservable
|
|
4
|
-
from .panel import QolsysPanel
|
|
5
|
-
from .settings import QolsysSettings
|
|
6
|
-
from .state import QolsysState
|
|
7
8
|
|
|
8
9
|
LOGGER = logging.getLogger(__name__)
|
|
9
10
|
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from .controller import QolsysController
|
|
10
13
|
|
|
11
|
-
class QolsysPlugin:
|
|
12
|
-
def __init__(self, state: QolsysState, panel: QolsysPanel, settings: QolsysSettings) -> None:
|
|
13
|
-
|
|
14
|
-
self._state: QolsysState = state
|
|
15
|
-
self._panel: QolsysPanel = panel
|
|
16
|
-
self._settings: QolsysSettings = settings
|
|
17
14
|
|
|
15
|
+
class QolsysPlugin:
|
|
16
|
+
def __init__(self, controller: QolsysController) -> None:
|
|
17
|
+
self._controller = controller
|
|
18
18
|
self.connected = False
|
|
19
19
|
self.connected_observer = QolsysObservable()
|
|
20
20
|
|
|
21
|
+
@abstractmethod
|
|
21
22
|
def config(self) -> None:
|
|
22
23
|
pass
|
|
23
24
|
|
|
24
|
-
@property
|
|
25
|
-
def state(self) -> QolsysState:
|
|
26
|
-
return self._state
|
|
27
|
-
|
|
28
|
-
@property
|
|
29
|
-
def panel(self) -> QolsysPanel:
|
|
30
|
-
return self._panel
|
|
31
|
-
|
|
32
|
-
@property
|
|
33
|
-
def settings(self) -> QolsysSettings:
|
|
34
|
-
return self._settings
|
qolsys_controller/plugin_c4.py
CHANGED
|
@@ -9,7 +9,7 @@ class QolsysPluginC4(QolsysPlugin):
|
|
|
9
9
|
def __init__(self) -> None:
|
|
10
10
|
|
|
11
11
|
# C4 Integration
|
|
12
|
-
|
|
12
|
+
raise NotImplementedError("C4 Plugin Not Yet Implemented") # noqa: EM101
|
|
13
13
|
|
|
14
14
|
def config(self, panel_ip: str, token: str) -> bool: # noqa: ARG002
|
|
15
15
|
LOGGER.warning("C4Plugin: Configuring Plugin")
|