qolsys-controller 0.0.2__tar.gz → 0.0.5__tar.gz

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.
Files changed (94) hide show
  1. qolsys_controller-0.0.5/.github/workflows/build.yml +36 -0
  2. qolsys_controller-0.0.5/.github/workflows/publish.yml +27 -0
  3. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/.gitignore +2 -0
  4. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/PKG-INFO +7 -3
  5. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/README.md +6 -2
  6. qolsys_controller-0.0.5/bin/qolsys.py +75 -0
  7. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/example.py +19 -20
  8. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/pyproject.toml +2 -2
  9. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/controller.py +6 -8
  10. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/db.py +62 -58
  11. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table.py +24 -25
  12. qolsys_controller-0.0.5/qolsys_controller/database/table_alarmedsensor.py +46 -0
  13. qolsys_controller-0.0.5/qolsys_controller/database/table_automation.py +77 -0
  14. qolsys_controller-0.0.5/qolsys_controller/database/table_country_locale.py +60 -0
  15. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_dashboard_msgs.py +6 -5
  16. qolsys_controller-0.0.5/qolsys_controller/database/table_dimmerlight.py +57 -0
  17. qolsys_controller-0.0.5/qolsys_controller/database/table_doorlock.py +59 -0
  18. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_eu_event.py +5 -5
  19. qolsys_controller-0.0.5/qolsys_controller/database/table_heat_map.py +44 -0
  20. qolsys_controller-0.0.5/qolsys_controller/database/table_history.py +48 -0
  21. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_iqremotesettings.py +13 -12
  22. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_iqrouter_network_config.py +5 -5
  23. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_iqrouter_user_device.py +5 -5
  24. qolsys_controller-0.0.5/qolsys_controller/database/table_master_slave.py +71 -0
  25. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_partition.py +10 -10
  26. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_powerg_device.py +5 -5
  27. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_qolsyssettings.py +10 -10
  28. qolsys_controller-0.0.5/qolsys_controller/database/table_scene.py +55 -0
  29. qolsys_controller-0.0.5/qolsys_controller/database/table_sensor.py +121 -0
  30. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_smartsocket.py +5 -5
  31. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_state.py +12 -11
  32. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_tcc.py +6 -5
  33. qolsys_controller-0.0.5/qolsys_controller/database/table_thermostat.py +94 -0
  34. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_trouble_conditions.py +14 -13
  35. qolsys_controller-0.0.5/qolsys_controller/database/table_user.py +50 -0
  36. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_virtual_device.py +5 -5
  37. qolsys_controller-0.0.5/qolsys_controller/database/table_weather.py +48 -0
  38. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_zigbee_device.py +5 -5
  39. qolsys_controller-0.0.5/qolsys_controller/database/table_zwave_association_group.py +53 -0
  40. qolsys_controller-0.0.5/qolsys_controller/database/table_zwave_history.py +59 -0
  41. qolsys_controller-0.0.5/qolsys_controller/database/table_zwave_node.py +150 -0
  42. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/database/table_zwave_other.py +5 -5
  43. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/enum.py +44 -41
  44. qolsys_controller-0.0.5/qolsys_controller/errors.py +37 -0
  45. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/mdns.py +3 -3
  46. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/mqtt_command_queue.py +2 -3
  47. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/observable.py +3 -2
  48. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/panel.py +163 -161
  49. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/partition.py +46 -43
  50. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/pki.py +72 -65
  51. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/plugin.py +5 -4
  52. qolsys_controller-0.0.5/qolsys_controller/plugin_c4.py +17 -0
  53. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/plugin_remote.py +237 -228
  54. qolsys_controller-0.0.5/qolsys_controller/settings.py +155 -0
  55. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/state.py +68 -65
  56. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/task_manager.py +3 -3
  57. qolsys_controller-0.0.5/qolsys_controller/utils_mqtt.py +24 -0
  58. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/zone.py +69 -68
  59. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/zwave_device.py +46 -43
  60. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/zwave_dimmer.py +28 -26
  61. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/zwave_garagedoor.py +1 -0
  62. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/zwave_generic.py +2 -1
  63. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/zwave_lock.py +28 -30
  64. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/zwave_outlet.py +1 -0
  65. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/zwave_thermostat.py +58 -55
  66. qolsys_controller-0.0.2/config/pki/cc4b73865c89/cc4b73865c89.old_secure +0 -19
  67. qolsys_controller-0.0.2/config/pki/cc4b73865c89/cc4b73865c89.oldqolsys +0 -20
  68. qolsys_controller-0.0.2/config/users.conf +0 -10
  69. qolsys_controller-0.0.2/qolsys_controller/database/table_alarmedsensor.py +0 -45
  70. qolsys_controller-0.0.2/qolsys_controller/database/table_automation.py +0 -73
  71. qolsys_controller-0.0.2/qolsys_controller/database/table_country_locale.py +0 -57
  72. qolsys_controller-0.0.2/qolsys_controller/database/table_dimmerlight.py +0 -55
  73. qolsys_controller-0.0.2/qolsys_controller/database/table_doorlock.py +0 -57
  74. qolsys_controller-0.0.2/qolsys_controller/database/table_heat_map.py +0 -43
  75. qolsys_controller-0.0.2/qolsys_controller/database/table_history.py +0 -47
  76. qolsys_controller-0.0.2/qolsys_controller/database/table_master_slave.py +0 -68
  77. qolsys_controller-0.0.2/qolsys_controller/database/table_scene.py +0 -52
  78. qolsys_controller-0.0.2/qolsys_controller/database/table_sensor.py +0 -112
  79. qolsys_controller-0.0.2/qolsys_controller/database/table_thermostat.py +0 -87
  80. qolsys_controller-0.0.2/qolsys_controller/database/table_user.py +0 -49
  81. qolsys_controller-0.0.2/qolsys_controller/database/table_weather.py +0 -47
  82. qolsys_controller-0.0.2/qolsys_controller/database/table_zwave_association_group.py +0 -51
  83. qolsys_controller-0.0.2/qolsys_controller/database/table_zwave_history.py +0 -57
  84. qolsys_controller-0.0.2/qolsys_controller/database/table_zwave_node.py +0 -145
  85. qolsys_controller-0.0.2/qolsys_controller/errors.py +0 -37
  86. qolsys_controller-0.0.2/qolsys_controller/plugin_c4.py +0 -18
  87. qolsys_controller-0.0.2/qolsys_controller/settings.py +0 -59
  88. qolsys_controller-0.0.2/qolsys_controller/utils_mqtt.py +0 -21
  89. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/Info_mqtt.md +0 -0
  90. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/LICENSE +0 -0
  91. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/info_pairing.md +0 -0
  92. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/info_qolsys.md +0 -0
  93. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/qolsys_controller/__init__.py +0 -0
  94. {qolsys_controller-0.0.2 → qolsys_controller-0.0.5}/requirements.txt +0 -0
