qolsys-controller 0.0.82__tar.gz → 0.2.9__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.
Potentially problematic release.
This version of qolsys-controller might be problematic. Click here for more details.
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/PKG-INFO +1 -1
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/pyproject.toml +1 -1
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/controller.py +73 -16
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/db.py +7 -7
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_sensor.py +2 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_smartsocket.py +12 -1
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_user.py +1 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/enum.py +29 -16
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/enum_zwave.py +16 -0
- qolsys_controller-0.2.9/qolsys_controller/observable_v2.py +14 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/panel.py +40 -9
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/state.py +74 -19
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/zone.py +68 -7
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/zwave_device.py +57 -3
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/zwave_dimmer.py +6 -2
- qolsys_controller-0.2.9/qolsys_controller/zwave_energy_clamp.py +19 -0
- qolsys_controller-0.2.9/qolsys_controller/zwave_extenal_siren.py +20 -0
- qolsys_controller-0.2.9/qolsys_controller/zwave_garagedoor.py +20 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/zwave_generic.py +6 -2
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/zwave_lock.py +6 -2
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/zwave_service_meter.py +1 -1
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/zwave_service_multilevelsensor.py +9 -0
- qolsys_controller-0.2.9/qolsys_controller/zwave_smart_socket.py +20 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/zwave_thermometer.py +6 -2
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/zwave_thermostat.py +43 -5
- qolsys_controller-0.2.9/qolsys_controller/zwave_water_valve.py +20 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/requirements.txt +2 -2
- qolsys_controller-0.0.82/qolsys_controller/zwave_energy_clamp.py +0 -15
- qolsys_controller-0.0.82/qolsys_controller/zwave_garagedoor.py +0 -13
- qolsys_controller-0.0.82/qolsys_controller/zwave_outlet.py +0 -13
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/.github/workflows/build.yml +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/.github/workflows/publish.yml +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/.gitignore +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/Info_mqtt.md +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/LICENSE +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/README.md +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/bin/qolsys.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/example.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/info_pairing.md +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/info_qolsys.md +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/mypy.ini +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/__init__.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/adc_device.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/adc_service.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/adc_service_garagedoor.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_alarmedsensor.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_automation.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_country_locale.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_dashboard_msgs.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_dimmerlight.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_doorlock.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_eu_event.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_heat_map.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_history.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_iqremotesettings.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_iqrouter_network_config.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_iqrouter_user_device.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_master_slave.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_nest_device.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_output_rules.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_partition.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_pgm_outputs.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_powerg_device.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_qolsyssettings.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_scene.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_sensor_group.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_shades.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_state.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_tcc.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_thermostat.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_trouble_conditions.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_virtual_device.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_weather.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_zigbee_device.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_zwave_association_group.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_zwave_history.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_zwave_node.py +1 -1
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_zwave_other.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/enum_adc.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/errors.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/mdns.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/mqtt_command.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/mqtt_command_queue.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/observable.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/partition.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/pki.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/scene.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/settings.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/task_manager.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/users.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/utils_mqtt.py +0 -0
- {qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/weather.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qolsys-controller
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.9
|
|
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
|
|
@@ -157,15 +157,24 @@ class QolsysController:
|
|
|
157
157
|
self.connected_observer.notify()
|
|
158
158
|
|
|
159
159
|
async def mqtt_connect_task(self, reconnect: bool, run_forever: bool) -> None:
|
|
160
|
-
# Configure TLS
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
160
|
+
# Configure TLS context for MQTT connection
|
|
161
|
+
def create_tls_context(self: QolsysController) -> ssl.SSLContext:
|
|
162
|
+
ctx = ssl.create_default_context(
|
|
163
|
+
purpose=ssl.Purpose.SERVER_AUTH,
|
|
164
|
+
cafile=str(self._pki.qolsys_cer_file_path),
|
|
165
|
+
)
|
|
166
|
+
ctx.set_ciphers("DEFAULT:@SECLEVEL=0")
|
|
167
|
+
ctx.minimum_version = ssl.TLSVersion.TLSv1_2
|
|
168
|
+
ctx.check_hostname = False
|
|
169
|
+
ctx.verify_mode = ssl.CERT_NONE
|
|
170
|
+
ctx.load_cert_chain(
|
|
171
|
+
certfile=str(self._pki.secure_file_path),
|
|
172
|
+
keyfile=str(self._pki.key_file_path),
|
|
173
|
+
)
|
|
174
|
+
return ctx
|
|
175
|
+
|
|
176
|
+
loop = asyncio.get_running_loop()
|
|
177
|
+
ctx = await loop.run_in_executor(None, create_tls_context, self)
|
|
169
178
|
|
|
170
179
|
LOGGER.debug("MQTT: Connecting ...")
|
|
171
180
|
|
|
@@ -177,7 +186,7 @@ class QolsysController:
|
|
|
177
186
|
self.aiomqtt = aiomqtt.Client(
|
|
178
187
|
hostname=self.settings.panel_ip,
|
|
179
188
|
port=8883,
|
|
180
|
-
|
|
189
|
+
tls_context=ctx,
|
|
181
190
|
tls_insecure=True,
|
|
182
191
|
clean_session=True,
|
|
183
192
|
timeout=self.settings.mqtt_timeout,
|
|
@@ -748,6 +757,51 @@ class QolsysController:
|
|
|
748
757
|
LOGGER.debug("MQTT: Receiving execute_scene command")
|
|
749
758
|
return response
|
|
750
759
|
|
|
760
|
+
async def command_panel_virtual_device_action(self, device_id: str, state: int) -> dict[str, Any] | None:
|
|
761
|
+
LOGGER.debug("MQTT: Sending virtual_device command")
|
|
762
|
+
|
|
763
|
+
garage_door = self.state.adc_device(device_id)
|
|
764
|
+
if not garage_door:
|
|
765
|
+
LOGGER.error("Invalid Virtual Garage Door Id: %s", device_id)
|
|
766
|
+
|
|
767
|
+
device_list = {
|
|
768
|
+
"virtualDeviceList": [
|
|
769
|
+
{
|
|
770
|
+
"virtualDeviceId": device_id,
|
|
771
|
+
"virtualDeviceFunctionList": [
|
|
772
|
+
{
|
|
773
|
+
"vdFuncId": 1,
|
|
774
|
+
"vdFuncState": state,
|
|
775
|
+
"vdFuncBackendTimestamp": int(time.time() * 1000),
|
|
776
|
+
"vdFuncType": 1,
|
|
777
|
+
}
|
|
778
|
+
],
|
|
779
|
+
}
|
|
780
|
+
]
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
virtual_command = {
|
|
784
|
+
"operation_name": "send_virtual_device_description",
|
|
785
|
+
"virtual_device_operation": 4,
|
|
786
|
+
"virtual_device_description": json.dumps(device_list),
|
|
787
|
+
"operation_source": 0,
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
ipc_request = [
|
|
791
|
+
{
|
|
792
|
+
"dataType": "string",
|
|
793
|
+
"dataValue": json.dumps(virtual_command),
|
|
794
|
+
}
|
|
795
|
+
]
|
|
796
|
+
|
|
797
|
+
LOGGER.debug("virtual command: %s", virtual_command)
|
|
798
|
+
|
|
799
|
+
command = MQTTCommand_Panel(self)
|
|
800
|
+
command.append_ipc_request(ipc_request)
|
|
801
|
+
response = await command.send_command()
|
|
802
|
+
LOGGER.debug("MQTT: Receiving virtual_device command: %s", response)
|
|
803
|
+
return response
|
|
804
|
+
|
|
751
805
|
async def command_panel_trigger_police(self, partition_id: str, silent: bool) -> dict[str, Any] | None:
|
|
752
806
|
LOGGER.debug("MQTT: Sending panel_trigger_police command")
|
|
753
807
|
|
|
@@ -839,7 +893,7 @@ class QolsysController:
|
|
|
839
893
|
return response
|
|
840
894
|
|
|
841
895
|
async def command_zwave_switch_binary_set(self, node_id: str, status: bool) -> dict[str, Any] | None:
|
|
842
|
-
LOGGER.debug("MQTT: Sending
|
|
896
|
+
LOGGER.debug("MQTT: Sending set_zwave_switch_binar#y command - Node(%s) - Status(%s)", node_id, status)
|
|
843
897
|
zwave_node = self.state.zwave_device(node_id)
|
|
844
898
|
|
|
845
899
|
if not zwave_node:
|
|
@@ -916,17 +970,21 @@ class QolsysController:
|
|
|
916
970
|
temp_int = int(round(setpoint * (10**precision)))
|
|
917
971
|
temp_bytes = temp_int.to_bytes(size, byteorder="big", signed=True)
|
|
918
972
|
|
|
973
|
+
setpointmode = ThermostatSetpointMode.HEATING
|
|
974
|
+
if mode == ThermostatSetpointMode.COOLING:
|
|
975
|
+
setpointmode = mode
|
|
976
|
+
|
|
919
977
|
zwave_bytes: list[int] = [
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
978
|
+
0x43, # Thermostat Setpoint
|
|
979
|
+
0x01, # SET
|
|
980
|
+
setpointmode.value,
|
|
923
981
|
pss,
|
|
924
982
|
] + list(temp_bytes)
|
|
925
983
|
|
|
926
984
|
LOGGER.debug(
|
|
927
985
|
"MQTT: Sending zwave_thermostat_setpoint_set - Node(%s) - Mode(%s) - Setpoint(%s): %s",
|
|
928
986
|
node_id,
|
|
929
|
-
mode,
|
|
987
|
+
mode.value,
|
|
930
988
|
setpoint,
|
|
931
989
|
zwave_bytes,
|
|
932
990
|
)
|
|
@@ -943,7 +1001,6 @@ class QolsysController:
|
|
|
943
1001
|
LOGGER.error("zwave_thermostat_mode_set - Invalid node_id %s", node_id)
|
|
944
1002
|
return None
|
|
945
1003
|
|
|
946
|
-
LOGGER.debug("thermostat_mode: %s", int(mode))
|
|
947
1004
|
if mode not in thermostat.available_thermostat_mode():
|
|
948
1005
|
LOGGER.error("thermostat_mode_set - Invalid mode %s", mode)
|
|
949
1006
|
|
|
@@ -216,7 +216,7 @@ class QolsysDB:
|
|
|
216
216
|
return partitions
|
|
217
217
|
|
|
218
218
|
def get_adc_devices(self) -> list[dict[str, str]]:
|
|
219
|
-
self.cursor.execute(f"SELECT * FROM {self.table_virtual_device.table} ORDER BY device_id")
|
|
219
|
+
self.cursor.execute(f"SELECT * FROM {self.table_virtual_device.table} ORDER BY CAST(device_id AS INTEGER)")
|
|
220
220
|
self.db.commit()
|
|
221
221
|
|
|
222
222
|
devices = []
|
|
@@ -228,7 +228,7 @@ class QolsysDB:
|
|
|
228
228
|
return devices
|
|
229
229
|
|
|
230
230
|
def get_zwave_devices(self) -> list[dict[str, str]]:
|
|
231
|
-
self.cursor.execute(f"SELECT * FROM {self.table_zwave_node.table} ORDER BY node_id")
|
|
231
|
+
self.cursor.execute(f"SELECT * FROM {self.table_zwave_node.table} ORDER BY CAST(node_id AS INTEGER)")
|
|
232
232
|
self.db.commit()
|
|
233
233
|
|
|
234
234
|
devices = []
|
|
@@ -240,7 +240,7 @@ class QolsysDB:
|
|
|
240
240
|
return devices
|
|
241
241
|
|
|
242
242
|
def get_zwave_other_devices(self) -> list[dict[str, str]]:
|
|
243
|
-
self.cursor.execute(f"SELECT * FROM {self.table_zwave_other.table} ORDER BY node_id")
|
|
243
|
+
self.cursor.execute(f"SELECT * FROM {self.table_zwave_other.table} ORDER BY CAST(node_id AS INTEGER)")
|
|
244
244
|
self.db.commit()
|
|
245
245
|
|
|
246
246
|
devices = []
|
|
@@ -252,7 +252,7 @@ class QolsysDB:
|
|
|
252
252
|
return devices
|
|
253
253
|
|
|
254
254
|
def get_locks(self) -> list[dict[str, str]]:
|
|
255
|
-
self.cursor.execute(f"SELECT * FROM {self.table_doorlock.table} ORDER BY node_id")
|
|
255
|
+
self.cursor.execute(f"SELECT * FROM {self.table_doorlock.table} ORDER BY CAST(node_id AS INTEGER)")
|
|
256
256
|
self.db.commit()
|
|
257
257
|
|
|
258
258
|
locks = []
|
|
@@ -264,7 +264,7 @@ class QolsysDB:
|
|
|
264
264
|
return locks
|
|
265
265
|
|
|
266
266
|
def get_thermostats(self) -> list[dict[str, str]]:
|
|
267
|
-
self.cursor.execute(f"SELECT * FROM {self.table_thermostat.table} ORDER BY node_id")
|
|
267
|
+
self.cursor.execute(f"SELECT * FROM {self.table_thermostat.table} ORDER BY CAST(node_id AS INTEGER)")
|
|
268
268
|
self.db.commit()
|
|
269
269
|
|
|
270
270
|
thermostats = []
|
|
@@ -276,7 +276,7 @@ class QolsysDB:
|
|
|
276
276
|
return thermostats
|
|
277
277
|
|
|
278
278
|
def get_dimmers(self) -> list[dict[str, str]]:
|
|
279
|
-
self.cursor.execute(f"SELECT * FROM {self.table_dimmer.table} ORDER BY node_id")
|
|
279
|
+
self.cursor.execute(f"SELECT * FROM {self.table_dimmer.table} ORDER BY CAST(node_id AS INTEGER)")
|
|
280
280
|
self.db.commit()
|
|
281
281
|
|
|
282
282
|
dimmers = []
|
|
@@ -288,7 +288,7 @@ class QolsysDB:
|
|
|
288
288
|
return dimmers
|
|
289
289
|
|
|
290
290
|
def get_zones(self) -> list[dict[str, str]]:
|
|
291
|
-
self.cursor.execute(f"SELECT * FROM {self.table_sensor.table} ORDER BY zoneid")
|
|
291
|
+
self.cursor.execute(f"SELECT * FROM {self.table_sensor.table} ORDER BY CAST(zoneid AS INTEGER)")
|
|
292
292
|
self.db.commit()
|
|
293
293
|
|
|
294
294
|
zones = []
|
{qolsys_controller-0.0.82 → qolsys_controller-0.2.9}/qolsys_controller/database/table_smartsocket.py
RENAMED
|
@@ -12,10 +12,21 @@ class QolsysTableSmartSocket(QolsysTable):
|
|
|
12
12
|
self._uri = "content://com.qolsys.qolsysprovider.SmartSocketsContentProvider/smartsocket"
|
|
13
13
|
self._table = "smartsocket"
|
|
14
14
|
self._abort_on_error = False
|
|
15
|
-
self._implemented =
|
|
15
|
+
self._implemented = True
|
|
16
16
|
|
|
17
17
|
self._columns = [
|
|
18
18
|
"_id",
|
|
19
|
+
"created_by",
|
|
20
|
+
"created_date",
|
|
21
|
+
"last_updated_date",
|
|
22
|
+
"node_id",
|
|
23
|
+
"paired_status",
|
|
24
|
+
"power_usage",
|
|
25
|
+
"status",
|
|
26
|
+
"updated_by",
|
|
27
|
+
"socket_id",
|
|
28
|
+
"socket_name",
|
|
29
|
+
"current_usagevoltage_usage",
|
|
19
30
|
]
|
|
20
31
|
|
|
21
32
|
self._create_table()
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
from enum import StrEnum
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
class QolsysEvent(StrEnum):
|
|
5
|
+
EVENT_PANEL_PARTITION_ADD = "EVENT_PANEL_PARTITION_ADD"
|
|
6
|
+
EVENT_PANEL_ZONE_ADD = "EVENT_PANEL_ZONE_ADD"
|
|
7
|
+
EVENT_PANEL_DOORBELL = "EVENT_PANEL_DOORBELL"
|
|
8
|
+
EVENT_PANEL_CHIME = "EVENT_PANEL_CHIME"
|
|
9
|
+
EVENT_ZWAVE_DEVICE_ADD = "EVENT_ZWAVE_MULTILEVELSENSOR_ADD"
|
|
10
|
+
EVENT_ZWAVE_MULTILEVELSENSOR_ADD = "EVENT_ZWAVE_MULTILEVELSENSOR_ADD"
|
|
11
|
+
EVENT_ZWAVE_METER_ADD = "EVENT_ZWAVE_METER_ADD"
|
|
12
|
+
|
|
13
|
+
|
|
4
14
|
class PartitionSystemStatus(StrEnum):
|
|
5
15
|
ARM_STAY = "ARM-STAY"
|
|
6
16
|
ARM_AWAY = "ARM-AWAY"
|
|
@@ -48,23 +58,24 @@ class PartitionAlarmType(StrEnum):
|
|
|
48
58
|
|
|
49
59
|
|
|
50
60
|
class ZoneStatus(StrEnum):
|
|
61
|
+
ACTIVE = "Active"
|
|
62
|
+
ACTIVATED = "Activated"
|
|
51
63
|
ALARMED = "Alarmed"
|
|
52
|
-
|
|
64
|
+
ARM_AWAY = "Arm-Away"
|
|
65
|
+
ARM_STAY = "Arm-Stay"
|
|
53
66
|
CLOSED = "Closed"
|
|
54
|
-
|
|
67
|
+
CONNECTED = "connected"
|
|
68
|
+
DISARM = "Disarm"
|
|
69
|
+
OPEN = "Open"
|
|
55
70
|
INACTIVE = "Inactive"
|
|
56
|
-
ACTIVATED = "Activated"
|
|
57
71
|
IDLE = "Idle"
|
|
58
72
|
NORMAL = "Normal"
|
|
59
73
|
UNREACHABLE = "Unreachable"
|
|
60
74
|
TAMPERED = "Tampered"
|
|
61
75
|
SYNCHRONIZING = "Synchronizing"
|
|
62
|
-
CONNECTED = "connected"
|
|
63
76
|
DISCONNECTED = "disconnected"
|
|
64
77
|
FAILURE = "Failure"
|
|
65
78
|
NOT_NETWORKED = "Not Networked"
|
|
66
|
-
DISARM = "Disarm"
|
|
67
|
-
ARM_AWAY = "Arm-Away"
|
|
68
79
|
|
|
69
80
|
|
|
70
81
|
class DeviceCapability(StrEnum):
|
|
@@ -72,20 +83,20 @@ class DeviceCapability(StrEnum):
|
|
|
72
83
|
WIFI = "WiFi"
|
|
73
84
|
POWERG = "POWERG"
|
|
74
85
|
ZWAVE = "Z-Wave"
|
|
86
|
+
S_LINE = "S-Line"
|
|
75
87
|
|
|
76
88
|
|
|
77
89
|
class ZoneSensorType(StrEnum):
|
|
78
|
-
|
|
90
|
+
AUXILIARY_PENDANT = "Auxiliary Pendant"
|
|
91
|
+
BLUETOOTH = "Bluetooth"
|
|
92
|
+
CO_DETECTOR = "CODetector"
|
|
79
93
|
DOORBELL = "Doorbell"
|
|
80
|
-
|
|
94
|
+
DOOR_WINDOW = "Door_Window"
|
|
81
95
|
GLASS_BREAK = "GlassBreak"
|
|
96
|
+
MOTION = "Motion"
|
|
82
97
|
KEY_FOB = "KeyFob"
|
|
83
98
|
KEYPAD = "Keypad"
|
|
84
|
-
AUXILIARY_PENDANT = "Auxiliary Pendant"
|
|
85
99
|
SMOKE_DETECTOR = "SmokeDetector"
|
|
86
|
-
CO_DETECTOR = "CODetector"
|
|
87
|
-
# HARDWIRE_TRANSLATOR = "" # TBD
|
|
88
|
-
# WIRELESS_TRANSLATOR = "" #TBD
|
|
89
100
|
TEMPERATURE = "Temperature"
|
|
90
101
|
HEAT = "Heat"
|
|
91
102
|
WATER = "Water"
|
|
@@ -93,16 +104,18 @@ class ZoneSensorType(StrEnum):
|
|
|
93
104
|
FREEZE = "Freeze"
|
|
94
105
|
TILT = "Tilt"
|
|
95
106
|
SMOKE_M = "Smoke_M"
|
|
96
|
-
# DOOR_WINDOW_M = "" #TBD
|
|
97
|
-
# OCCUPANCY = "" #TBD
|
|
98
107
|
SIREN = "Siren"
|
|
99
|
-
# HIGH_TEMPERATURE = "" # TBD
|
|
100
108
|
PANEL_MOTION = "Panel Motion"
|
|
101
109
|
PANEL_GLASS_BREAK = "Panel Glass Break"
|
|
102
|
-
BLUETOOTH = "Bluetooth"
|
|
103
110
|
TAKEOVER_MODULE = "TakeoverModule"
|
|
104
111
|
TRANSLATOR = "Translator"
|
|
105
112
|
TAMPER = "Tamper Sensor"
|
|
113
|
+
ZWAVE_SIREN = "Z-Wave Siren"
|
|
114
|
+
# HARDWIRE_TRANSLATOR = "" # TBD
|
|
115
|
+
# HIGH_TEMPERATURE = "" # TBD
|
|
116
|
+
# DOOR_WINDOW_M = "" #TBD
|
|
117
|
+
# WIRELESS_TRANSLATOR = "" #TBD
|
|
118
|
+
# OCCUPANCY = "" #TBD
|
|
106
119
|
|
|
107
120
|
|
|
108
121
|
class ZoneSensorGroup(StrEnum):
|
|
@@ -160,14 +160,30 @@ BITMASK_SUPPORTED_THERMOSTAT_FAN_MODE = {
|
|
|
160
160
|
class ZwaveCommandClass(IntEnum):
|
|
161
161
|
SwitchBinary = 0x25
|
|
162
162
|
SwitchMultilevel = 0x26
|
|
163
|
+
SceneActivation = 0x2B
|
|
164
|
+
SceneActuatorConf = 0x2C
|
|
163
165
|
SensorMultiLevel = 0x31
|
|
164
166
|
Meter = 0x32
|
|
165
167
|
ThermostatMode = 0x40
|
|
166
168
|
ThermostatSetPoint = 0x43
|
|
167
169
|
ThermostatFanMode = 0x44
|
|
168
170
|
ThermostatFanState = 0x45
|
|
171
|
+
DeviceResetLocally = 0x5A
|
|
172
|
+
AssociationGroupInformation = 0x59
|
|
173
|
+
ZWavePlusInfo = 0x5E
|
|
174
|
+
MultiChannel = 0x60
|
|
169
175
|
DoorLock = 0x62
|
|
176
|
+
Supervision = 0x6C
|
|
177
|
+
Configuration = 0x70
|
|
170
178
|
Alarm = 0x71
|
|
179
|
+
ManufacturerSpecific = 0x72
|
|
180
|
+
PowerLevel = 0x73
|
|
181
|
+
FirmwareUpdate = 0x7A
|
|
182
|
+
Association = 0x85
|
|
183
|
+
Version = 0x86
|
|
184
|
+
Indicator = 0x87
|
|
185
|
+
MultiChannelAssociation = 0x8E
|
|
186
|
+
SecurityS2 = 0x9F
|
|
171
187
|
|
|
172
188
|
|
|
173
189
|
class ZwaveCommand(IntEnum):
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class QolsysObservable_v2:
|
|
6
|
+
def __init__(self) -> None:
|
|
7
|
+
self._observers: dict[str, Any] = {}
|
|
8
|
+
|
|
9
|
+
def subscribe(self, event_name: str, callback: Callable[[], None]) -> None:
|
|
10
|
+
self._observers.setdefault(event_name, []).append(callback)
|
|
11
|
+
|
|
12
|
+
def publish(self, event_name: str, *args: Any, **kwargs: Any) -> None:
|
|
13
|
+
for callback in self._observers.get(event_name, []):
|
|
14
|
+
callback(*args, **kwargs)
|
|
@@ -7,13 +7,18 @@ from typing import TYPE_CHECKING, Any
|
|
|
7
7
|
|
|
8
8
|
from qolsys_controller.adc_device import QolsysAdcDevice
|
|
9
9
|
from qolsys_controller.zwave_energy_clamp import QolsysEnergyClamp
|
|
10
|
+
from qolsys_controller.zwave_extenal_siren import QolsysExternalSiren
|
|
11
|
+
from qolsys_controller.zwave_garagedoor import QolsysGarageDoor
|
|
12
|
+
from qolsys_controller.zwave_smart_socket import QolsysSmartSocket
|
|
10
13
|
from qolsys_controller.zwave_thermometer import QolsysThermometer
|
|
14
|
+
from qolsys_controller.zwave_water_valve import QolsysWaterValve
|
|
11
15
|
|
|
12
16
|
from .database.db import QolsysDB
|
|
13
17
|
from .enum import (
|
|
14
18
|
PartitionAlarmState,
|
|
15
19
|
PartitionAlarmType,
|
|
16
20
|
PartitionSystemStatus,
|
|
21
|
+
QolsysEvent,
|
|
17
22
|
)
|
|
18
23
|
from .observable import QolsysObservable
|
|
19
24
|
from .partition import QolsysPartition
|
|
@@ -452,6 +457,14 @@ class QolsysPanel(QolsysObservable):
|
|
|
452
457
|
case "primaryDisconnect":
|
|
453
458
|
LOGGER.info("Main Panel Disconnect")
|
|
454
459
|
|
|
460
|
+
case "eventNameDoorBell":
|
|
461
|
+
LOGGER.debug("Doorbell Event: %s", json.dumps(data))
|
|
462
|
+
self._controller.state.state_observer.publish(QolsysEvent.EVENT_PANEL_DOORBELL, data)
|
|
463
|
+
|
|
464
|
+
case "chime":
|
|
465
|
+
LOGGER.debug("Chime Event: %s", json.dumps(data))
|
|
466
|
+
self._controller.state.state_observer.publish(QolsysEvent.EVENT_PANEL_CHIME, data)
|
|
467
|
+
|
|
455
468
|
case "dbChanged":
|
|
456
469
|
match dbOperation:
|
|
457
470
|
case "update":
|
|
@@ -901,23 +914,29 @@ class QolsysPanel(QolsysObservable):
|
|
|
901
914
|
# Check if z-wave device is an Energy Clamp
|
|
902
915
|
if device.get("node_type", "") == "Energy Clamp":
|
|
903
916
|
LOGGER.debug(device)
|
|
904
|
-
qolsys_meter_device = QolsysEnergyClamp(device)
|
|
917
|
+
qolsys_meter_device = QolsysEnergyClamp(self._controller, device)
|
|
905
918
|
devices.append(qolsys_meter_device)
|
|
906
919
|
device_added = True
|
|
907
920
|
|
|
908
921
|
# Check if z-wave device is a thermometer
|
|
909
922
|
if device.get("node_type", "") == "Thermometer":
|
|
910
|
-
qolsys_thermometer = QolsysThermometer(device)
|
|
923
|
+
qolsys_thermometer = QolsysThermometer(self._controller, device)
|
|
911
924
|
devices.append(qolsys_thermometer)
|
|
912
925
|
device_added = True
|
|
913
926
|
|
|
927
|
+
# Check if z-wave device is an external siren
|
|
928
|
+
if device.get("node_type", "") == "External Siren":
|
|
929
|
+
qolsys_siren = QolsysExternalSiren(self._controller, device)
|
|
930
|
+
devices.append(qolsys_siren)
|
|
931
|
+
device_added = True
|
|
932
|
+
|
|
914
933
|
# Check if z-wave device is a Dimmer
|
|
915
934
|
for d in dimmers_list:
|
|
916
935
|
dimmer_node_id = d.get("node_id", "")
|
|
917
936
|
|
|
918
937
|
# Found a Dimmer
|
|
919
938
|
if zwave_node_id == dimmer_node_id:
|
|
920
|
-
qolsys_dimmer = QolsysDimmer(d, device)
|
|
939
|
+
qolsys_dimmer = QolsysDimmer(self._controller, d, device)
|
|
921
940
|
devices.append(qolsys_dimmer)
|
|
922
941
|
device_added = True
|
|
923
942
|
break
|
|
@@ -928,7 +947,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
928
947
|
|
|
929
948
|
# Found a Thermostat
|
|
930
949
|
if zwave_node_id == thermostat_node_id:
|
|
931
|
-
qolsys_thermostat = QolsysThermostat(thermostat, device)
|
|
950
|
+
qolsys_thermostat = QolsysThermostat(self._controller, thermostat, device)
|
|
932
951
|
devices.append(qolsys_thermostat)
|
|
933
952
|
device_added = True
|
|
934
953
|
break
|
|
@@ -939,18 +958,32 @@ class QolsysPanel(QolsysObservable):
|
|
|
939
958
|
|
|
940
959
|
# Found a Lock
|
|
941
960
|
if zwave_node_id == lock_node_id:
|
|
942
|
-
qolsys_lock = QolsysLock(lock, device)
|
|
961
|
+
qolsys_lock = QolsysLock(self._controller, lock, device)
|
|
943
962
|
devices.append(qolsys_lock)
|
|
944
963
|
device_added = True
|
|
945
964
|
break
|
|
946
965
|
|
|
947
966
|
# Found a Smart Outlet
|
|
967
|
+
if device.get("node_type", "") == "Smart Socket":
|
|
968
|
+
qolsys_socket = QolsysSmartSocket(self._controller, device)
|
|
969
|
+
devices.append(qolsys_socket)
|
|
970
|
+
device_added = True
|
|
948
971
|
|
|
949
972
|
# Found Garage Door Openner
|
|
973
|
+
if device.get("node_type", "") == "Garage Door":
|
|
974
|
+
qolsys_garagedoor = QolsysGarageDoor(self._controller, device)
|
|
975
|
+
devices.append(qolsys_garagedoor)
|
|
976
|
+
device_added = True
|
|
977
|
+
|
|
978
|
+
# Found a Water Valve
|
|
979
|
+
if device.get("node_type", "") == "Water Valve":
|
|
980
|
+
qolsys_watervalve = QolsysWaterValve(self._controller, device)
|
|
981
|
+
devices.append(qolsys_watervalve)
|
|
982
|
+
device_added = True
|
|
950
983
|
|
|
951
984
|
# No Specific z-wave device found, add a generic z-wave device
|
|
952
985
|
if not device_added:
|
|
953
|
-
qolsys_generic = QolsysGeneric(device)
|
|
986
|
+
qolsys_generic = QolsysGeneric(self._controller, device)
|
|
954
987
|
devices.append(qolsys_generic)
|
|
955
988
|
|
|
956
989
|
return devices
|
|
@@ -987,9 +1020,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
987
1020
|
new_zone = QolsysZone(zone_info, self._controller.settings)
|
|
988
1021
|
|
|
989
1022
|
if new_zone.current_capability == "POWERG":
|
|
990
|
-
LOGGER.debug("Loading PowerG device info for zone %s", new_zone.zone_id)
|
|
991
1023
|
powerg_dict = self.db.get_powerg(short_id=new_zone.shortID)
|
|
992
|
-
LOGGER.debug("PowerG device info: %s", powerg_dict)
|
|
993
1024
|
if powerg_dict is not None:
|
|
994
1025
|
new_zone.update_powerg(powerg_dict)
|
|
995
1026
|
|
|
@@ -1042,7 +1073,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
1042
1073
|
LOGGER.debug("Z-Wave Firmware Version: %s", self.ZWAVE_FIRM_WARE_VERSION)
|
|
1043
1074
|
LOGGER.debug("Z-Wave Card Present: %s", self.ZWAVE_CARD)
|
|
1044
1075
|
LOGGER.debug("Z-Wave Controller Enabled: %s", self.ZWAVE_CONTROLLER)
|
|
1045
|
-
LOGGER.debug("
|
|
1076
|
+
LOGGER.debug("Partitions Enabled: %s", self.PARTITIONS)
|
|
1046
1077
|
LOGGER.debug("Control4 Enabled: %s", self.CONTROL_4)
|
|
1047
1078
|
LOGGER.debug("Six Digit User Code Enabled: %s", self.SIX_DIGIT_USER_CODE)
|
|
1048
1079
|
LOGGER.debug("Secure Arming: %s", self.SECURE_ARMING)
|