qolsys-controller 0.0.28__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 +18 -7
- qolsys_controller/database/db.py +31 -0
- qolsys_controller/database/table.py +36 -2
- qolsys_controller/database/table_doorlock.py +1 -0
- qolsys_controller/database/table_eu_event.py +11 -2
- qolsys_controller/database/table_powerg_device.py +25 -1
- qolsys_controller/database/table_sensor.py +2 -0
- qolsys_controller/database/table_user.py +1 -0
- qolsys_controller/database/table_zwave_node.py +1 -0
- qolsys_controller/database/table_zwave_other.py +14 -1
- qolsys_controller/enum.py +9 -5
- qolsys_controller/enum_zwave.py +0 -1
- qolsys_controller/mdns.py +8 -3
- qolsys_controller/panel.py +134 -45
- qolsys_controller/partition.py +14 -1
- qolsys_controller/plugin.py +10 -20
- qolsys_controller/plugin_c4.py +1 -1
- qolsys_controller/plugin_remote.py +165 -181
- qolsys_controller/settings.py +53 -19
- qolsys_controller/state.py +53 -13
- qolsys_controller/task_manager.py +18 -1
- qolsys_controller/weather.py +74 -0
- qolsys_controller/zone.py +148 -10
- qolsys_controller/zwave_device.py +1 -1
- qolsys_controller/zwave_lock.py +1 -1
- {qolsys_controller-0.0.28.dist-info → qolsys_controller-0.0.51.dist-info}/METADATA +5 -4
- {qolsys_controller-0.0.28.dist-info → qolsys_controller-0.0.51.dist-info}/RECORD +29 -28
- {qolsys_controller-0.0.28.dist-info → qolsys_controller-0.0.51.dist-info}/WHEEL +0 -0
- {qolsys_controller-0.0.28.dist-info → qolsys_controller-0.0.51.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,37 +1,42 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
2
4
|
import base64
|
|
5
|
+
import contextlib
|
|
3
6
|
import datetime
|
|
4
7
|
import json
|
|
5
8
|
import logging
|
|
6
9
|
import random
|
|
7
10
|
import ssl
|
|
8
11
|
import uuid
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
9
13
|
|
|
14
|
+
import aiofiles
|
|
10
15
|
import aiomqtt
|
|
11
16
|
|
|
12
17
|
from .enum import PartitionAlarmState, PartitionSystemStatus
|
|
13
|
-
from .enum_zwave import ThermostatFanMode, ThermostatMode
|
|
14
18
|
from .errors import QolsysMqttError, QolsysSslError
|
|
15
19
|
from .mdns import QolsysMDNS
|
|
16
20
|
from .mqtt_command_queue import QolsysMqttCommandQueue
|
|
17
|
-
from .panel import QolsysPanel
|
|
18
21
|
from .pki import QolsysPKI
|
|
19
22
|
from .plugin import QolsysPlugin
|
|
20
|
-
from .settings import QolsysSettings
|
|
21
|
-
from .state import QolsysState
|
|
22
23
|
from .task_manager import QolsysTaskManager
|
|
23
24
|
from .utils_mqtt import generate_random_mac
|
|
24
25
|
|
|
25
26
|
LOGGER = logging.getLogger(__name__)
|
|
26
27
|
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from .controller import QolsysController
|
|
30
|
+
from .enum_zwave import ThermostatFanMode, ThermostatMode
|
|
31
|
+
|
|
27
32
|
|
|
28
33
|
class QolsysPluginRemote(QolsysPlugin):
|
|
29
34
|
|
|
30
|
-
def __init__(self,
|
|
31
|
-
super().__init__(
|
|
35
|
+
def __init__(self, controller: QolsysController) -> None:
|
|
36
|
+
super().__init__(controller=controller)
|
|
32
37
|
|
|
33
38
|
# PKI
|
|
34
|
-
self._pki = QolsysPKI(settings=settings)
|
|
39
|
+
self._pki = QolsysPKI(settings=controller.settings)
|
|
35
40
|
self._auto_discover_pki = True
|
|
36
41
|
|
|
37
42
|
# Plugin
|
|
@@ -82,20 +87,14 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
82
87
|
self._auto_discover_pki = value
|
|
83
88
|
|
|
84
89
|
def is_paired(self) -> bool:
|
|
85
|
-
# Check if plugin is paired:
|
|
86
|
-
# 1- random_mac set
|
|
87
|
-
# 2- KEY file present
|
|
88
|
-
# 3- Signed certificate file present
|
|
89
|
-
# 4- Qolsys certificate present
|
|
90
|
-
# 5- Qolsys Panel IP present
|
|
91
90
|
return (
|
|
92
91
|
self._pki.id != "" and
|
|
93
92
|
self._pki.check_key_file() and
|
|
94
93
|
self._pki.check_cer_file() and
|
|
95
94
|
self._pki.check_qolsys_cer_file() and
|
|
96
95
|
self._pki.check_secure_file() and
|
|
97
|
-
self.settings.check_panel_ip() and
|
|
98
|
-
self.settings.check_plugin_ip()
|
|
96
|
+
self._controller.settings.check_panel_ip() and
|
|
97
|
+
self._controller.settings.check_plugin_ip()
|
|
99
98
|
)
|
|
100
99
|
|
|
101
100
|
async def config(self, start_pairing: bool) -> bool:
|
|
@@ -106,24 +105,24 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
106
105
|
super().config()
|
|
107
106
|
|
|
108
107
|
# Check and created config_directory
|
|
109
|
-
if not self.settings.check_config_directory(create=start_pairing):
|
|
108
|
+
if not self._controller.settings.check_config_directory(create=start_pairing):
|
|
110
109
|
return False
|
|
111
110
|
|
|
112
111
|
# Read user file for access code
|
|
113
112
|
loop = asyncio.get_running_loop()
|
|
114
|
-
if not loop.run_in_executor(None, self.panel.read_users_file):
|
|
113
|
+
if not loop.run_in_executor(None, self._controller.panel.read_users_file):
|
|
115
114
|
return False
|
|
116
115
|
|
|
117
116
|
# Config PKI
|
|
118
117
|
if self._auto_discover_pki:
|
|
119
118
|
if self._pki.auto_discover_pki():
|
|
120
|
-
self.settings.random_mac = self._pki.formatted_id()
|
|
119
|
+
self._controller.settings.random_mac = self._pki.formatted_id()
|
|
121
120
|
else:
|
|
122
|
-
self._pki.set_id(self.settings.random_mac)
|
|
121
|
+
self._pki.set_id(self._controller.settings.random_mac)
|
|
123
122
|
|
|
124
123
|
# Set mqtt_remote_client_id
|
|
125
|
-
self.settings.mqtt_remote_client_id = "qolsys-controller-" + self._pki.formatted_id()
|
|
126
|
-
LOGGER.debug("Using MQTT remoteClientID: %s", self.settings.mqtt_remote_client_id)
|
|
124
|
+
self._controller.settings.mqtt_remote_client_id = "qolsys-controller-" + self._pki.formatted_id()
|
|
125
|
+
LOGGER.debug("Using MQTT remoteClientID: %s", self._controller.settings.mqtt_remote_client_id)
|
|
127
126
|
|
|
128
127
|
# Check if plugin is paired
|
|
129
128
|
if self.is_paired():
|
|
@@ -146,7 +145,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
146
145
|
return True
|
|
147
146
|
|
|
148
147
|
async def start_operation(self) -> None:
|
|
149
|
-
await self._task_manager.run(self.mqtt_connect_task(reconnect=True), self._mqtt_task_connect_label)
|
|
148
|
+
await self._task_manager.run(self.mqtt_connect_task(reconnect=True, run_forever=True), self._mqtt_task_connect_label)
|
|
150
149
|
|
|
151
150
|
async def stop_operation(self) -> None:
|
|
152
151
|
LOGGER.debug("Stopping Plugin Operation")
|
|
@@ -166,7 +165,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
166
165
|
self.connected = False
|
|
167
166
|
self.connected_observer.notify()
|
|
168
167
|
|
|
169
|
-
async def mqtt_connect_task(self, reconnect: bool) -> None:
|
|
168
|
+
async def mqtt_connect_task(self, reconnect: bool, run_forever: bool) -> None:
|
|
170
169
|
# Configure TLS parameters for MQTT connection
|
|
171
170
|
tls_params = aiomqtt.TLSParameters(
|
|
172
171
|
ca_certs=self._pki.qolsys_cer_file_path,
|
|
@@ -179,73 +178,79 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
179
178
|
|
|
180
179
|
LOGGER.debug("MQTT: Connecting ...")
|
|
181
180
|
|
|
181
|
+
self._task_manager.cancel(self._mqtt_task_listen_label)
|
|
182
|
+
self._task_manager.cancel(self._mqtt_task_ping_label)
|
|
183
|
+
|
|
182
184
|
while True:
|
|
183
185
|
try:
|
|
184
186
|
self.aiomqtt = aiomqtt.Client(
|
|
185
|
-
hostname=self.settings.panel_ip,
|
|
187
|
+
hostname=self._controller.settings.panel_ip,
|
|
186
188
|
port=8883,
|
|
187
189
|
tls_params=tls_params,
|
|
188
190
|
tls_insecure=True,
|
|
189
191
|
clean_session=True,
|
|
190
|
-
timeout=self.settings.mqtt_timeout,
|
|
191
|
-
identifier=
|
|
192
|
+
timeout=self._controller.settings.mqtt_timeout,
|
|
193
|
+
identifier= self._controller.settings.mqtt_remote_client_id,
|
|
192
194
|
)
|
|
193
195
|
|
|
194
196
|
await self.aiomqtt.__aenter__()
|
|
195
197
|
|
|
196
198
|
LOGGER.info("MQTT: Client Connected")
|
|
197
199
|
|
|
198
|
-
# Subscribe to panel internal
|
|
200
|
+
# Subscribe to panel internal database updates
|
|
199
201
|
await self.aiomqtt.subscribe("iq2meid")
|
|
200
202
|
|
|
201
|
-
# Subscribte to MQTT
|
|
202
|
-
await self.aiomqtt.subscribe("response_" + self.settings.random_mac, qos=self.settings.mqtt_qos)
|
|
203
|
+
# Subscribte to MQTT private response
|
|
204
|
+
await self.aiomqtt.subscribe("response_" + self._controller.settings.random_mac, qos=self._controller.settings.mqtt_qos)
|
|
203
205
|
|
|
204
206
|
# Subscribe to Z-Wave response
|
|
205
|
-
await self.aiomqtt.subscribe("ZWAVE_RESPONSE", qos=self.settings.mqtt_qos)
|
|
207
|
+
await self.aiomqtt.subscribe("ZWAVE_RESPONSE", qos=self._controller.settings.mqtt_qos)
|
|
206
208
|
|
|
207
209
|
# Only log all traffic for debug purposes
|
|
208
210
|
if self.log_mqtt_mesages:
|
|
209
211
|
# Subscribe to MQTT commands send to panel by other devices
|
|
210
|
-
|
|
212
|
+
await self.aiomqtt.subscribe("mastermeid", qos=self._controller.settings.mqtt_qos)
|
|
211
213
|
|
|
212
214
|
# Subscribe to all topics
|
|
213
|
-
await self.aiomqtt.subscribe("#", qos=self.settings.mqtt_qos)
|
|
215
|
+
# await self.aiomqtt.subscribe("#", qos=self._controller.settings.mqtt_qos)
|
|
214
216
|
|
|
215
|
-
# Start mqtt_listent_task and mqtt_ping_task
|
|
216
|
-
self._task_manager.cancel(self._mqtt_task_listen_label)
|
|
217
|
-
self._task_manager.cancel(self._mqtt_task_ping_label)
|
|
218
217
|
self._task_manager.run(self.mqtt_listen_task(), self._mqtt_task_listen_label)
|
|
219
218
|
self._task_manager.run(self.mqtt_ping_task(), self._mqtt_task_ping_label)
|
|
220
219
|
|
|
221
220
|
response_connect = await self.command_connect()
|
|
222
|
-
self.panel.imei = response_connect.get("master_imei", "")
|
|
223
|
-
self.panel.product_type = response_connect.get("primary_product_type", "")
|
|
221
|
+
self._controller.panel.imei = response_connect.get("master_imei", "")
|
|
222
|
+
self._controller.panel.product_type = response_connect.get("primary_product_type", "")
|
|
224
223
|
|
|
225
224
|
await self.command_pingevent()
|
|
226
|
-
await self.command_timesync()
|
|
227
225
|
await self.command_pair_status_request()
|
|
228
226
|
|
|
229
227
|
response_database = await self.command_sync_database()
|
|
230
228
|
LOGGER.debug("MQTT: Updating State from syncdatabase")
|
|
231
|
-
self.panel.load_database(response_database.get("fulldbdata"))
|
|
232
|
-
self.panel.dump()
|
|
233
|
-
self.state.dump()
|
|
229
|
+
self._controller.panel.load_database(response_database.get("fulldbdata"))
|
|
230
|
+
self._controller.panel.dump()
|
|
231
|
+
self._controller.state.dump()
|
|
234
232
|
|
|
235
233
|
self.connected = True
|
|
236
234
|
self.connected_observer.notify()
|
|
235
|
+
|
|
236
|
+
if not run_forever:
|
|
237
|
+
self.connected = False
|
|
238
|
+
self.connected_observer.notify()
|
|
239
|
+
self._task_manager.cancel(self._mqtt_task_listen_label)
|
|
240
|
+
self._task_manager.cancel(self._mqtt_task_ping_label)
|
|
241
|
+
await self.aiomqtt.__aexit__(None,None,None)
|
|
242
|
+
|
|
237
243
|
break
|
|
238
244
|
|
|
239
245
|
except aiomqtt.MqttError as err:
|
|
240
246
|
# Receive pannel network error
|
|
241
247
|
self.connected = False
|
|
242
248
|
self.connected_observer.notify()
|
|
243
|
-
await self.aiomqtt.__aexit__(None, None, None)
|
|
244
249
|
self.aiomqtt = None
|
|
245
250
|
|
|
246
251
|
if reconnect:
|
|
247
|
-
LOGGER.debug("MQTT Error - %s: Reconnecting in %s seconds ...", err, self.settings.mqtt_timeout)
|
|
248
|
-
await asyncio.sleep(self.settings.mqtt_timeout)
|
|
252
|
+
LOGGER.debug("MQTT Error - %s: Connect - Reconnecting in %s seconds ...", err, self._controller.settings.mqtt_timeout)
|
|
253
|
+
await asyncio.sleep(self._controller.settings.mqtt_timeout)
|
|
249
254
|
else:
|
|
250
255
|
raise QolsysMqttError from err
|
|
251
256
|
|
|
@@ -255,16 +260,16 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
255
260
|
# Pannels need to be re-paired
|
|
256
261
|
self.connected = False
|
|
257
262
|
self.connected_observer.notify()
|
|
258
|
-
await self.aiomqtt.__aexit__(None, None, None)
|
|
259
263
|
self.aiomqtt = None
|
|
260
264
|
raise QolsysSslError from err
|
|
261
265
|
|
|
262
266
|
async def mqtt_ping_task(self) -> None:
|
|
263
267
|
while True:
|
|
264
268
|
if self.aiomqtt is not None and self.connected:
|
|
265
|
-
|
|
269
|
+
with contextlib.suppress(aiomqtt.MqttError):
|
|
270
|
+
await self.command_pingevent()
|
|
266
271
|
|
|
267
|
-
await asyncio.sleep(self.settings.mqtt_ping)
|
|
272
|
+
await asyncio.sleep(self._controller.settings.mqtt_ping)
|
|
268
273
|
|
|
269
274
|
async def mqtt_listen_task(self) -> None:
|
|
270
275
|
try:
|
|
@@ -274,17 +279,15 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
274
279
|
LOGGER.debug("MQTT TOPIC: %s\n%s", message.topic, message.payload.decode())
|
|
275
280
|
|
|
276
281
|
# Panel response to MQTT Commands
|
|
277
|
-
if message.topic.matches("response_" + self.settings.random_mac):
|
|
282
|
+
if message.topic.matches("response_" + self._controller.settings.random_mac):
|
|
278
283
|
data = message.payload.decode()
|
|
279
|
-
# data = message.payload.decode().replace("\\\\", "\\")
|
|
280
|
-
# data = fix_json_string(data)
|
|
281
284
|
data = json.loads(data)
|
|
282
285
|
await self._mqtt_command_queue.handle_response(data)
|
|
283
286
|
|
|
284
287
|
# Panel updates to IQ2MEID database
|
|
285
288
|
if message.topic.matches("iq2meid"):
|
|
286
289
|
data = json.loads(message.payload.decode())
|
|
287
|
-
self.panel.parse_iq2meid_message(data)
|
|
290
|
+
self._controller.panel.parse_iq2meid_message(data)
|
|
288
291
|
|
|
289
292
|
# Panel Z-Wave response
|
|
290
293
|
if message.topic.matches("ZWAVE_RESPONSE"):
|
|
@@ -293,34 +296,23 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
293
296
|
decoded_payload = base64.b64decode(zwave.get("ZWAVE_PAYLOAD","")).hex()
|
|
294
297
|
LOGGER.debug("Z-Wave Response: Node(%s) - Status(%s) - Payload(%s)",zwave.get("NODE_ID",""),zwave.get("ZWAVE_COMMAND_STATUS",""),decoded_payload)
|
|
295
298
|
|
|
296
|
-
|
|
297
299
|
except aiomqtt.MqttError as err:
|
|
298
300
|
self.connected = False
|
|
299
301
|
self.connected_observer.notify()
|
|
300
302
|
|
|
301
|
-
LOGGER.debug("%s: Reconnecting in %s seconds ...", err, self.settings.mqtt_timeout)
|
|
302
|
-
await asyncio.sleep(self.settings.mqtt_timeout)
|
|
303
|
-
self._task_manager.run(self.mqtt_connect_task(reconnect=True), self._mqtt_task_connect_label)
|
|
304
|
-
|
|
305
|
-
except ssl.SSLError as err:
|
|
306
|
-
# SSL error is and authentication error with invalid certificates en pki
|
|
307
|
-
# We cannot recover from this error automaticly
|
|
308
|
-
# Pannels need to be re-paired
|
|
309
|
-
self.connected = False
|
|
310
|
-
self.connected_observer.notify()
|
|
311
|
-
await self.aiomqtt.__aexit__(None, None, None)
|
|
312
|
-
self.aiomqtt = None
|
|
313
|
-
raise QolsysSslError from err
|
|
303
|
+
LOGGER.debug("%s: Listen - Reconnecting in %s seconds ...", err, self._controller.settings.mqtt_timeout)
|
|
304
|
+
await asyncio.sleep(self._controller.settings.mqtt_timeout)
|
|
305
|
+
self._task_manager.run(self.mqtt_connect_task(reconnect=True, run_forever=True), self._mqtt_task_connect_label)
|
|
314
306
|
|
|
315
307
|
async def start_initial_pairing(self) -> bool:
|
|
316
308
|
# check if random_mac exist
|
|
317
|
-
if self.settings.random_mac == "":
|
|
309
|
+
if self._controller.settings.random_mac == "":
|
|
318
310
|
LOGGER.debug("Creating random_mac")
|
|
319
|
-
self.settings.random_mac = generate_random_mac()
|
|
320
|
-
self._pki.create(self.settings.random_mac, key_size=self.settings.key_size)
|
|
311
|
+
self._controller.settings.random_mac = generate_random_mac()
|
|
312
|
+
self._pki.create(self._controller.settings.random_mac, key_size=self._controller.settings.key_size)
|
|
321
313
|
|
|
322
314
|
# Check if PKI is valid
|
|
323
|
-
self._pki.set_id(self.settings.random_mac)
|
|
315
|
+
self._pki.set_id(self._controller.settings.random_mac)
|
|
324
316
|
LOGGER.debug("Checking PKI")
|
|
325
317
|
if not (
|
|
326
318
|
self._pki.check_key_file() and
|
|
@@ -332,19 +324,19 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
332
324
|
|
|
333
325
|
LOGGER.debug("Starting Pairing Process")
|
|
334
326
|
|
|
335
|
-
if not self.settings.check_plugin_ip():
|
|
327
|
+
if not self._controller.settings.check_plugin_ip():
|
|
336
328
|
LOGGER.error("Plugin IP Address not configured")
|
|
337
329
|
return False
|
|
338
330
|
|
|
339
331
|
# If we dont allready have client signed certificate, start the pairing server
|
|
340
|
-
if not self._pki.check_secure_file() or not self._pki.check_qolsys_cer_file() or not self.settings.check_panel_ip():
|
|
332
|
+
if not self._pki.check_secure_file() or not self._pki.check_qolsys_cer_file() or not self._controller.settings.check_panel_ip():
|
|
341
333
|
|
|
342
334
|
# High Level Random Pairing Port
|
|
343
335
|
pairing_port = random.randint(50000, 55000)
|
|
344
336
|
|
|
345
337
|
# Start Pairing mDNS Brodcast
|
|
346
|
-
LOGGER.debug("Starting mDNS Service Discovery: %s:%s", self.settings.plugin_ip, str(pairing_port))
|
|
347
|
-
mdns_server = QolsysMDNS(self.settings.plugin_ip, pairing_port)
|
|
338
|
+
LOGGER.debug("Starting mDNS Service Discovery: %s:%s", self._controller.settings.plugin_ip, str(pairing_port))
|
|
339
|
+
mdns_server = QolsysMDNS(self._controller.settings.plugin_ip, pairing_port)
|
|
348
340
|
await mdns_server.start_mdns()
|
|
349
341
|
|
|
350
342
|
# Start Key Exchange Server
|
|
@@ -352,8 +344,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
352
344
|
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
|
353
345
|
context.load_cert_chain(certfile=self._pki.cer_file_path, keyfile=self._pki.key_file_path)
|
|
354
346
|
self.certificate_exchange_server = await asyncio.start_server(self.handle_key_exchange_client,
|
|
355
|
-
self.settings.plugin_ip, pairing_port, ssl=context)
|
|
356
|
-
|
|
347
|
+
self._controller.settings.plugin_ip, pairing_port, ssl=context)
|
|
357
348
|
LOGGER.debug("Certificate Exchange Server Waiting for Panel")
|
|
358
349
|
LOGGER.debug("Press Pair Button in IQ Remote Config Page ...")
|
|
359
350
|
|
|
@@ -363,6 +354,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
363
354
|
|
|
364
355
|
except asyncio.CancelledError:
|
|
365
356
|
LOGGER.debug("Stoping Certificate Exchange Server")
|
|
357
|
+
await self.certificate_exchange_server.wait_closed()
|
|
366
358
|
LOGGER.debug("Stoping mDNS Service Discovery")
|
|
367
359
|
await mdns_server.stop_mdns()
|
|
368
360
|
|
|
@@ -370,19 +362,16 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
370
362
|
|
|
371
363
|
# We have client sgined certificate at this point
|
|
372
364
|
# Connect to Panel MQTT to send pairing command
|
|
373
|
-
await self._task_manager.run(self.mqtt_connect_task(reconnect=False), self._mqtt_task_connect_label)
|
|
365
|
+
await self._task_manager.run(self.mqtt_connect_task(reconnect=False, run_forever=False), self._mqtt_task_connect_label)
|
|
374
366
|
LOGGER.debug("Plugin Pairing Completed ")
|
|
375
367
|
return True
|
|
376
368
|
|
|
377
|
-
async def handle_key_exchange_client(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None:
|
|
369
|
+
async def handle_key_exchange_client(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None: # noqa: PLR0915
|
|
378
370
|
|
|
379
371
|
received_panel_mac = False
|
|
380
372
|
received_signed_client_certificate = False
|
|
381
373
|
received_qolsys_cer = False
|
|
382
374
|
|
|
383
|
-
signed_certificate_data = ""
|
|
384
|
-
qolsys_certificate_data = ""
|
|
385
|
-
|
|
386
375
|
try:
|
|
387
376
|
continue_pairing = True
|
|
388
377
|
while continue_pairing:
|
|
@@ -398,19 +387,19 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
398
387
|
LOGGER.debug("Receiving from Panel: %s", mac)
|
|
399
388
|
|
|
400
389
|
# Remove \x00 and \x01 from received string
|
|
401
|
-
self.settings.panel_mac = "".join(char for char in mac if char.isprintable())
|
|
402
|
-
self.settings.panel_ip = address
|
|
390
|
+
self._controller.settings.panel_mac = "".join(char for char in mac if char.isprintable())
|
|
391
|
+
self._controller.settings.panel_ip = address
|
|
403
392
|
received_panel_mac = True
|
|
404
393
|
|
|
405
394
|
# Sending random_mac to panel
|
|
406
|
-
message = b"\x00\x11" + self.settings.random_mac.encode()
|
|
395
|
+
message = b"\x00\x11" + self._controller.settings.random_mac.encode()
|
|
407
396
|
LOGGER.debug("Sending to Panel: %s", message.decode())
|
|
408
397
|
writer.write(message)
|
|
409
398
|
await writer.drain()
|
|
410
399
|
|
|
411
400
|
# Sending CSR File to panel
|
|
412
|
-
with open(self._pki.csr_file_path, "rb") as
|
|
413
|
-
content =
|
|
401
|
+
async with aiofiles.open(self._pki.csr_file_path, mode="rb") as f:
|
|
402
|
+
content = await f.read()
|
|
414
403
|
LOGGER.debug("Sending to Panel: [CSR File Content]")
|
|
415
404
|
writer.write(content)
|
|
416
405
|
writer.write(b"sent")
|
|
@@ -420,36 +409,26 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
420
409
|
|
|
421
410
|
# Read signed certificate data
|
|
422
411
|
if (received_panel_mac and not received_signed_client_certificate and not received_qolsys_cer):
|
|
412
|
+
request = await reader.readuntil(b"sent")
|
|
413
|
+
if request.endswith(b"sent"):
|
|
414
|
+
request = request[:-4]
|
|
423
415
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
certificates = [item for item in signed_certificate_data.split("sent") if item]
|
|
429
|
-
LOGGER.debug("Saving [Signed Client Certificate]")
|
|
430
|
-
with open(self._pki.secure_file_path, "wb") as f:
|
|
431
|
-
f.write(certificates[0].encode())
|
|
432
|
-
received_signed_client_certificate = True
|
|
433
|
-
|
|
434
|
-
if len(certificates) > 1:
|
|
435
|
-
qolsys_certificate_data += certificates[1]
|
|
416
|
+
LOGGER.debug("Saving [Signed Client Certificate]")
|
|
417
|
+
async with aiofiles.open(self._pki.secure_file_path, mode="wb") as f:
|
|
418
|
+
await f.write(request)
|
|
419
|
+
received_signed_client_certificate = True
|
|
436
420
|
|
|
437
421
|
# Read qolsys certificate data
|
|
438
422
|
if (received_panel_mac and received_signed_client_certificate and not received_qolsys_cer):
|
|
439
|
-
|
|
440
|
-
request
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
423
|
+
request = await reader.readuntil(b"sent")
|
|
424
|
+
if request.endswith(b"sent"):
|
|
425
|
+
request = request[:-4]
|
|
426
|
+
|
|
427
|
+
LOGGER.debug("Saving [Qolsys Certificate]")
|
|
428
|
+
async with aiofiles.open(self._pki.qolsys_cer_file_path, mode="wb") as f:
|
|
429
|
+
await f.write(request)
|
|
430
|
+
received_qolsys_cer = True
|
|
444
431
|
continue_pairing = False
|
|
445
|
-
certificates = [item for item in qolsys_certificate_data.split("sent") if item]
|
|
446
|
-
|
|
447
|
-
LOGGER.debug("Saving [Qolsys Certificate]")
|
|
448
|
-
with open(self._pki.qolsys_cer_file_path, "w") as f:
|
|
449
|
-
f.write(certificates[0])
|
|
450
|
-
received_qolsys_cer = True
|
|
451
|
-
continue_pairing = False
|
|
452
|
-
writer.close()
|
|
453
432
|
|
|
454
433
|
continue
|
|
455
434
|
|
|
@@ -461,6 +440,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
461
440
|
|
|
462
441
|
finally:
|
|
463
442
|
writer.close()
|
|
443
|
+
await writer.wait_closed()
|
|
464
444
|
self.certificate_exchange_server.close()
|
|
465
445
|
|
|
466
446
|
async def send_command(self, topic: str, json_payload: str, request_id: str) -> dict:
|
|
@@ -468,17 +448,17 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
468
448
|
LOGGER.error("MQTT Client not configured")
|
|
469
449
|
raise QolsysMqttError
|
|
470
450
|
|
|
471
|
-
await self.aiomqtt.publish(topic=topic, payload=json.dumps(json_payload), qos=self.settings.mqtt_qos)
|
|
451
|
+
await self.aiomqtt.publish(topic=topic, payload=json.dumps(json_payload), qos=self._controller.settings.mqtt_qos)
|
|
472
452
|
return await self._mqtt_command_queue.wait_for_response(request_id)
|
|
473
453
|
|
|
474
454
|
async def command_connect(self) -> dict:
|
|
475
455
|
LOGGER.debug("MQTT: Sending connect command")
|
|
476
456
|
|
|
477
457
|
topic = "mastermeid"
|
|
478
|
-
ipAddress = self.settings.plugin_ip
|
|
458
|
+
ipAddress = self._controller.settings.plugin_ip
|
|
479
459
|
eventName = "connect_v204"
|
|
480
|
-
macAddress = self.settings.random_mac
|
|
481
|
-
remoteClientID = self.settings.mqtt_remote_client_id
|
|
460
|
+
macAddress = self._controller.settings.random_mac
|
|
461
|
+
remoteClientID = self._controller.settings.mqtt_remote_client_id
|
|
482
462
|
softwareVersion = "4.4.1"
|
|
483
463
|
producType = "tab07_rk68"
|
|
484
464
|
bssid = ""
|
|
@@ -497,8 +477,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
497
477
|
remote_panel_plugged = 1
|
|
498
478
|
remote_panel_battery_temperature = 430
|
|
499
479
|
requestID = str(uuid.uuid4())
|
|
500
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
501
|
-
remoteMacAddress = self.settings.random_mac
|
|
480
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
481
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
502
482
|
|
|
503
483
|
dhcpInfo = {
|
|
504
484
|
"ipaddress": "",
|
|
@@ -548,9 +528,9 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
548
528
|
|
|
549
529
|
topic = "mastermeid"
|
|
550
530
|
eventName = "pingevent"
|
|
551
|
-
macAddress = self.settings.random_mac
|
|
531
|
+
macAddress = self._controller.settings.random_mac
|
|
552
532
|
remote_panel_status = "Active"
|
|
553
|
-
ipAddress = self.settings.plugin_ip
|
|
533
|
+
ipAddress = self._controller.settings.plugin_ip
|
|
554
534
|
current_battery_status = "Normal"
|
|
555
535
|
remote_panel_battery_percentage = 100
|
|
556
536
|
remote_panel_battery_temperature = 430
|
|
@@ -563,8 +543,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
563
543
|
remote_panel_battery_health = 2
|
|
564
544
|
remote_panel_plugged = 1
|
|
565
545
|
requestID = str(uuid.uuid4())
|
|
566
|
-
remoteMacAddress = self.settings.random_mac
|
|
567
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
546
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
547
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
568
548
|
|
|
569
549
|
payload = {
|
|
570
550
|
"eventName": eventName,
|
|
@@ -597,8 +577,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
597
577
|
eventName = "timeSync"
|
|
598
578
|
startTimestamp = datetime.datetime.now().timestamp()
|
|
599
579
|
requestID = str(uuid.uuid4())
|
|
600
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
601
|
-
remoteMacAddress = self.settings.random_mac
|
|
580
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
581
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
602
582
|
|
|
603
583
|
payload = {
|
|
604
584
|
"eventName": eventName,
|
|
@@ -617,8 +597,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
617
597
|
topic = "mastermeid"
|
|
618
598
|
eventName = "syncdatabase"
|
|
619
599
|
requestID = str(uuid.uuid4())
|
|
620
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
621
|
-
remoteMacAddress = self.settings.random_mac
|
|
600
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
601
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
622
602
|
|
|
623
603
|
payload = {
|
|
624
604
|
"eventName": eventName,
|
|
@@ -637,8 +617,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
637
617
|
topic = "mastermeid"
|
|
638
618
|
eventName = "acStatus"
|
|
639
619
|
requestID = str(uuid.uuid4())
|
|
640
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
641
|
-
remoteMacAddress = self.settings.random_mac
|
|
620
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
621
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
642
622
|
acStatus = "Connected"
|
|
643
623
|
|
|
644
624
|
payload = {"eventName": eventName,
|
|
@@ -655,8 +635,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
655
635
|
topic = "mastermeid"
|
|
656
636
|
eventName = "dealerLogo"
|
|
657
637
|
requestID = str(uuid.uuid4())
|
|
658
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
659
|
-
remoteMacAddress = self.settings.random_mac
|
|
638
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
639
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
660
640
|
|
|
661
641
|
payload = {
|
|
662
642
|
"eventName": eventName,
|
|
@@ -672,9 +652,9 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
672
652
|
|
|
673
653
|
topic = "mastermeid"
|
|
674
654
|
eventName = "pair_status_request"
|
|
675
|
-
remoteMacAddress = self.settings.random_mac
|
|
655
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
676
656
|
requestID = str(uuid.uuid4())
|
|
677
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
657
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
678
658
|
|
|
679
659
|
payload = {
|
|
680
660
|
"eventName": eventName,
|
|
@@ -691,9 +671,9 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
691
671
|
|
|
692
672
|
topic = "mastermeid"
|
|
693
673
|
eventName = "disconnect"
|
|
694
|
-
remoteClientID = self.settings.mqtt_remote_client_id
|
|
674
|
+
remoteClientID = self._controller.settings.mqtt_remote_client_id
|
|
695
675
|
requestID = str(uuid.uuid4())
|
|
696
|
-
remoteMacAddress = self.settings.random_mac
|
|
676
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
697
677
|
|
|
698
678
|
payload = {
|
|
699
679
|
"eventName": eventName,
|
|
@@ -710,9 +690,9 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
710
690
|
topic = "mastermeid"
|
|
711
691
|
eventName = "connect_v204"
|
|
712
692
|
pairing_request = True
|
|
713
|
-
ipAddress = self.settings.plugin_ip
|
|
714
|
-
macAddress = self.settings.random_mac
|
|
715
|
-
remoteClientID = self.settings.mqtt_remote_client_id
|
|
693
|
+
ipAddress = self._controller.settings.plugin_ip
|
|
694
|
+
macAddress = self._controller.settings.random_mac
|
|
695
|
+
remoteClientID = self._controller.settings.mqtt_remote_client_id
|
|
716
696
|
softwareVersion = "4.4.1"
|
|
717
697
|
productType = "tab07_rk68"
|
|
718
698
|
bssid = ""
|
|
@@ -720,8 +700,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
720
700
|
dealerIconsCheckSum = ""
|
|
721
701
|
remote_feature_support_version = "1"
|
|
722
702
|
requestID = str(uuid.uuid4())
|
|
723
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
724
|
-
remoteMacAddress = self.settings.random_mac
|
|
703
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
704
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
725
705
|
|
|
726
706
|
dhcpInfo = {
|
|
727
707
|
"ipaddress": "",
|
|
@@ -759,7 +739,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
759
739
|
LOGGER.debug("MQTT: Sending ui_delay command")
|
|
760
740
|
|
|
761
741
|
# partition state needs to be sent for ui_delay to work
|
|
762
|
-
partition = self.state.partition(partition_id)
|
|
742
|
+
partition = self._controller.state.partition(partition_id)
|
|
763
743
|
|
|
764
744
|
arming_command = {
|
|
765
745
|
"operation_name": "ui_delay",
|
|
@@ -768,7 +748,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
768
748
|
"partitionID": partition_id, # STR EXPECTED
|
|
769
749
|
"silentDisarming":silent_disarming,
|
|
770
750
|
"operation_source": 1,
|
|
771
|
-
"macAddress": self.settings.random_mac,
|
|
751
|
+
"macAddress": self._controller.settings.random_mac,
|
|
772
752
|
}
|
|
773
753
|
|
|
774
754
|
topic = "mastermeid"
|
|
@@ -777,8 +757,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
777
757
|
ipcInterfaceName = "android.os.IQInternalService"
|
|
778
758
|
ipcTransactionID = 7
|
|
779
759
|
requestID = str(uuid.uuid4())
|
|
780
|
-
remoteMacAddress = self.settings.random_mac
|
|
781
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
760
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
761
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
782
762
|
|
|
783
763
|
payload = {
|
|
784
764
|
"eventName": eventName,
|
|
@@ -798,7 +778,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
798
778
|
LOGGER.debug("MQTT: Receiving ui_delay command")
|
|
799
779
|
|
|
800
780
|
async def command_disarm(self, partition_id: str, user_code: str = "", silent_disarming: bool = False) -> bool:
|
|
801
|
-
partition = self.state.partition(partition_id)
|
|
781
|
+
partition = self._controller.state.partition(partition_id)
|
|
802
782
|
if not partition:
|
|
803
783
|
LOGGER.debug("MQTT: disarm command error - Unknow Partition")
|
|
804
784
|
return False
|
|
@@ -806,7 +786,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
806
786
|
# Do local user code verification
|
|
807
787
|
user_id = 1
|
|
808
788
|
if self.check_user_code_on_disarm:
|
|
809
|
-
user_id = self.panel.check_user(user_code)
|
|
789
|
+
user_id = self._controller.panel.check_user(user_code)
|
|
810
790
|
if user_id == -1:
|
|
811
791
|
LOGGER.debug("MQTT: disarm command error - user_code error")
|
|
812
792
|
return False
|
|
@@ -834,7 +814,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
834
814
|
"userID": user_id,
|
|
835
815
|
"partitionID": int(partition_id), # INT EXPECTED
|
|
836
816
|
"operation_source": 1,
|
|
837
|
-
"macAddress": self.settings.random_mac,
|
|
817
|
+
"macAddress": self._controller.settings.random_mac,
|
|
838
818
|
}
|
|
839
819
|
|
|
840
820
|
topic = "mastermeid"
|
|
@@ -843,8 +823,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
843
823
|
ipcInterfaceName = "android.os.IQInternalService"
|
|
844
824
|
ipcTransactionID = 7
|
|
845
825
|
requestID = str(uuid.uuid4())
|
|
846
|
-
remoteMacAddress = self.settings.random_mac
|
|
847
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
826
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
827
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
848
828
|
|
|
849
829
|
payload = {"eventName": eventName,
|
|
850
830
|
"ipcServiceName": ipcServiceName,
|
|
@@ -867,10 +847,10 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
867
847
|
LOGGER.debug("MQTT: Sending zwave_doorlock_set command: EXPERIMENTAL")
|
|
868
848
|
LOGGER.debug("MQTT: Sending zwave_doorlock_set command - Node(%s) - Locked(%s)",node_id,locked)
|
|
869
849
|
|
|
870
|
-
command =
|
|
850
|
+
command = 98
|
|
871
851
|
|
|
872
852
|
# 0 unlocked
|
|
873
|
-
# 255
|
|
853
|
+
# 255 locked
|
|
874
854
|
lock_mode = 0
|
|
875
855
|
if locked:
|
|
876
856
|
lock_mode = 255
|
|
@@ -885,7 +865,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
885
865
|
},
|
|
886
866
|
{
|
|
887
867
|
"dataType": "byteArray",
|
|
888
|
-
"dataValue": [command,lock_mode],
|
|
868
|
+
"dataValue": [command,1,lock_mode],
|
|
889
869
|
},
|
|
890
870
|
{
|
|
891
871
|
"dataType": "int",
|
|
@@ -907,8 +887,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
907
887
|
ipcInterfaceName = "android.os.IQZwaveService"
|
|
908
888
|
ipcTransactionID = 47
|
|
909
889
|
requestID = str(uuid.uuid4())
|
|
910
|
-
remoteMacAddress = self.settings.random_mac
|
|
911
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
890
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
891
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
912
892
|
|
|
913
893
|
payload = {
|
|
914
894
|
"eventName": eventName,
|
|
@@ -927,7 +907,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
927
907
|
async def command_zwave_thermostat_setpoint_set(self, node_id: int, mode:ThermostatMode, setpoint:float) -> None:
|
|
928
908
|
# Command 67
|
|
929
909
|
LOGGER.debug("MQTT: Sending zwave_thermostat_setpoint_set command: EXPERIMENTAL")
|
|
930
|
-
LOGGER.debug("MQTT: Sending zwave_thermostat_setpoint_set
|
|
910
|
+
LOGGER.debug("MQTT: Sending zwave_thermostat_setpoint_set - Node(%s) - Mode(%s) - Setpoint(%s)",node_id,mode,setpoint)
|
|
931
911
|
ipcRequest = [{
|
|
932
912
|
"dataType": "int",
|
|
933
913
|
"dataValue": node_id,
|
|
@@ -960,8 +940,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
960
940
|
ipcInterfaceName = "android.os.IQZwaveService"
|
|
961
941
|
ipcTransactionID = 47
|
|
962
942
|
requestID = str(uuid.uuid4())
|
|
963
|
-
remoteMacAddress = self.settings.random_mac
|
|
964
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
943
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
944
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
965
945
|
|
|
966
946
|
payload = {"eventName": eventName,
|
|
967
947
|
"ipcServiceName": ipcServiceName,
|
|
@@ -978,7 +958,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
978
958
|
async def command_zwave_thermostat_mode_set(self, node_id: int, mode:ThermostatMode) -> None:
|
|
979
959
|
# Command 64
|
|
980
960
|
LOGGER.debug("MQTT: Sending zwave_thermostat_mode_set command: EXPERIMENTAL")
|
|
981
|
-
LOGGER.debug("MQTT: Sending zwave_thermostat_mode_set command")
|
|
961
|
+
LOGGER.debug("MQTT: Sending zwave_thermostat_mode_set command - Node(%s) - Mode(%s)",node_id,mode)
|
|
982
962
|
ipcRequest = [{
|
|
983
963
|
"dataType": "int",
|
|
984
964
|
"dataValue": node_id,
|
|
@@ -1011,8 +991,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1011
991
|
ipcInterfaceName = "android.os.IQZwaveService"
|
|
1012
992
|
ipcTransactionID = 47
|
|
1013
993
|
requestID = str(uuid.uuid4())
|
|
1014
|
-
remoteMacAddress = self.settings.random_mac
|
|
1015
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
994
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
995
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
1016
996
|
|
|
1017
997
|
payload = {
|
|
1018
998
|
"eventName": eventName,
|
|
@@ -1022,7 +1002,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1022
1002
|
"ipcRequest": ipcRequest,
|
|
1023
1003
|
"requestID": requestID,
|
|
1024
1004
|
"responseTopic": responseTopic,
|
|
1025
|
-
"remoteMacAddress": remoteMacAddress
|
|
1005
|
+
"remoteMacAddress": remoteMacAddress,
|
|
1026
1006
|
}
|
|
1027
1007
|
|
|
1028
1008
|
await self.send_command(topic, payload, requestID)
|
|
@@ -1031,7 +1011,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1031
1011
|
async def command_zwave_thermostat_fan_mode_set(self, node_id: int, fan_mode:ThermostatFanMode) -> None:
|
|
1032
1012
|
# Command 68
|
|
1033
1013
|
LOGGER.debug("MQTT: Sending zwave_thermostat_fan_mode_set command: EXPERIMENTAL")
|
|
1034
|
-
LOGGER.debug("MQTT: Sending zwave_thermostat_fan_mode_set command")
|
|
1014
|
+
LOGGER.debug("MQTT: Sending zwave_thermostat_fan_mode_set command - Node(%s) - FanMode(%s)",node_id,fan_mode)
|
|
1035
1015
|
ipcRequest = [{
|
|
1036
1016
|
"dataType": "int",
|
|
1037
1017
|
"dataValue": node_id,
|
|
@@ -1064,8 +1044,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1064
1044
|
ipcInterfaceName = "android.os.IQZwaveService"
|
|
1065
1045
|
ipcTransactionID = 47
|
|
1066
1046
|
requestID = str(uuid.uuid4())
|
|
1067
|
-
remoteMacAddress = self.settings.random_mac
|
|
1068
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
1047
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
1048
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
1069
1049
|
|
|
1070
1050
|
payload = {"eventName": eventName,
|
|
1071
1051
|
"ipcServiceName": ipcServiceName,
|
|
@@ -1080,7 +1060,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1080
1060
|
LOGGER.debug("MQTT: Receiving zwave_thermostat_fan_mode_set command")
|
|
1081
1061
|
|
|
1082
1062
|
async def command_zwave_switch_multi_level(self, node_id: int, level: int) -> None:
|
|
1083
|
-
LOGGER.debug("MQTT: Sending zwave_switch_multi_level command")
|
|
1063
|
+
LOGGER.debug("MQTT: Sending zwave_switch_multi_level command - Node(%s) - Level(%s)",node_id,level)
|
|
1084
1064
|
ipcRequest = [{
|
|
1085
1065
|
"dataType": "int", # Node ID
|
|
1086
1066
|
"dataValue": node_id,
|
|
@@ -1114,8 +1094,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1114
1094
|
ipcInterfaceName = "android.os.IQZwaveService"
|
|
1115
1095
|
ipcTransactionID = 47
|
|
1116
1096
|
requestID = str(uuid.uuid4())
|
|
1117
|
-
remoteMacAddress = self.settings.random_mac
|
|
1118
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
1097
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
1098
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
1119
1099
|
|
|
1120
1100
|
payload = {"eventName": eventName,
|
|
1121
1101
|
"ipcServiceName": ipcServiceName,
|
|
@@ -1168,8 +1148,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1168
1148
|
ipcInterfaceName = "android.os.IQZwaveService"
|
|
1169
1149
|
ipcTransactionID = 47
|
|
1170
1150
|
requestID = str(uuid.uuid4())
|
|
1171
|
-
remoteMacAddress = self.settings.random_mac
|
|
1172
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
1151
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
1152
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
1173
1153
|
|
|
1174
1154
|
payload = {"eventName": eventName,
|
|
1175
1155
|
"ipcServiceName": ipcServiceName,
|
|
@@ -1184,22 +1164,22 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1184
1164
|
LOGGER.debug("MQTT:Receiving zwave_switch_binary command")
|
|
1185
1165
|
|
|
1186
1166
|
|
|
1187
|
-
async def command_arm(self, partition_id: str, arming_type: str, user_code: str = "", exit_sounds: bool = False,
|
|
1188
|
-
instant_arm: bool = False) -> bool:
|
|
1167
|
+
async def command_arm(self, partition_id: str, arming_type: str, user_code: str = "", exit_sounds: bool = False, # noqa: PLR0913
|
|
1168
|
+
instant_arm: bool = False, entry_delay: bool = True) -> bool:
|
|
1189
1169
|
|
|
1190
|
-
LOGGER.debug("MQTT: Sending arm command: partition%s, arming_type:%s,
|
|
1191
|
-
partition_id, arming_type,
|
|
1170
|
+
LOGGER.debug("MQTT: Sending arm command: partition%s, arming_type:%s, exit_sounds:%s, instant_arm: %s, entry_delay:%s",
|
|
1171
|
+
partition_id, arming_type,exit_sounds,instant_arm,entry_delay)
|
|
1192
1172
|
|
|
1193
1173
|
user_id = 0
|
|
1194
1174
|
|
|
1195
|
-
partition = self.state.partition(partition_id)
|
|
1175
|
+
partition = self._controller.state.partition(partition_id)
|
|
1196
1176
|
if not partition:
|
|
1197
1177
|
LOGGER.debug("MQTT: arm command error - Unknow Partition")
|
|
1198
1178
|
return False
|
|
1199
1179
|
|
|
1200
|
-
if self.panel.SECURE_ARMING == "true" and self.check_user_code_on_arm:
|
|
1180
|
+
if self._controller.panel.SECURE_ARMING == "true" and self.check_user_code_on_arm:
|
|
1201
1181
|
# Do local user code verification to arm if secure arming is enabled
|
|
1202
|
-
user_id = self.panel.check_user(user_code)
|
|
1182
|
+
user_id = self._controller.panel.check_user(user_code)
|
|
1203
1183
|
if user_id == -1:
|
|
1204
1184
|
LOGGER.debug("MQTT: arm command error - user_code error")
|
|
1205
1185
|
return False
|
|
@@ -1223,19 +1203,23 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1223
1203
|
if not exit_sounds:
|
|
1224
1204
|
exitSoundValue = "OFF"
|
|
1225
1205
|
|
|
1206
|
+
entryDelay = "ON"
|
|
1207
|
+
if not entry_delay:
|
|
1208
|
+
entryDelay = "OFF"
|
|
1209
|
+
|
|
1226
1210
|
arming_command = {
|
|
1227
1211
|
"operation_name": mqtt_arming_type,
|
|
1228
1212
|
"bypass_zoneid_set": "[]",
|
|
1229
1213
|
"userID": user_id,
|
|
1230
1214
|
"partitionID": int(partition_id),
|
|
1231
1215
|
"exitSoundValue": exitSoundValue,
|
|
1232
|
-
"entryDelayValue":
|
|
1216
|
+
"entryDelayValue": entryDelay,
|
|
1233
1217
|
"multiplePartitionsSelected": False,
|
|
1234
1218
|
"instant_arming": instant_arm,
|
|
1235
1219
|
"final_exit_arming_selected": False,
|
|
1236
1220
|
"manually_selected_zones": "[]",
|
|
1237
1221
|
"operation_source": 1,
|
|
1238
|
-
"macAddress": self.settings.random_mac,
|
|
1222
|
+
"macAddress": self._controller.settings.random_mac,
|
|
1239
1223
|
}
|
|
1240
1224
|
|
|
1241
1225
|
topic = "mastermeid"
|
|
@@ -1244,8 +1228,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1244
1228
|
ipcInterfaceName = "android.os.IQInternalService"
|
|
1245
1229
|
ipcTransactionID = 7
|
|
1246
1230
|
requestID = str(uuid.uuid4())
|
|
1247
|
-
remoteMacAddress = self.settings.random_mac
|
|
1248
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
1231
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
1232
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
1249
1233
|
|
|
1250
1234
|
payload = {
|
|
1251
1235
|
"eventName": eventName,
|
|
@@ -1268,7 +1252,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1268
1252
|
async def command_execute_scene(self,scene_id:str) -> bool:
|
|
1269
1253
|
LOGGER.debug("MQTT: Sending execute_scene command")
|
|
1270
1254
|
|
|
1271
|
-
scene = self.state.scene(scene_id)
|
|
1255
|
+
scene = self._controller.state.scene(scene_id)
|
|
1272
1256
|
if not scene:
|
|
1273
1257
|
LOGGER.debug("MQTT: command_execute_scene Erro - Unknow Scene: %s", scene_id)
|
|
1274
1258
|
return False
|
|
@@ -1277,7 +1261,7 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1277
1261
|
"operation_name": "execute_scene",
|
|
1278
1262
|
"scene_id": scene.scene_id,
|
|
1279
1263
|
"operation_source": 1,
|
|
1280
|
-
"macAddress": self.settings.random_mac,
|
|
1264
|
+
"macAddress": self._controller.settings.random_mac,
|
|
1281
1265
|
}
|
|
1282
1266
|
|
|
1283
1267
|
topic = "mastermeid"
|
|
@@ -1286,8 +1270,8 @@ class QolsysPluginRemote(QolsysPlugin):
|
|
|
1286
1270
|
ipcInterfaceName = "android.os.IQInternalService"
|
|
1287
1271
|
ipcTransactionID = 7
|
|
1288
1272
|
requestID = str(uuid.uuid4())
|
|
1289
|
-
remoteMacAddress = self.settings.random_mac
|
|
1290
|
-
responseTopic = "response_" + self.settings.random_mac
|
|
1273
|
+
remoteMacAddress = self._controller.settings.random_mac
|
|
1274
|
+
responseTopic = "response_" + self._controller.settings.random_mac
|
|
1291
1275
|
|
|
1292
1276
|
payload = {
|
|
1293
1277
|
"eventName": eventName,
|