qolsys-controller 0.0.4__py3-none-any.whl → 0.0.7__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.
@@ -93,22 +93,23 @@ class QolsysPanel(QolsysObservable):
93
93
  self._product_type = ""
94
94
 
95
95
  def read_users_file(self) -> bool:
96
- # Loading user_code data from users.conf file
97
- try:
98
- path = self._settings.users_file_path
99
- with path.open("r", encoding="utf-8") as file:
100
- try:
101
- users = json.load(file)
102
- for user in users:
103
- self._users.append(user)
104
-
105
- except json.JSONDecodeError:
106
- LOGGER.exception("users.conf file json error")
107
- return False
108
-
109
- except FileNotFoundError:
110
- LOGGER.exception("users.conf file not found")
111
- return False
96
+ # Loading user_code data from users.conf file if exists
97
+ if self._settings.users_file_path.is_file():
98
+ try:
99
+ path = self._settings.users_file_path
100
+ with path.open("r", encoding="utf-8") as file:
101
+ try:
102
+ users = json.load(file)
103
+ for user in users:
104
+ self._users.append(user)
105
+
106
+ except json.JSONDecodeError:
107
+ LOGGER.exception("users.conf file json error")
108
+ return False
109
+
110
+ except FileNotFoundError:
111
+ LOGGER.exception("users.conf file not found")
112
+ return False
112
113
 
113
114
  return True
114
115
 
@@ -817,6 +818,7 @@ class QolsysPanel(QolsysObservable):
817
818
  LOGGER.debug("Android Version: %s", self.ANDROID_VERSION)
818
819
  LOGGER.debug("Hardware Version: %s", self.HARDWARE_VERSION)
819
820
  LOGGER.debug("MAC Address: %s", self.MAC_ADDRESS)
821
+ LOGGER.debug("MQTT remoteClientID: %s", self._settings.mqtt_remote_client_id)
820
822
  LOGGER.debug("Unique ID: %s", self.unique_id)
821
823
  LOGGER.debug("Panel Tamper State: %s", self.PANEL_TAMPER_STATE)
822
824
  LOGGER.debug("AC Status: %s", self.AC_STATUS)
@@ -110,6 +110,9 @@ class QolsysPluginRemote(QolsysPlugin):
110
110
  else:
111
111
  self._pki.set_id(self.settings.random_mac)
112
112
 
113
+ # Set mqtt_remote_client_id
114
+ self.settings.mqtt_remote_client_id = "qolsys-controller-" + self._pki.formatted_id()
115
+
113
116
  # Check if plugin is paired
114
117
  if self.is_paired():
115
118
  LOGGER.debug("Panel is Paired")
@@ -133,6 +136,24 @@ class QolsysPluginRemote(QolsysPlugin):
133
136
  async def start_operation(self) -> None:
134
137
  await self._task_manager.run(self.mqtt_connect_task(reconnect=True), self._mqtt_task_connect_label)
135
138
 
139
+ async def stop_operation(self) -> None:
140
+ LOGGER.debug("Stopping Plugin Operation")
141
+
142
+ if self.certificate_exchange_server is not None:
143
+ self.certificate_exchange_server.close()
144
+
145
+ if self.aiomqtt is not None:
146
+ await self.aiomqtt.__aexit__(None, None, None)
147
+ self.aiomqtt = None
148
+
149
+ self._task_manager.cancel(self._mqtt_task_connect_label)
150
+ self._task_manager.cancel(self._mqtt_task_listen_label)
151
+ self._task_manager.cancel(self._mqtt_task_ping_label)
152
+ self._task_manager.cancel(self._mqtt_task_config_label)
153
+
154
+ self.connected = False
155
+ self.connected_observer.notify()
156
+
136
157
  async def mqtt_connect_task(self, reconnect: bool) -> None:
137
158
  # Configure TLS parameters for MQTT connection