@@ -0,0 +1,36 @@
1
+ # This workflow will install Python dependencies, run tests and lint with a single version of Python
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3
+
4
+ name: Build
5
+
6
+ on:
7
+ push:
8
+ branches: [ "main" ]
9
+ pull_request:
10
+ branches: [ "main" ]
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ build:
17
+
18
+ runs-on: ubuntu-latest
19
+
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - name: Set up Python 3.12
23
+ uses: actions/setup-python@v3
24
+ with:
25
+ python-version: "3.12"
26
+ - name: Install dependencies
27
+ run: |
28
+ python -m pip install --upgrade pip
29
+ pip install flake8 pytest
30
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
31
+ - name: Lint with flake8
32
+ run: |
33
+ # stop the build if there are Python syntax errors or undefined names
34
+ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
35
+ # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
36
+ flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
@@ -0,0 +1,27 @@
1
+ name: Publish Python package to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ pypi-publish:
9
+ name: Upload release to PyPI
10
+ runs-on: ubuntu-latest
11
+ environment:
12
+ name: pypi
13
+ url: https://pypi.org/project/qolsys-controller/
14
+ permissions:
15
+ id-token: write # Required for PyPI Trusted Publishers
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: "3.12"
22
+ - name: Install build dependencies
23
+ run: python -m pip install build
24
+ - name: Build package
25
+ run: python -m build
26
+ - name: Publish package to PyPI
27
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -3,6 +3,8 @@
3
3
  /__pycache__
4
4
  .pyc
5
5
  build
6
+ dist
7
+ config
6
8
  __pycache__
7
9
  *.key
8
10
  *.secure
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qolsys-controller
3
- Version: 0.0.2
3
+ Version: 0.0.5
4
4
  Summary: A Python module that emulates a virtual IQ Remote device, enabling full local control of a Qolsys IQ Panel
5
5
  Project-URL: Homepage, https://github.com/EHylands/QolsysController
6
6
  Project-URL: Issues, https://github.com/EHylands/QolsysController/issues
