qolsys-controller 0.0.62__py3-none-any.whl → 0.0.87__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/adc_device.py +202 -0
- qolsys_controller/adc_service.py +139 -0
- qolsys_controller/adc_service_garagedoor.py +35 -0
- qolsys_controller/controller.py +245 -34
- qolsys_controller/database/db.py +60 -0
- qolsys_controller/database/table.py +1 -0
- qolsys_controller/database/table_alarmedsensor.py +2 -0
- qolsys_controller/database/table_history.py +2 -2
- qolsys_controller/database/table_smartsocket.py +12 -1
- qolsys_controller/database/table_thermostat.py +3 -0
- qolsys_controller/database/table_virtual_device.py +13 -1
- qolsys_controller/database/table_zwave_node.py +3 -0
- qolsys_controller/enum.py +5 -1
- qolsys_controller/enum_adc.py +28 -0
- qolsys_controller/enum_zwave.py +158 -29
- qolsys_controller/errors.py +5 -0
- qolsys_controller/mqtt_command.py +6 -0
- qolsys_controller/panel.py +109 -5
- qolsys_controller/partition.py +22 -2
- qolsys_controller/state.py +163 -1
- qolsys_controller/task_manager.py +4 -3
- qolsys_controller/zone.py +2 -1
- qolsys_controller/zwave_device.py +132 -4
- qolsys_controller/zwave_dimmer.py +3 -0
- qolsys_controller/zwave_energy_clamp.py +15 -0
- qolsys_controller/zwave_garagedoor.py +3 -0
- qolsys_controller/zwave_generic.py +3 -0
- qolsys_controller/zwave_lock.py +4 -0
- qolsys_controller/zwave_outlet.py +3 -0
- qolsys_controller/zwave_service_meter.py +192 -0
- qolsys_controller/zwave_service_multilevelsensor.py +119 -0
- qolsys_controller/zwave_thermometer.py +21 -0
- qolsys_controller/zwave_thermostat.py +150 -38
- {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/METADATA +1 -1
- {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/RECORD +37 -29
- {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/WHEEL +0 -0
- {qolsys_controller-0.0.62.dist-info → qolsys_controller-0.0.87.dist-info}/licenses/LICENSE +0 -0
qolsys_controller/enum_zwave.py
CHANGED
|
@@ -1,49 +1,178 @@
|
|
|
1
1
|
from enum import Enum, IntEnum
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
class MeterType(IntEnum):
|
|
5
|
+
UNKNOWN = 0x00
|
|
6
|
+
ELECTRIC_METER = 0x01
|
|
7
|
+
GAZ_METER = 0x02
|
|
8
|
+
WATER_METER = 0x03
|
|
9
|
+
HEATING = 0x04
|
|
10
|
+
COOLING = 0x05
|
|
11
|
+
RESERVED = 0x6
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MeterRateType(IntEnum):
|
|
15
|
+
UNSPECIFIED = 0x00
|
|
16
|
+
IMPORT = 0x01
|
|
17
|
+
EXPORT = 0x02
|
|
18
|
+
RESERVED = 0x03
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ZWaveMultilevelSensorScale(Enum):
|
|
22
|
+
TEMPERATURE_CELSIUS = "temperature_celsius"
|
|
23
|
+
TEMPERATURE_FAHRENHEIT = "temperature_fahrenheit"
|
|
24
|
+
RELATIVE_HUMIDITY = "relative_humidity"
|
|
25
|
+
WIND_DIRECTION = "wind_direction"
|
|
26
|
+
BAROMETRIC_PRESSURE = "barometric_pressure"
|
|
27
|
+
DEW_POINT = "dew_point"
|
|
28
|
+
RAIN_RATE = "rain_rate"
|
|
29
|
+
TIDE_LEVEL = "tide_level"
|
|
30
|
+
WEIGHT = "weight"
|
|
31
|
+
VOLTS = "volts"
|
|
32
|
+
AMPS = "amps"
|
|
33
|
+
WATTS = "watts"
|
|
34
|
+
DISTANCE = "distance"
|
|
35
|
+
ANGLE_POSITION = "angle_position"
|
|
36
|
+
ROTATION = "rotation"
|
|
37
|
+
WATER_TEMPERATURE_CELSIUS = "water_temperature_celsius"
|
|
38
|
+
WATER_TEMPERATURE_FAHRENHEIT = "water_temperature_fahrenheit"
|
|
39
|
+
LUMINOSITY_LUX = "luminosity_lux"
|
|
40
|
+
UNKNOWN = "unknown"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ZWaveUnknownMeterScale(IntEnum):
|
|
44
|
+
UNKNOWN = 0
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ZWaveElectricMeterScale(IntEnum):
|
|
48
|
+
KWH = 0
|
|
49
|
+
KVAH = 1
|
|
50
|
+
WATTS = 2
|
|
51
|
+
PULSE_COUNT = 3
|
|
52
|
+
VOLTS = 4
|
|
53
|
+
AMPS = 5
|
|
54
|
+
POWER_FACTOR = 6
|
|
55
|
+
KVAR = 7
|
|
56
|
+
KVARH = 8
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ZWaveGasMeterScale(IntEnum):
|
|
60
|
+
CUBIC_METERS = 0
|
|
61
|
+
CUBIC_FEET = 1
|
|
62
|
+
PULSE_COUNT = 3
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class ZWaveWaterMeterScale(IntEnum):
|
|
66
|
+
CUBIC_METERS = 0
|
|
67
|
+
CUBIC_FEET = 1
|
|
68
|
+
US_GALLONS = 2
|
|
69
|
+
PULSE_COUNT = 3
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class ZWaveThermalMeterScale(IntEnum):
|
|
73
|
+
KWH = 0
|
|
74
|
+
PULSE_COUNT = 3
|
|
75
|
+
|
|
76
|
+
|
|
4
77
|
class ThermostatMode(IntEnum):
|
|
5
|
-
OFF =
|
|
6
|
-
HEAT =
|
|
7
|
-
COOL =
|
|
8
|
-
AUTO =
|
|
9
|
-
AUX_HEAT =
|
|
10
|
-
RESUME =
|
|
11
|
-
FAN_ONLY =
|
|
12
|
-
FURNACE =
|
|
13
|
-
DRY_AIR =
|
|
14
|
-
MOIST_AIR =
|
|
15
|
-
AUTO_CHANGEOVER =
|
|
16
|
-
ENERGY_SAVE_HEAT =
|
|
17
|
-
ENERGY_SAVE_COOL =
|
|
18
|
-
AWAY =
|
|
19
|
-
|
|
20
|
-
|
|
78
|
+
OFF = 0x00
|
|
79
|
+
HEAT = 0x01
|
|
80
|
+
COOL = 0x02
|
|
81
|
+
AUTO = 0x03
|
|
82
|
+
AUX_HEAT = 0x04
|
|
83
|
+
RESUME = 0x05
|
|
84
|
+
FAN_ONLY = 0x06
|
|
85
|
+
FURNACE = 0x07
|
|
86
|
+
DRY_AIR = 0x08
|
|
87
|
+
MOIST_AIR = 0x09
|
|
88
|
+
AUTO_CHANGEOVER = 0x0A
|
|
89
|
+
ENERGY_SAVE_HEAT = 0x0B
|
|
90
|
+
ENERGY_SAVE_COOL = 0x0C
|
|
91
|
+
AWAY = 0x0F
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
BITMASK_SUPPORTED_THERMOSTAT_MODE = {
|
|
95
|
+
0: ThermostatMode.OFF,
|
|
96
|
+
1: ThermostatMode.HEAT,
|
|
97
|
+
2: ThermostatMode.COOL,
|
|
98
|
+
3: ThermostatMode.AUTO,
|
|
99
|
+
4: ThermostatMode.AUX_HEAT,
|
|
100
|
+
5: ThermostatMode.RESUME,
|
|
101
|
+
6: ThermostatMode.FAN_ONLY,
|
|
102
|
+
7: ThermostatMode.FURNACE,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class ThermostatSetpointMode(IntEnum):
|
|
107
|
+
HEATING = 0x01
|
|
108
|
+
COOLING = 0x02
|
|
109
|
+
FURNACE = 0x03
|
|
110
|
+
DRY_AIR = 0x04
|
|
111
|
+
MOIST_AIR = 0x05
|
|
112
|
+
AUTO_CHANGEOVER = 0x06
|
|
113
|
+
ECO_HEATING = 0x07
|
|
114
|
+
ECO_COOLING = 0x08
|
|
115
|
+
AWAY_HEATING = 0x09
|
|
116
|
+
AWAY_COOLING = 0x10
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
BITMASK_SUPPORTED_THERMOSTAT_SETPOINT_MODE = {
|
|
120
|
+
0: ThermostatSetpointMode.HEATING,
|
|
121
|
+
1: ThermostatSetpointMode.COOLING,
|
|
122
|
+
2: ThermostatSetpointMode.FURNACE,
|
|
123
|
+
3: ThermostatSetpointMode.DRY_AIR,
|
|
124
|
+
4: ThermostatSetpointMode.MOIST_AIR,
|
|
125
|
+
5: ThermostatSetpointMode.AUTO_CHANGEOVER,
|
|
126
|
+
6: ThermostatSetpointMode.ECO_HEATING,
|
|
127
|
+
7: ThermostatSetpointMode.ECO_COOLING,
|
|
128
|
+
8: ThermostatSetpointMode.AWAY_HEATING,
|
|
129
|
+
9: ThermostatSetpointMode.AWAY_COOLING,
|
|
130
|
+
}
|
|
21
131
|
|
|
22
132
|
|
|
23
133
|
class ThermostatFanMode(IntEnum):
|
|
24
|
-
AUTO_LOW =
|
|
25
|
-
LOW =
|
|
26
|
-
AUTO_HIGH =
|
|
27
|
-
HIGH =
|
|
28
|
-
AUTO_MEDIUM =
|
|
29
|
-
MEDIUM =
|
|
30
|
-
CIRCULATION =
|
|
31
|
-
HUMIDITY_CIRCULATION =
|
|
32
|
-
LEFT_RIGHT =
|
|
33
|
-
UP_DOWN =
|
|
34
|
-
QUIET =
|
|
134
|
+
AUTO_LOW = 0x00
|
|
135
|
+
LOW = 0x01
|
|
136
|
+
AUTO_HIGH = 0x02
|
|
137
|
+
HIGH = 0x03
|
|
138
|
+
AUTO_MEDIUM = 0x04
|
|
139
|
+
MEDIUM = 0x05
|
|
140
|
+
CIRCULATION = 0x06
|
|
141
|
+
HUMIDITY_CIRCULATION = 0x07
|
|
142
|
+
LEFT_RIGHT = 0x08
|
|
143
|
+
UP_DOWN = 0x09
|
|
144
|
+
QUIET = 0x0A
|
|
35
145
|
EXTERNAL_CIRCULATION = 0x0800
|
|
36
|
-
MANUFACTURER_SPECEFIC = 0x1000
|
|
37
146
|
|
|
38
147
|
|
|
39
|
-
|
|
148
|
+
BITMASK_SUPPORTED_THERMOSTAT_FAN_MODE = {
|
|
149
|
+
0: ThermostatFanMode.AUTO_LOW,
|
|
150
|
+
1: ThermostatFanMode.LOW,
|
|
151
|
+
2: ThermostatFanMode.AUTO_HIGH,
|
|
152
|
+
3: ThermostatFanMode.HIGH,
|
|
153
|
+
4: ThermostatFanMode.AUTO_MEDIUM,
|
|
154
|
+
5: ThermostatFanMode.MEDIUM,
|
|
155
|
+
6: ThermostatFanMode.CIRCULATION,
|
|
156
|
+
7: ThermostatFanMode.HUMIDITY_CIRCULATION,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class ZwaveCommandClass(IntEnum):
|
|
40
161
|
SwitchBinary = 0x25
|
|
41
162
|
SwitchMultilevel = 0x26
|
|
163
|
+
SensorMultiLevel = 0x31
|
|
164
|
+
Meter = 0x32
|
|
42
165
|
ThermostatMode = 0x40
|
|
43
166
|
ThermostatSetPoint = 0x43
|
|
44
167
|
ThermostatFanMode = 0x44
|
|
45
168
|
ThermostatFanState = 0x45
|
|
46
169
|
DoorLock = 0x62
|
|
170
|
+
Alarm = 0x71
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class ZwaveCommand(IntEnum):
|
|
174
|
+
SET = 0x01
|
|
175
|
+
GET = 0x02
|
|
47
176
|
|
|
48
177
|
|
|
49
178
|
class ZwaveDeviceClass(Enum):
|
qolsys_controller/errors.py
CHANGED
|
@@ -9,6 +9,11 @@ class QolsysError(Exception):
|
|
|
9
9
|
super().__init__(*args, **kwargs)
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
class QolsysUserCodeError(QolsysError):
|
|
13
|
+
def __init__(self) -> None:
|
|
14
|
+
super().__init__("QolsysUserCodeError")
|
|
15
|
+
|
|
16
|
+
|
|
12
17
|
class QolsysSslError(QolsysError):
|
|
13
18
|
def __init__(self) -> None:
|
|
14
19
|
super().__init__("QolsysSslError")
|
|
@@ -91,26 +91,32 @@ class MQTTCommand_ZWave(MQTTCommand_IpcCall):
|
|
|
91
91
|
|
|
92
92
|
ipc_request: list[dict[str, Any]] = [
|
|
93
93
|
{
|
|
94
|
+
# Node ID
|
|
94
95
|
"dataType": "int",
|
|
95
96
|
"dataValue": int(node_id),
|
|
96
97
|
},
|
|
97
98
|
{
|
|
99
|
+
# End Point
|
|
98
100
|
"dataType": "int",
|
|
99
101
|
"dataValue": 0,
|
|
100
102
|
},
|
|
101
103
|
{
|
|
104
|
+
# Z-Wave Payload
|
|
102
105
|
"dataType": "byteArray",
|
|
103
106
|
"dataValue": zwave_command,
|
|
104
107
|
},
|
|
105
108
|
{
|
|
109
|
+
# Transmit option ?
|
|
106
110
|
"dataType": "int",
|
|
107
111
|
"dataValue": 0,
|
|
108
112
|
},
|
|
109
113
|
{
|
|
114
|
+
# Priority
|
|
110
115
|
"dataType": "int",
|
|
111
116
|
"dataValue": 106,
|
|
112
117
|
},
|
|
113
118
|
{
|
|
119
|
+
# Callback ?
|
|
114
120
|
"dataType": "byteArray",
|
|
115
121
|
"dataValue": [0],
|
|
116
122
|
},
|
qolsys_controller/panel.py
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import base64
|
|
3
4
|
import json
|
|
4
5
|
import logging
|
|
5
6
|
from typing import TYPE_CHECKING, Any
|
|
6
7
|
|
|
8
|
+
from qolsys_controller.adc_device import QolsysAdcDevice
|
|
9
|
+
from qolsys_controller.zwave_energy_clamp import QolsysEnergyClamp
|
|
10
|
+
from qolsys_controller.zwave_thermometer import QolsysThermometer
|
|
11
|
+
|
|
7
12
|
from .database.db import QolsysDB
|
|
8
13
|
from .enum import (
|
|
9
14
|
PartitionAlarmState,
|
|
@@ -386,9 +391,54 @@ class QolsysPanel(QolsysObservable):
|
|
|
386
391
|
self._controller.state.sync_partitions_data(self.get_partitions_from_db())
|
|
387
392
|
self._controller.state.sync_zones_data(self.get_zones_from_db())
|
|
388
393
|
self._controller.state.sync_zwave_devices_data(self.get_zwave_devices_from_db())
|
|
394
|
+
self._controller.state.sync_adc_devices_data(self.get_adc_devices_from_db())
|
|
389
395
|
self._controller.state.sync_scenes_data(self.get_scenes_from_db())
|
|
390
396
|
self._controller.state.sync_weather_data(self.get_weather_from_db())
|
|
391
397
|
|
|
398
|
+
# Validate all local user match a Qolsys Panel user
|
|
399
|
+
qolsys_users = self.db.get_users()
|
|
400
|
+
qolsys_user_list = []
|
|
401
|
+
for qolsys_user in qolsys_users:
|
|
402
|
+
try:
|
|
403
|
+
userid = int(qolsys_user.get("userid", ""))
|
|
404
|
+
except ValueError:
|
|
405
|
+
LOGGER.error("Invalid userid in panel database: %s", qolsys_user.get("userid", ""))
|
|
406
|
+
userid = -1
|
|
407
|
+
|
|
408
|
+
qolsys_user_list.append(userid)
|
|
409
|
+
|
|
410
|
+
for local_user in self._users:
|
|
411
|
+
if local_user.id not in qolsys_user_list:
|
|
412
|
+
LOGGER.error("ID %s from users.conf file not found in panel database", local_user.id)
|
|
413
|
+
|
|
414
|
+
# Check associated zone_id in iqremotesettins table
|
|
415
|
+
LOGGER.debug("Checking iqremotesettings table for zone_id matching panel MAC address")
|
|
416
|
+
iqremote_settings_list = self.db.get_iqremote_settings()
|
|
417
|
+
for iqremote in iqremote_settings_list:
|
|
418
|
+
if (
|
|
419
|
+
self._controller.settings.random_mac.replace(":", "").lower()
|
|
420
|
+
== iqremote.get("mac_address", "").replace(":", "").lower()
|
|
421
|
+
):
|
|
422
|
+
self._controller._zone_id = iqremote.get("zone_id", "")
|
|
423
|
+
LOGGER.debug("Found matching zone_id: %s", self._controller._zone_id)
|
|
424
|
+
break
|
|
425
|
+
|
|
426
|
+
# Parse Z-Wave message
|
|
427
|
+
def parse_zwave_message(self, data: dict[str, Any]) -> None:
|
|
428
|
+
zwave = data.get("ZWAVE_RESPONSE", "")
|
|
429
|
+
payload = base64.b64decode(zwave.get("ZWAVE_PAYLOAD", "")).hex()
|
|
430
|
+
# LOGGER.debug(
|
|
431
|
+
# "Z-Wave Response: Node(%s) - Status(%s) - Payload(%s)",
|
|
432
|
+
# zwave.get("NODE_ID", ""),
|
|
433
|
+
# zwave.get("ZWAVE_COMMAND_STATUS", ""),
|
|
434
|
+
# payload,
|
|
435
|
+
# )
|
|
436
|
+
|
|
437
|
+
node_id: str = str(zwave.get("NODE_ID", 0))
|
|
438
|
+
node = self._controller.state.zwave_device(node_id)
|
|
439
|
+
if node is not None:
|
|
440
|
+
node.update_raw(bytes.fromhex(payload))
|
|
441
|
+
|
|
392
442
|
# Parse panel update to database
|
|
393
443
|
def parse_iq2meid_message(self, data: dict[str, Any]) -> None: # noqa: C901, PLR0912, PLR0915
|
|
394
444
|
eventName = data.get("eventName")
|
|
@@ -564,6 +614,22 @@ class QolsysPanel(QolsysObservable):
|
|
|
564
614
|
case self.db.table_zwave_association_goup.uri:
|
|
565
615
|
self.db.table_zwave_association_goup.update(selection, selection_argument, content_values)
|
|
566
616
|
|
|
617
|
+
# Update Zwave Other
|
|
618
|
+
case self.db.table_zwave_other.uri:
|
|
619
|
+
self.db.table_zwave_other.update(selection, selection_argument, content_values)
|
|
620
|
+
|
|
621
|
+
# Country Locale
|
|
622
|
+
case self.db.table_country_locale.uri:
|
|
623
|
+
self.db.table_country_locale.update(selection, selection_argument, content_values)
|
|
624
|
+
|
|
625
|
+
# Virtual device
|
|
626
|
+
case self.db.table_virtual_device.uri:
|
|
627
|
+
self.db.table_virtual_device.update(selection, selection_argument, content_values)
|
|
628
|
+
adc_id = content_values.get("device_id", "")
|
|
629
|
+
adc_device = self._controller.state.adc_device(adc_id)
|
|
630
|
+
if adc_device is not None:
|
|
631
|
+
adc_device.update_adc_device(content_values)
|
|
632
|
+
|
|
567
633
|
case _:
|
|
568
634
|
LOGGER.debug("iq2meid updating unknow uri:%s", uri)
|
|
569
635
|
LOGGER.debug(data)
|
|
@@ -641,6 +707,13 @@ class QolsysPanel(QolsysObservable):
|
|
|
641
707
|
case self.db.table_zwave_association_goup.uri:
|
|
642
708
|
self.db.table_zwave_association_goup.delete(selection, selection_argument)
|
|
643
709
|
|
|
710
|
+
case self.db.table_virtual_device.uri:
|
|
711
|
+
self.db.table_virtual_device.delete(selection, selection_argument)
|
|
712
|
+
self._controller.state.sync_adc_devices_data(self.get_adc_devices_from_db())
|
|
713
|
+
|
|
714
|
+
case self.db.table_zwave_other.uri:
|
|
715
|
+
self.db.table_zwave_other.delete(selection, selection_argument)
|
|
716
|
+
|
|
644
717
|
case _:
|
|
645
718
|
LOGGER.debug("iq2meid deleting unknown uri:%s", uri)
|
|
646
719
|
LOGGER.debug(data)
|
|
@@ -771,9 +844,21 @@ class QolsysPanel(QolsysObservable):
|
|
|
771
844
|
self.db.table_weather.insert(data=content_values)
|
|
772
845
|
self._controller.state.sync_weather_data(self.get_weather_from_db())
|
|
773
846
|
|
|
847
|
+
# ZWave Association Group
|
|
774
848
|
case self.db.table_zwave_association_goup.uri:
|
|
775
849
|
self.db.table_zwave_association_goup.insert(data=content_values)
|
|
776
850
|
|
|
851
|
+
# Zwave Other
|
|
852
|
+
case self.db.table_zwave_other.uri:
|
|
853
|
+
self.db.table_zwave_other.insert(data=content_values)
|
|
854
|
+
LOGGER.debug("New Z-Wave Other information")
|
|
855
|
+
LOGGER.debug(content_values)
|
|
856
|
+
|
|
857
|
+
# Virtual Device
|
|
858
|
+
case self.db.table_virtual_device.uri:
|
|
859
|
+
self.db.table_virtual_device.insert(data=content_values)
|
|
860
|
+
self._controller.state.sync_adc_devices_data(self.get_adc_devices_from_db())
|
|
861
|
+
|
|
777
862
|
case _:
|
|
778
863
|
LOGGER.debug("iq2meid inserting unknow uri:%s", uri)
|
|
779
864
|
LOGGER.debug(data)
|
|
@@ -793,6 +878,15 @@ class QolsysPanel(QolsysObservable):
|
|
|
793
878
|
# No valid user code found
|
|
794
879
|
return -1
|
|
795
880
|
|
|
881
|
+
def get_adc_devices_from_db(self) -> list[QolsysAdcDevice]:
|
|
882
|
+
adc_devices: list[QolsysAdcDevice] = []
|
|
883
|
+
devices_list = self.db.get_adc_devices()
|
|
884
|
+
|
|
885
|
+
for device in devices_list:
|
|
886
|
+
adc_devices.append(QolsysAdcDevice(device))
|
|
887
|
+
|
|
888
|
+
return adc_devices
|
|
889
|
+
|
|
796
890
|
def get_zwave_devices_from_db(self) -> list[QolsysZWaveDevice]:
|
|
797
891
|
devices: list[QolsysZWaveDevice] = []
|
|
798
892
|
devices_list = self.db.get_zwave_devices()
|
|
@@ -802,8 +896,21 @@ class QolsysPanel(QolsysObservable):
|
|
|
802
896
|
|
|
803
897
|
for device in devices_list:
|
|
804
898
|
device_added = False
|
|
805
|
-
|
|
806
899
|
zwave_node_id = device.get("node_id", "")
|
|
900
|
+
|
|
901
|
+
# Check if z-wave device is an Energy Clamp
|
|
902
|
+
if device.get("node_type", "") == "Energy Clamp":
|
|
903
|
+
LOGGER.debug(device)
|
|
904
|
+
qolsys_meter_device = QolsysEnergyClamp(device)
|
|
905
|
+
devices.append(qolsys_meter_device)
|
|
906
|
+
device_added = True
|
|
907
|
+
|
|
908
|
+
# Check if z-wave device is a thermometer
|
|
909
|
+
if device.get("node_type", "") == "Thermometer":
|
|
910
|
+
qolsys_thermometer = QolsysThermometer(device)
|
|
911
|
+
devices.append(qolsys_thermometer)
|
|
912
|
+
device_added = True
|
|
913
|
+
|
|
807
914
|
# Check if z-wave device is a Dimmer
|
|
808
915
|
for d in dimmers_list:
|
|
809
916
|
dimmer_node_id = d.get("node_id", "")
|
|
@@ -907,10 +1014,7 @@ class QolsysPanel(QolsysObservable):
|
|
|
907
1014
|
|
|
908
1015
|
alarm_type = []
|
|
909
1016
|
for alarm in self.db.get_alarm_type(partition_id):
|
|
910
|
-
|
|
911
|
-
alarm_type.append(PartitionAlarmType("Police Emergency"))
|
|
912
|
-
else:
|
|
913
|
-
alarm_type.append(PartitionAlarmType(alarm))
|
|
1017
|
+
alarm_type.append(PartitionAlarmType(alarm))
|
|
914
1018
|
|
|
915
1019
|
alarm_state = PartitionAlarmState(self.db.get_state_partition("ALARM_STATE", partition_id) or "UNKNOWN")
|
|
916
1020
|
|
qolsys_controller/partition.py
CHANGED
|
@@ -38,7 +38,8 @@ class QolsysPartition(QolsysObservable):
|
|
|
38
38
|
self._alarm_state: PartitionAlarmState = alarm_state
|
|
39
39
|
|
|
40
40
|
# Alarm Type (alarmedsensor table)
|
|
41
|
-
self._alarm_type_array: list[PartitionAlarmType] =
|
|
41
|
+
self._alarm_type_array: list[PartitionAlarmType] = []
|
|
42
|
+
self.append_alarm_type(alarm_type_array)
|
|
42
43
|
|
|
43
44
|
# Other
|
|
44
45
|
self._command_exit_sounds: bool = True
|
|
@@ -72,7 +73,7 @@ class QolsysPartition(QolsysObservable):
|
|
|
72
73
|
|
|
73
74
|
# Update system_status
|
|
74
75
|
if "SYSTEM_STATUS" in data:
|
|
75
|
-
self.system_status = PartitionSystemStatus
|
|
76
|
+
self.system_status = PartitionSystemStatus(data.get("SYSTEM_STATUS", ""))
|
|
76
77
|
|
|
77
78
|
# Update system_status_changed_time
|
|
78
79
|
if "SYSTEM_STATUS_CHANGED_TIME" in data:
|
|
@@ -250,6 +251,25 @@ class QolsysPartition(QolsysObservable):
|
|
|
250
251
|
data_changed = False
|
|
251
252
|
|
|
252
253
|
for new_alarm_type in new_alarm_type_array:
|
|
254
|
+
# Map values to Police Emergency if needed
|
|
255
|
+
if new_alarm_type in {
|
|
256
|
+
PartitionAlarmType.GLASS_BREAK,
|
|
257
|
+
PartitionAlarmType.GLASS_BREAK_AWAY_ONLY,
|
|
258
|
+
PartitionAlarmType.ENTRY_EXIT_LONG_DELAY,
|
|
259
|
+
PartitionAlarmType.ENTRY_EXIT_NORMAL_DELAY,
|
|
260
|
+
PartitionAlarmType.INSTANT_PERIMETER_DW,
|
|
261
|
+
PartitionAlarmType.INSTANT_INTERIOR_DOOR,
|
|
262
|
+
PartitionAlarmType.AWAY_DELAY_MOTION,
|
|
263
|
+
PartitionAlarmType.AWAY_INSTANT_MOTION,
|
|
264
|
+
PartitionAlarmType.REPORTING_SAFETY_SENSOR,
|
|
265
|
+
PartitionAlarmType.DELAYED_REPORTING_SAFETY_SENSOR,
|
|
266
|
+
PartitionAlarmType.AWAY_INSTANT_FOLLOWER_DELAY,
|
|
267
|
+
PartitionAlarmType.STAY_INSTANT_MOTION,
|
|
268
|
+
PartitionAlarmType.STAY_DELAY_MOTION,
|
|
269
|
+
PartitionAlarmType.EMPTY,
|
|
270
|
+
}:
|
|
271
|
+
new_alarm_type = PartitionAlarmType.POLICE_EMERGENCY
|
|
272
|
+
|
|
253
273
|
# Value already in array
|
|
254
274
|
if new_alarm_type in self._alarm_type_array:
|
|
255
275
|
continue
|