138
159
  tls_params = aiomqtt.TLSParameters(
@@ -228,6 +249,7 @@ class QolsysPluginRemote(QolsysPlugin):
228
249
  while True:
229
250
  if self.aiomqtt is not None and self.connected:
230
251
  await self.command_pingevent()
252
+
231
253
  await asyncio.sleep(self.settings.mqtt_ping)
232
254
 
233
255
  async def mqtt_listen_task(self) -> None:
@@ -434,7 +456,7 @@ class QolsysPluginRemote(QolsysPlugin):
434
456
  ipAddress = self.settings.plugin_ip
435
457
  eventName = "connect_v204"
436
458
  macAddress = self.settings.random_mac
437
- remoteClientID = "QolsysController"
459
+ remoteClientID = self.settings.mqtt_remote_client_id
438
460
  softwareVersion = "4.4.1"
439
461
  producType = "tab07_rk68"
440
462
  bssid = ""
@@ -646,7 +668,7 @@ class QolsysPluginRemote(QolsysPlugin):
646
668
 
647
669
  topic = "mastermeid"
648
670
  eventName = "disconnect"
649
- remoteClientID = "QolsysRemote"
671
+ remoteClientID = self.settings.mqtt_remote_client_id
650
672
  requestID = str(uuid.uuid4())
651
673
  remoteMacAddress = self.settings.random_mac
652
674
 
@@ -24,7 +24,8 @@ class QolsysSettings:
24
24
 
25
25
  # MQTT
26
26
  self._mqtt_timeout: int = 30
27
- self._mqtt_ping: int = 600
27
+ self._mqtt_ping: int = 15
28
+ self._mqtt_remote_client_id = ""
28
29
 
29
30
  @property
30
31
  def random_mac(self) -> str:
@@ -89,6 +90,14 @@ class QolsysSettings:
89
90
  def mqtt_ping(self) -> int:
90
91
  return self._mqtt_ping
91
92
 
93
+ @property
94
+ def mqtt_remote_client_id(self) -> str:
95
+ return self._mqtt_remote_client_id
96
+
97
+ @mqtt_remote_client_id.setter
98
+ def mqtt_remote_client_id(self,client_id:str) -> None:
99
+ self._mqtt_remote_client_id = client_id
100
+
92
101
  def check_panel_ip(self) -> bool:
93
102
  if self._panel_ip == "":
94
103
  LOGGER.debug("Invalid Panel IP: %s", self._panel_ip)
@@ -123,4 +132,33 @@ class QolsysSettings:
123
132
  return False
124
133
 
125
134
  LOGGER.debug("Using config_directory: %s", self.config_directory.resolve())
135
+
136
+ # Create pki directory if not found
137
+ if not self.pki_directory.is_dir():
138
+ LOGGER.debug("Creating pki_directory: %s", self.pki_directory.resolve())
139
+ try:
140
+ self.pki_directory.mkdir(parents=True)
141
+ except PermissionError:
142
+ LOGGER.exception("Permission denied: Unable to create: %s", self.pki_directory.resolve())
143
+ return False
144
+ except Exception:
145
+ LOGGER.exception("Error creating pki_directory: %s", self.pki_directory.resolve())
146
+ return False
147
+
148
+ LOGGER.debug("Using pki_directory: %s", self.pki_directory.resolve())
149
+
150
+ # Create media directory if not found
151
+ if not self._media_directory.is_dir():
152
+ LOGGER.debug("Creating media_directory: %s", self._media_directory.resolve())
153
+ try:
154
+ self._media_directory.mkdir(parents=True)
155
+ except PermissionError:
156
+ LOGGER.exception("Permission denied: Unable to create: %s", self._media_directory.resolve())
157
+ return False
158
+ except Exception:
159
+ LOGGER.exception("Error creating media_directory: %s", self._media_directory.resolve())
160
+ return False
161
+
162
+ LOGGER.debug("Using media_directory: %s", self._media_directory.resolve())
163
+
126
164
  return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qolsys-controller
3
- Version: 0.0.4
3
+ Version: 0.0.7
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/build.yml/badge.svg)](https://github.com/EHylands/QolsysController/actions/workflows/build.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:
@@ -5,13 +5,13 @@ qolsys_controller/errors.py,sha256=Z_eVJ4XqWucdn1lu_83DPnEKEG4L3FMfjhz5iO6RuBM,1
5
5
  qolsys_controller/mdns.py,sha256=3_d-_K5Fyxc-2s0Fo1advTSpD72P369Hou1Ko0z__Ag,606
6
6
  qolsys_controller/mqtt_command_queue.py,sha256=FjSbjK3_3SXV5eQPfQ-k8HOI5Tbu2aWzAxe4uXymK64,937
7
7
  qolsys_controller/observable.py,sha256=X7uMnBHGpklPTa-RHKldXA0Rq38Cs1yOIuxl8ODeKV4,1049
8
- qolsys_controller/panel.py,sha256=2y2MUG3YUsGL25SwXBzkoVZj1ijPAhOKTdW5lzPzfLg,39255
8
+ qolsys_controller/panel.py,sha256=1FSrAuhSoFfl-5-KttvCAItBm0SktYlq9ZPthYuXCvM,39456
9
9
  qolsys_controller/partition.py,sha256=-Fos327y3MlSWwJCbDeQM51-K8uMHANxIJ8kN9-S5CA,8045
10
10
  qolsys_controller/pki.py,sha256=OoaNtnf-ZAjG7yg-y8eu_9yvlIrZzruxuwl6dTojhQg,8663
11
11
  qolsys_controller/plugin.py,sha256=Qh0irFbuw9R2QF3jOFTJw70ceVxK1ld5_sW7VnpOrA8,819
12
12
  qolsys_controller/plugin_c4.py,sha256=71o5Y7Y13GO0vWCPIsCtpqXxrplryyqt8ua5L8F4StQ,382
13
- qolsys_controller/plugin_remote.py,sha256=kjPijZgNQwuX0DlCut7UIL3dnS1LWEfAUpvc---YrnM,36960
14
- qolsys_controller/settings.py,sha256=g6EjEO9AA09-CcSl-IpKQZBCHqamADVKra6dla8qV3Q,3589
13
+ qolsys_controller/plugin_remote.py,sha256=Kc2GC7oDQI2wPrKlk1TtCpeFSK-3AkQuAzUdTYId894,37794
14
+ qolsys_controller/settings.py,sha256=0cbp8UoIdyLYjDlnkIqrGm0ZDUkq3UlRhG2GXGx4_BM,5208
15
15
  qolsys_controller/state.py,sha256=eWn4KiWN75K83CVW224zekDUeIpgjh9tDfnpaOJWV3I,14360
16
16
  qolsys_controller/task_manager.py,sha256=IBFi1l9aId950wvRpvP6d4PHZhr3v1hnnt8NVulM3BI,1139
17
17
  qolsys_controller/utils_mqtt.py,sha256=2hf9_BnQbsWi8t0KBiK5MSsDgGjlbWVJi-Sd3H5VVt0,575
@@ -56,7 +56,7 @@ qolsys_controller/database/table_zwave_association_group.py,sha256=S_tWpfzzD44rJ
56
56
  qolsys_controller/database/table_zwave_history.py,sha256=4RiCzA_XFdXXVA9X48Z4eoxA_4DFKwdjkP2N6IHHOqQ,1897
57
57
  qolsys_controller/database/table_zwave_node.py,sha256=csESJCkcg8qAPn3KSL4jO9b1oymZ5wrQiXcmWR9vSc0,7302
58
58
  qolsys_controller/database/table_zwave_other.py,sha256=HJzLd4MUfNynE9jHiCzN7j1PFDncwQHeDkP5_8_s0YE,747
59
- qolsys_controller-0.0.4.dist-info/METADATA,sha256=xVy9B_UEwcNAOT1MB_yNN2EBw5GuIBcT8wzcnZhP1Kc,3835
60
- qolsys_controller-0.0.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
61
- qolsys_controller-0.0.4.dist-info/licenses/LICENSE,sha256=GBHv9eggdA5ablDMW1xiLzGDZ2gCIhcKGW__c2aVIOc,1069
62
- qolsys_controller-0.0.4.dist-info/RECORD,,
59
+ qolsys_controller-0.0.7.dist-info/METADATA,sha256=BoMf9sKljaf_faBT1gVOT6Z5tQoRfjN8tOvkfpBcFpk,4174
60
+ qolsys_controller-0.0.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
61
+ qolsys_controller-0.0.7.dist-info/licenses/LICENSE,sha256=GBHv9eggdA5ablDMW1xiLzGDZ2gCIhcKGW__c2aVIOc,1069
62
+ qolsys_controller-0.0.7.dist-info/RECORD,,