@@ -14,7 +14,9 @@ Classifier: Topic :: Home Automation
14
14
  Requires-Python: >=3.12
15
15
  Description-Content-Type: text/markdown
16
16
 
17
- # QolsysController
17
+ # Qolsys Controller - qolsys-controller
18
+
19
+ [![Build](https://github.com/EHylands/QolsysController/actions/workflows/python-app.yml/badge.svg)](https://github.com/EHylands/QolsysController/actions/workflows/python-app.yml)
18
20
 
19
21
  A Python module that emulates a virtual IQ Remote device, enabling full **local control** of a Qolsys IQ Panel over MQTT — no cloud access required.
20
22
 
@@ -62,7 +64,9 @@ A Python module that emulates a virtual IQ Remote device, enabling full **local
62
64
 
63
65
  ## ⚠️ Certificate Warning
64
66
 
65
- During pairing, the main panel issues **only one signed client certificate** per virtual IQ Remote. If any key files are lost or deleted, re-pairing may become impossible.
67
+ During pairing, the main panel issues **only one signed client certificate** per virtual IQ Remote. If any key files are lost or deleted, re-pairing may become impossible.
68
+
69
+ A new PKI, including a new private key, can be recreated under specific circumstances, though the precise conditions remain unknown at this time.
66
70
 
67
71
  **Important:**
68
72
  Immediately back up the following files from the `pki/` directory after initial pairing:
@@ -1,4 +1,6 @@
1
- # QolsysController
1
+ # Qolsys Controller - qolsys-controller
2
+
3
+ [![Build](https://github.com/EHylands/QolsysController/actions/workflows/python-app.yml/badge.svg)](https://github.com/EHylands/QolsysController/actions/workflows/python-app.yml)
2
4
 
3
5
  A Python module that emulates a virtual IQ Remote device, enabling full **local control** of a Qolsys IQ Panel over MQTT — no cloud access required.
4
6
 
@@ -46,7 +48,9 @@ A Python module that emulates a virtual IQ Remote device, enabling full **local
46
48
 
47
49
  ## ⚠️ Certificate Warning
48
50
 
49
- During pairing, the main panel issues **only one signed client certificate** per virtual IQ Remote. If any key files are lost or deleted, re-pairing may become impossible.
51
+ During pairing, the main panel issues **only one signed client certificate** per virtual IQ Remote. If any key files are lost or deleted, re-pairing may become impossible.
52
+
53
+ A new PKI, including a new private key, can be recreated under specific circumstances, though the precise conditions remain unknown at this time.
50
54
 
51
55
  **Important:**
52
56
  Immediately back up the following files from the `pki/` directory after initial pairing:
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import argparse
4
+ import asyncio
5
+ import logging
6
+ import os
7
+ import sys
8
+
9
+ from qolsys_controller import qolsys_controller
10
+ from qolsys_controller.errors import QolsysMqttError, QolsysSqlError, QolsysSslError
11
+
12
+
13
+ async def main() -> None: # noqa: D103
14
+
15
+ cli_parser = argparse.ArgumentParser()
16
+ cli_parser.add_argument("--panel-ip", help="Qolsys Panel IP", default="")
17
+ cli_parser.add_argument("--plugin-ip", help="Plugin IP", default="")
18
+ cli_parser.add_argument("--config-dir", help="Configuration Directory", default="./config/")
19
+ cli_parser.add_argument("--pki-autodiscovery", help="Enable PKI Autodiscovery", action="store_true")
20
+ cli_parser.add_argument("--debug", help="Verbose MQTT Traffic", action="store_true")
21
+
22
+ args = cli_parser.parse_args()
23
+
24
+ logging.basicConfig(level=logging.DEBUG, format="%(levelname)s - %(module)s: %(message)s")
25
+ LOGGER = logging.getLogger(__name__)
26
+
27
+ loop = asyncio.new_event_loop()
28
+ asyncio.set_event_loop(loop)
29
+
30
+ Panel = qolsys_controller()
31
+
32
+ # Select plugin
33
+ Panel.select_plugin("remote")
34
+ Panel.settings.config_directory = args.config_dir
35
+ Panel.plugin.settings.panel_ip = args.panel_ip
36
+ Panel.plugin.settings.plugin_ip = args.plugin_ip
37
+ Panel.plugin.settings.random_mac = ""
38
+
39
+ # Additionnal remote plugin config
40
+ Panel.plugin.check_user_code_on_disarm = False
41
+ Panel.plugin.log_mqtt_mesages = args.debug
42
+ Panel.plugin.auto_discover_pki = args.pki_autodiscovery
43
+
44
+ # Configure remote plugin
45
+ if not await Panel.plugin.config(start_pairing=True):
46
+ LOGGER.debug("Error Configuring remote plugin")
47
+ return
48
+
49
+ try:
50
+ await Panel.plugin.start_operation()
51
+
52
+ except QolsysMqttError:
53
+ LOGGER.debug("QolsysMqttError")
54
+
55
+ except QolsysSslError:
56
+ LOGGER.debug("QolsysSslError")
57
+
58
+ except QolsysSqlError:
59
+ LOGGER.debug("QolsysSqlError")
60
+
61
+ if not Panel.plugin.connected:
62
+ LOGGER.error("Panel not ready for operation")
63
+ return
64
+
65
+ LOGGER.debug("Qolsys Panel Ready for operation")
66
+
67
+ stop_event = asyncio.Event()
68
+ await stop_event.wait()
69
+
70
+ # Change to the "Selector" event loop if platform is Windows
71
+ if sys.platform.lower() == "win32" or os.name.lower() == "nt":
72
+ from asyncio import WindowsSelectorEventLoopPolicy, set_event_loop_policy
73
+ set_event_loop_policy(WindowsSelectorEventLoopPolicy())
74
+
75
+ asyncio.run(main())
@@ -8,23 +8,25 @@ import sys
8
8
  from qolsys_controller.controller import QolsysController
9
9
  from qolsys_controller.errors import QolsysMqttError, QolsysSqlError, QolsysSslError
10
10
 
11
- logging.basicConfig(level=logging.DEBUG,format="%(levelname)s - %(module)s: %(message)s")
11
+ logging.basicConfig(level=logging.DEBUG, format="%(levelname)s - %(module)s: %(message)s")
12
12
  LOGGER = logging.getLogger(__name__)
13
13
 
14
+
14
15
  async def main() -> None: # noqa: D103
15
16
 
16
- remote = QolsysController(config_directory="./config/")
17
+ remote = QolsysController()
17
18
 
18
19
  # Select plugin
19
20
  remote.select_plugin("remote")
20
21
 
21
- remote.plugin.settings.panel_ip = "192.168.10.220"
22
+ remote.plugin.settings.config_directory = "./config/"
23
+ remote.plugin.settings.panel_ip = "192.168.10.220"
22
24
  remote.plugin.settings.plugin_ip = "192.168.10.73"
23
- remote.plugin.settings.random_mac = "" # Example: F2:16:3E:33:ED:20
25
+ remote.plugin.settings.random_mac = "" # Example: F2:16:3E:33:ED:20
24
26
 
25
27
  # Additionnal remote plugin config
26
- remote.plugin.check_user_code_on_disarm = False # Check user code in user.conf file
27
- remote.plugin.log_mqtt_mesages = False # Enable for MQTT debug purposes
28
+ remote.plugin.check_user_code_on_disarm = False # Check user code in user.conf file
29
+ remote.plugin.log_mqtt_mesages = False # Enable for MQTT debug purposes
28
30
  remote.plugin.auto_discover_pki = True
29
31
 
30
32
  # Configure remote plugin
@@ -36,13 +38,13 @@ async def main() -> None: # noqa: D103
36
38
  await remote.plugin.start_operation()
37
39
 
38
40
  except QolsysMqttError:
39
- LOGGER.debug("QolsysMqttError")
41
+ LOGGER.debug("QolsysMqttError")
40
42
 
41
43
  except QolsysSslError:
42
- LOGGER.debug("QolsysSslError")
44
+ LOGGER.debug("QolsysSslError")
43
45
 
44
46
  except QolsysSqlError:
45
- LOGGER.debug("QolsysSqlError")
47
+ LOGGER.debug("QolsysSqlError")
46
48
 
47
49
  if not remote.plugin.connected:
48
50
  LOGGER.error("Panel not ready for operation")
@@ -56,9 +58,9 @@ async def main() -> None: # noqa: D103
56
58
  # await asyncio.sleep(3)
57
59
  # await remote.plugin.command_zwave_switch_multi_level(node_id=6,level=99)
58
60
 
59
- # DISARM
60
- #await asyncio.sleep(3)
61
- #await remote.plugin.command_disarm(partition_id="0",
61
+ # DISARM
62
+ # await asyncio.sleep(3)
63
+ # await remote.plugin.command_disarm(partition_id="0",
62
64
  # user_code="1111")
63
65
 
64
66
  # ARM_STAY
@@ -68,24 +70,23 @@ async def main() -> None: # noqa: D103
68
70
  user_code="1111",
69
71
  exit_sounds=False,
70
72
  instant_arm=False)
71
-
72
73
 
73
74
  # DISARM
74
75
  await asyncio.sleep(3)
75
76
  await remote.plugin.command_disarm(partition_id="0",
76
77
  user_code="1111")
77
78
 
78
-
79
79
  # ARM_AWAY
80
- #await asyncio.sleep(3)
81
- #await remote.plugin.command_arm(partition_id=0,
80
+ # await asyncio.sleep(3)
81
+ # await remote.plugin.command_arm(partition_id=0,
82
82
  # arming_type='ARM-AWAY',
83
83
  # user_code='1111',
84
84
  # exit_sounds=True,
85
85
  # instant_arm=False)
86
86
 
87
- while True:
88
- await asyncio.sleep(1)
87
+ # Use an asyncio.Event to keep the program running efficiently
88
+ stop_event = asyncio.Event()
89
+ await stop_event.wait()
89
90
 
90
91
  # Change to the "Selector" event loop if platform is Windows
91
92
  if sys.platform.lower() == "win32" or os.name.lower() == "nt":
@@ -93,5 +94,3 @@ if sys.platform.lower() == "win32" or os.name.lower() == "nt":
93
94
  set_event_loop_policy(WindowsSelectorEventLoopPolicy())
94
95
 
95
96
  asyncio.run(main())
96
-
97
-
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "qolsys-controller"
3
- version = "0.0.2"
3
+ version = "0.0.5"
4
4
  authors = [
5
5
  { name="Eric Hylands", email="" },
6
6
  ]
@@ -31,5 +31,5 @@ line-length = 88
31
31
 
32
32
  [tool.ruff.lint]
33
33
  select = ['ALL']
34
- ignore = ["E501","S608","S311","S104","D100","D101", "D102","D107", "FBT001", "N802","N806","PERF401"]
34
+ ignore = ["E501","S608","S311","S104","D100","D101", "D102","D107","ERA001", "FBT001","FBT002", "N802","N806","PERF401"]
35
35
 
@@ -9,16 +9,16 @@ from .state import QolsysState
9
9
 
10
10
  LOGGER = logging.getLogger(__name__)
11
11
 
12
+
12
13
  class QolsysController:
13
14
 
14
- def __init__(self,config_directory:str) -> None:
15
+ def __init__(self) -> None:
15
16
 
16
17
  # QolsysController Information
17
18
  self.plugin = None
18
- self._config_directory = config_directory
19
19
  self._state = QolsysState()
20
- self._panel = QolsysPanel(settings_directory=config_directory,state=self.state)
21
20
  self._settings = QolsysSettings()
21
+ self._panel = QolsysPanel(settings=self.settings, state=self.state)
22
22
 
23
23
  @property
24
24
  def state(self) -> QolsysState:
@@ -32,21 +32,19 @@ class QolsysController:
32
32
  def settings(self) -> QolsysSettings:
33
33
  return self._settings
34
34
 
35
- def select_plugin(self,plugin: str) -> None:
35
+ def select_plugin(self, plugin: str) -> None:
36
36
 
37
37
  match plugin:
38
38
 
39
39
  case "c4":
40
40
  LOGGER.debug("C4 Plugin Selected")
41
- self.plugin = QolsysPluginC4(self.state,self.panel,self.settings)
41
+ self.plugin = QolsysPluginC4(self.state, self.panel, self.settings)
42
42
  return
43
43
 
44
44
  case "remote":
45
45
  LOGGER.debug("Remote Plugin Selected")
46
- self.plugin = QolsysPluginRemote(self.state,self.panel,self.settings,self._config_directory)
46
+ self.plugin = QolsysPluginRemote(self.state, self.panel, self.settings)
47
47
  return
48
48
 
49
49
  case _:
50
50
  LOGGER.debug("Unknow Plugin Selected")
51
-
52
-
@@ -36,44 +36,45 @@ from .table_zwave_other import QolsysTableZwaveOther
36
36
 
37
37
  LOGGER = logging.getLogger(__name__)
38
38
 
39
+
39
40
  class QolsysDB:
40
41
 
41
42
  def __init__(self) -> None: # noqa: PLR0915
42
43
 
43
- self._db:sqlite3.Connection = sqlite3.connect(":memory:")
44
- self._cursor:sqlite3.Cursor = self._db.cursor()
45
-
46
- self.table_alarmedsensor = QolsysTableAlarmedSensor(self.db,self.cursor)
47
- self.table_automation = QolsysTableAutomation(self.db,self.cursor)
48
- self.table_country_locale = QolsysTableCountryLocale(self.db,self.cursor)
49
- self.table_dashboard_msgs = QolsysTableDashboardMsgs(self.db,self.cursor)
50
- self.table_dimmer = QolsysTableDimmerLight(self.db,self.cursor)
51
- self.table_doorlock = QolsysTableDoorLock(self.db,self.cursor)
52
- self.table_eu_event = QolsysTableEuEvent(self.db,self.cursor)
53
- self.table_heat_map = QolsysTableHeatMap(self.db,self.cursor)
54
- self.table_history = QolsysTableHistory(self.db,self.cursor)
55
- self.table_iqremotesettings = QolsysTableIqRemoteSettings(self.db,self.cursor)
56
- self.table_iqrouter_network_config = QolsysTableIqRouterNetworkConfig(self.db,self.cursor)
57
- self.table_iqrouter_user_device = QolsysTableIqRouterUserDevice(self.db,self.cursor)
58
- self.table_master_slave = QolsysTableMasterSlave(self.db,self.cursor)
59
- self.table_partition = QolsysTablePartition(self.db,self.cursor)
60
- self.table_powerg_device = QolsysTablePowerGDevice(self.db,self.cursor)
61
- self.table_sensor = QolsysTableSensor(self.db,self.cursor)
62
- self.table_smartsocket = QolsysTableSmartSocket(self.db,self.cursor)
63
- self.table_qolsyssettings = QolsysTableQolsysSettings(self.db,self.cursor)
64
- self.table_scene = QolsysTableScene(self.db,self.cursor)
65
- self.table_state = QolsysTableState(self.db,self.cursor)
66
- self.table_tcc = QolsysTableTcc(self.db,self.cursor)
67
- self.table_thermostat = QolsysTableThermostat(self.db,self.cursor)
68
- self.table_trouble_conditions = QolsysTableTroubleConditions(self.db,self.cursor)
69
- self.table_user = QolsysTableUser(self.db,self.cursor)
70
- self.table_virtual_device = QolsysTableVirtualDevice(self.db,self.cursor)
71
- self.table_weather = QolsysTableWeather(self.db,self.cursor)
72
- self.table_zigbee_device = QolsysTableZigbeeDevice(self.db,self.cursor)
73
- self.table_zwave_association_goup = QolsysTableZwaveAssociationGroup(self.db,self.cursor)
74
- self.table_zwave_history = QolsysTableZwaveHistory(self.db,self.cursor)
75
- self.table_zwave_node = QolsysTableZwaveNode(self.db,self.cursor)
76
- self.table_zwave_other = QolsysTableZwaveOther(self.db,self.cursor)
44
+ self._db: sqlite3.Connection = sqlite3.connect(":memory:")
45
+ self._cursor: sqlite3.Cursor = self._db.cursor()
46
+
47
+ self.table_alarmedsensor = QolsysTableAlarmedSensor(self.db, self.cursor)
48
+ self.table_automation = QolsysTableAutomation(self.db, self.cursor)
49
+ self.table_country_locale = QolsysTableCountryLocale(self.db, self.cursor)
50
+ self.table_dashboard_msgs = QolsysTableDashboardMsgs(self.db, self.cursor)
51
+ self.table_dimmer = QolsysTableDimmerLight(self.db, self.cursor)
52
+ self.table_doorlock = QolsysTableDoorLock(self.db, self.cursor)
53
+ self.table_eu_event = QolsysTableEuEvent(self.db, self.cursor)
54
+ self.table_heat_map = QolsysTableHeatMap(self.db, self.cursor)
55
+ self.table_history = QolsysTableHistory(self.db, self.cursor)
56
+ self.table_iqremotesettings = QolsysTableIqRemoteSettings(self.db, self.cursor)
57
+ self.table_iqrouter_network_config = QolsysTableIqRouterNetworkConfig(self.db, self.cursor)
58
+ self.table_iqrouter_user_device = QolsysTableIqRouterUserDevice(self.db, self.cursor)
59
+ self.table_master_slave = QolsysTableMasterSlave(self.db, self.cursor)
60
+ self.table_partition = QolsysTablePartition(self.db, self.cursor)
61
+ self.table_powerg_device = QolsysTablePowerGDevice(self.db, self.cursor)
62
+ self.table_sensor = QolsysTableSensor(self.db, self.cursor)
63
+ self.table_smartsocket = QolsysTableSmartSocket(self.db, self.cursor)
64
+ self.table_qolsyssettings = QolsysTableQolsysSettings(self.db, self.cursor)
65
+ self.table_scene = QolsysTableScene(self.db, self.cursor)
66
+ self.table_state = QolsysTableState(self.db, self.cursor)
67
+ self.table_tcc = QolsysTableTcc(self.db, self.cursor)
68
+ self.table_thermostat = QolsysTableThermostat(self.db, self.cursor)
69
+ self.table_trouble_conditions = QolsysTableTroubleConditions(self.db, self.cursor)
70
+ self.table_user = QolsysTableUser(self.db, self.cursor)
71
+ self.table_virtual_device = QolsysTableVirtualDevice(self.db, self.cursor)
72
+ self.table_weather = QolsysTableWeather(self.db, self.cursor)
73
+ self.table_zigbee_device = QolsysTableZigbeeDevice(self.db, self.cursor)
74
+ self.table_zwave_association_goup = QolsysTableZwaveAssociationGroup(self.db, self.cursor)
75
+ self.table_zwave_history = QolsysTableZwaveHistory(self.db, self.cursor)
76
+ self.table_zwave_node = QolsysTableZwaveNode(self.db, self.cursor)
77
+ self.table_zwave_other = QolsysTableZwaveOther(self.db, self.cursor)
77
78
 
78
79
  self._table_array = []
79
80
  self._table_array.append(self.table_sensor)
@@ -143,108 +144,111 @@ class QolsysDB:
143
144
  return self._cursor
144
145
 
145
146
  def get_partitions(self) -> list[dict]:
146
- self.cursor.execute(f"SELECT * FROM {self.table_partition.table} ORDER BY partition_id" )
147
+ self.cursor.execute(f"SELECT * FROM {self.table_partition.table} ORDER BY partition_id")
147
148
  self.db.commit()
148
149
 
149
150
  partitions = []
150
151
  columns = [description[0] for description in self.cursor.description]
151
- for row in self.cursor.fetchall():
152
+ for row in self.cursor.fetchall():
152
153
  row_dict = dict(zip(columns, row, strict=True))
153
154
  partitions.append(row_dict)
154
155
 
155
156
  return partitions
156
157
 
157
158
  def get_zwave_devices(self) -> list[dict]:
158
- self.cursor.execute(f"SELECT * FROM {self.table_zwave_node.table} ORDER BY node_id" )
159
+ self.cursor.execute(f"SELECT * FROM {self.table_zwave_node.table} ORDER BY node_id")
159
160
  self.db.commit()
160
161
 
161
162
  devices = []
162
163
  columns = [description[0] for description in self.cursor.description]
163
- for row in self.cursor.fetchall():
164
+ for row in self.cursor.fetchall():
164
165
  row_dict = dict(zip(columns, row, strict=True))
165
166
  devices.append(row_dict)
166
167
 
167
168
  return devices
168
169
 
169
170
  def get_locks(self) -> list[dict]:
170
- self.cursor.execute(f"SELECT * FROM {self.table_doorlock.table} ORDER BY node_id" )
171
+ self.cursor.execute(f"SELECT * FROM {self.table_doorlock.table} ORDER BY node_id")
171
172
  self.db.commit()
172
173
 
173
174
  locks = []
174
175
  columns = [description[0] for description in self.cursor.description]
175
- for row in self.cursor.fetchall():
176
+ for row in self.cursor.fetchall():
176
177
  row_dict = dict(zip(columns, row, strict=True))
177
178
  locks.append(row_dict)
178
179
 
179
180
  return locks
180
181
 
181
182
  def get_thermostats(self) -> list[dict]:
182
- self.cursor.execute(f"SELECT * FROM {self.table_thermostat.table} ORDER BY node_id" )
183
+ self.cursor.execute(f"SELECT * FROM {self.table_thermostat.table} ORDER BY node_id")
183
184
  self.db.commit()
184
185
 
185
186
  thermostats = []
186
187
  columns = [description[0] for description in self.cursor.description]
187
- for row in self.cursor.fetchall():
188
+ for row in self.cursor.fetchall():
188
189
  row_dict = dict(zip(columns, row, strict=True))
189
190
  thermostats.append(row_dict)
190
191
 
191
192
  return thermostats
192
193
 
193
194
  def get_dimmers(self) -> list[dict]:
194
- self.cursor.execute(f"SELECT * FROM {self.table_dimmer.table} ORDER BY node_id" )
195
+ self.cursor.execute(f"SELECT * FROM {self.table_dimmer.table} ORDER BY node_id")
195
196
  self.db.commit()
196
197
 
197
198
  dimmers = []
198
199
  columns = [description[0] for description in self.cursor.description]
199
- for row in self.cursor.fetchall():
200
+ for row in self.cursor.fetchall():
200
201
  row_dict = dict(zip(columns, row, strict=True))
201
202
  dimmers.append(row_dict)
202
203
 
203
204
  return dimmers
204
205
 
205
206
  def get_zones(self) -> list[dict]:
206
- self.cursor.execute(f"SELECT * FROM {self.table_sensor.table} ORDER BY zoneid" )
207
+ self.cursor.execute(f"SELECT * FROM {self.table_sensor.table} ORDER BY zoneid")
207
208
  self.db.commit()
208
209
 
209
210
  zones = []
210
211
  columns = [description[0] for description in self.cursor.description]
211
- for row in self.cursor.fetchall():
212
+ for row in self.cursor.fetchall():
212
213
  row_dict = dict(zip(columns, row, strict=True))
213
214
  zones.append(row_dict)
214
215
 
215
216
  return zones
216
217
 
217
- def get_setting_panel(self,setting:str) -> str:
218
- self.cursor.execute(f"SELECT value FROM {self.table_qolsyssettings.table} WHERE name = ? and partition_id = ? ", (setting,"0"))
218
+ def get_setting_panel(self, setting: str) -> str:
219
+ self.cursor.execute(f"""SELECT value FROM {self.table_qolsyssettings.table}
220
+ WHERE name = ? and partition_id = ? """, (setting, "0"))
219
221
  row = self.cursor.fetchone()
220
222
 
221
223
  if row is None:
222
- LOGGER.debug("%s value not found",setting)
224
+ LOGGER.debug("%s value not found", setting)
223
225
  return None
224
226
 
225
227
  return row[0]
226
228
 
227
- def get_setting_partition(self,setting:str,partition_id:str) -> str | None:
228
- self.cursor.execute(f"SELECT value FROM {self.table_qolsyssettings.table} WHERE name = ? and partition_id = ? ", (setting,partition_id))
229
+ def get_setting_partition(self, setting: str, partition_id: str) -> str | None:
230
+ self.cursor.execute(f"""SELECT value FROM {self.table_qolsyssettings.table}
231
+ WHERE name = ? and partition_id = ? """, (setting, partition_id))
229
232
  row = self.cursor.fetchone()
230
233
 
231
234
  if row is None:
232
- LOGGER.debug("%s value not found",setting)
235
+ LOGGER.debug("%s value not found", setting)
233
236
  return None
234
237
 
235
238
  return row[0]
236
239
 
237
- def get_state_partition(self,state:str,partition_id:str) -> str | None:
238
- self.cursor.execute(f"SELECT value FROM {self.table_state.table} WHERE name = ? and partition_id = ? ", (state,partition_id))
240
+ def get_state_partition(self, state: str, partition_id: str) -> str | None:
241
+ self.cursor.execute(
242
+ f"""SELECT value FROM {self.table_state.table} WHERE name = ? and partition_id = ? """, (state, partition_id))
239
243
  row = self.cursor.fetchone()
240
244
 
241
245
  if row is None:
242
- LOGGER.debug("%s value not found",state)
246
+ LOGGER.debug("%s value not found", state)
243
247
  return None
244
248
 
245
249
  return row[0]
246
250
 
247
- def get_alarm_type(self,partition_id:str) -> list[str]:
251
+ def get_alarm_type(self, partition_id: str) -> list[str]:
248
252
  alarm_type = []
249
253
  self.cursor.execute(f"SELECT sgroup FROM {self.table_alarmedsensor.table} WHERE partition_id = ? ", (partition_id))
250
254
  rows = self.cursor.fetchall()
@@ -258,14 +262,14 @@ class QolsysDB:
258
262
  for table in self._table_array:
259
263
  table.clear()
260
264
 
261
- def get_table(self,uri:str) -> QolsysTable | None:
265
+ def get_table(self, uri: str) -> QolsysTable | None:
262
266
  for table in self._table_array:
263
267
  if uri == table.uri:
264
268
  return table
265
269
 
266
270
  return None
267
271
 
268
- def load_db(self,database:dict) -> None:
272
+ def load_db(self, database: dict) -> None:
269
273
 
270
274
  self.clear_db()
271
275