qolsys-controller 0.0.44__py3-none-any.whl → 0.0.62__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 +829 -20
- qolsys_controller/database/db.py +48 -29
- qolsys_controller/database/table.py +89 -60
- qolsys_controller/database/table_alarmedsensor.py +0 -2
- qolsys_controller/database/table_automation.py +0 -1
- qolsys_controller/database/table_country_locale.py +0 -1
- qolsys_controller/database/table_dashboard_msgs.py +1 -2
- qolsys_controller/database/table_dimmerlight.py +0 -1
- qolsys_controller/database/table_doorlock.py +0 -1
- qolsys_controller/database/table_eu_event.py +1 -2
- qolsys_controller/database/table_heat_map.py +0 -2
- qolsys_controller/database/table_history.py +4 -1
- qolsys_controller/database/table_iqremotesettings.py +0 -2
- qolsys_controller/database/table_iqrouter_network_config.py +0 -1
- qolsys_controller/database/table_iqrouter_user_device.py +0 -2
- qolsys_controller/database/table_master_slave.py +0 -1
- qolsys_controller/database/table_nest_device.py +0 -1
- qolsys_controller/database/table_output_rules.py +0 -1
- qolsys_controller/database/table_partition.py +0 -1
- qolsys_controller/database/table_pgm_outputs.py +0 -2
- qolsys_controller/database/table_powerg_device.py +0 -2
- qolsys_controller/database/table_qolsyssettings.py +0 -2
- qolsys_controller/database/table_scene.py +0 -2
- qolsys_controller/database/table_sensor.py +2 -2
- qolsys_controller/database/table_sensor_group.py +23 -0
- qolsys_controller/database/table_shades.py +0 -2
- qolsys_controller/database/table_smartsocket.py +0 -2
- qolsys_controller/database/table_state.py +0 -1
- qolsys_controller/database/table_tcc.py +0 -1
- qolsys_controller/database/table_thermostat.py +0 -1
- qolsys_controller/database/table_trouble_conditions.py +0 -2
- qolsys_controller/database/table_user.py +0 -2
- qolsys_controller/database/table_virtual_device.py +0 -2
- qolsys_controller/database/table_weather.py +0 -2
- qolsys_controller/database/table_zigbee_device.py +0 -1
- qolsys_controller/database/table_zwave_association_group.py +0 -1
- qolsys_controller/database/table_zwave_history.py +0 -1
- qolsys_controller/database/table_zwave_node.py +0 -1
- qolsys_controller/database/table_zwave_other.py +0 -1
- qolsys_controller/enum.py +37 -12
- qolsys_controller/enum_zwave.py +81 -36
- qolsys_controller/errors.py +9 -12
- qolsys_controller/mdns.py +7 -4
- qolsys_controller/mqtt_command.py +119 -0
- qolsys_controller/mqtt_command_queue.py +5 -4
- qolsys_controller/observable.py +2 -2
- qolsys_controller/panel.py +195 -151
- qolsys_controller/partition.py +129 -127
- qolsys_controller/pki.py +69 -97
- qolsys_controller/scene.py +30 -28
- qolsys_controller/settings.py +96 -50
- qolsys_controller/state.py +59 -34
- qolsys_controller/task_manager.py +8 -12
- qolsys_controller/users.py +25 -0
- qolsys_controller/utils_mqtt.py +8 -16
- qolsys_controller/weather.py +71 -0
- qolsys_controller/zone.py +242 -214
- qolsys_controller/zwave_device.py +108 -95
- qolsys_controller/zwave_dimmer.py +53 -50
- qolsys_controller/zwave_garagedoor.py +0 -1
- qolsys_controller/zwave_generic.py +2 -3
- qolsys_controller/zwave_lock.py +47 -44
- qolsys_controller/zwave_outlet.py +0 -1
- qolsys_controller/zwave_thermostat.py +112 -118
- qolsys_controller-0.0.62.dist-info/METADATA +89 -0
- qolsys_controller-0.0.62.dist-info/RECORD +69 -0
- {qolsys_controller-0.0.44.dist-info → qolsys_controller-0.0.62.dist-info}/WHEEL +1 -1
- qolsys_controller/plugin.py +0 -34
- qolsys_controller/plugin_c4.py +0 -17
- qolsys_controller/plugin_remote.py +0 -1298
- qolsys_controller-0.0.44.dist-info/METADATA +0 -93
- qolsys_controller-0.0.44.dist-info/RECORD +0 -68
- {qolsys_controller-0.0.44.dist-info → qolsys_controller-0.0.62.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTablePgmOutputs(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.PgmOutputsContentProvider/pgm_outputs"
|
|
@@ -15,7 +14,6 @@ class QolsysTablePgmOutputs(QolsysTable):
|
|
|
15
14
|
self._abort_on_error = False
|
|
16
15
|
self._implemented = False
|
|
17
16
|
|
|
18
|
-
|
|
19
17
|
self._columns = [
|
|
20
18
|
"_id",
|
|
21
19
|
]
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTablePowerGDevice(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.PowerGDeviceContentProvider/powerg_device"
|
|
@@ -15,7 +14,6 @@ class QolsysTablePowerGDevice(QolsysTable):
|
|
|
15
14
|
self._abort_on_error = False
|
|
16
15
|
self._implemented = True
|
|
17
16
|
|
|
18
|
-
|
|
19
17
|
self._columns = [
|
|
20
18
|
"_id",
|
|
21
19
|
"avg_link_quality",
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableQolsysSettings(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.QolsysSettingsProvider/qolsyssettings"
|
|
@@ -15,7 +14,6 @@ class QolsysTableQolsysSettings(QolsysTable):
|
|
|
15
14
|
self._abort_on_error = False
|
|
16
15
|
self._implemented = True
|
|
17
16
|
|
|
18
|
-
|
|
19
17
|
self._columns = [
|
|
20
18
|
"_id",
|
|
21
19
|
"version",
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableScene(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.SceneContentProvider/scene"
|
|
@@ -15,7 +14,6 @@ class QolsysTableScene(QolsysTable):
|
|
|
15
14
|
self._abort_on_error = False
|
|
16
15
|
self._implemented = True
|
|
17
16
|
|
|
18
|
-
|
|
19
17
|
self._columns = [
|
|
20
18
|
"_id",
|
|
21
19
|
"version",
|
|
@@ -7,12 +7,11 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableSensor(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.SensorContentProvider/sensor"
|
|
14
13
|
self._table = "sensor"
|
|
15
|
-
self._abort_on_error =
|
|
14
|
+
self._abort_on_error = False
|
|
16
15
|
self._implemented = True
|
|
17
16
|
|
|
18
17
|
self._columns = [
|
|
@@ -65,6 +64,7 @@ class QolsysTableSensor(QolsysTable):
|
|
|
65
64
|
"secondary_panel_mac_address",
|
|
66
65
|
"extras",
|
|
67
66
|
"allowspeaker",
|
|
67
|
+
"firmware_version",
|
|
68
68
|
]
|
|
69
69
|
|
|
70
70
|
self._create_table()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import logging # noqa: INP001
|
|
2
|
+
import sqlite3
|
|
3
|
+
|
|
4
|
+
from .table import QolsysTable
|
|
5
|
+
|
|
6
|
+
LOGGER = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class QolsysTableSensorGroup(QolsysTable):
|
|
10
|
+
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
11
|
+
super().__init__(db, cursor)
|
|
12
|
+
self._uri = "content://com.qolsys.qolsysprovider.SensorGroupContentProvider/sensor_group" # ?
|
|
13
|
+
self._table = "sensor_group"
|
|
14
|
+
self._abort_on_error = False
|
|
15
|
+
self._implemented = True
|
|
16
|
+
|
|
17
|
+
self._columns = [
|
|
18
|
+
"_id",
|
|
19
|
+
"GROUPNAME",
|
|
20
|
+
"ACTIVEARMINGMODE",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
self._create_table()
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableShades(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.ShadesContentProvider/shades"
|
|
@@ -20,4 +19,3 @@ class QolsysTableShades(QolsysTable):
|
|
|
20
19
|
]
|
|
21
20
|
|
|
22
21
|
self._create_table()
|
|
23
|
-
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableSmartSocket(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.SmartSocketsContentProvider/smartsocket"
|
|
@@ -20,4 +19,3 @@ class QolsysTableSmartSocket(QolsysTable):
|
|
|
20
19
|
]
|
|
21
20
|
|
|
22
21
|
self._create_table()
|
|
23
|
-
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableState(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.StateContentProvider/state"
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableTcc(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.TccContentProvider/tcc"
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableThermostat(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.ThermostatsContentProvider/thermostat"
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableTroubleConditions(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.TroubleConditionsContentProvider/trouble_conditions"
|
|
@@ -28,4 +27,3 @@ class QolsysTableTroubleConditions(QolsysTable):
|
|
|
28
27
|
]
|
|
29
28
|
|
|
30
29
|
self._create_table()
|
|
31
|
-
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableUser(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.UserContentProvider/user"
|
|
@@ -43,4 +42,3 @@ class QolsysTableUser(QolsysTable):
|
|
|
43
42
|
]
|
|
44
43
|
|
|
45
44
|
self._create_table()
|
|
46
|
-
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableVirtualDevice(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.VirtualDeviceContentProvider/virtual_device"
|
|
@@ -20,4 +19,3 @@ class QolsysTableVirtualDevice(QolsysTable):
|
|
|
20
19
|
]
|
|
21
20
|
|
|
22
21
|
self._create_table()
|
|
23
|
-
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableWeather(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.ForecastWeatherContentProvider/weather"
|
|
@@ -30,4 +29,3 @@ class QolsysTableWeather(QolsysTable):
|
|
|
30
29
|
]
|
|
31
30
|
|
|
32
31
|
self._create_table()
|
|
33
|
-
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableZigbeeDevice(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.ZigbeeDeviceContentProvider/zigbee_device"
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableZwaveAssociationGroup(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.ZwaveAssociationGroupContentProvider/zwave_association_group"
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableZwaveHistory(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.ZDeviceHistoryContentProvider/zwave_history"
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableZwaveNode(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.ZwaveContentProvider/zwave_node"
|
|
@@ -7,7 +7,6 @@ LOGGER = logging.getLogger(__name__)
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QolsysTableZwaveOther(QolsysTable):
|
|
10
|
-
|
|
11
10
|
def __init__(self, db: sqlite3.Connection, cursor: sqlite3.Cursor) -> None:
|
|
12
11
|
super().__init__(db, cursor)
|
|
13
12
|
self._uri = "content://com.qolsys.qolsysprovider.ZwaveOtherDeviceContentProvider/zwave_other"
|
qolsys_controller/enum.py
CHANGED
|
@@ -12,6 +12,12 @@ class PartitionSystemStatus(StrEnum):
|
|
|
12
12
|
UNKNOWN = "UNKNOWN"
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
class PartitionArmingType(StrEnum):
|
|
16
|
+
ARM_STAY = "ui_armstay"
|
|
17
|
+
ARM_AWAY = "ui_armaway"
|
|
18
|
+
ARM_NIGHT = "ui_armnight"
|
|
19
|
+
|
|
20
|
+
|
|
15
21
|
class PartitionAlarmState(StrEnum):
|
|
16
22
|
NONE = "None"
|
|
17
23
|
DELAY = "Delay"
|
|
@@ -27,6 +33,18 @@ class PartitionAlarmType(StrEnum):
|
|
|
27
33
|
SILENT_POLICE_EMERGENCY = "Silent Police Emergency"
|
|
28
34
|
GLASS_BREAK_AWAY_ONLY = "glassbreakawayonly"
|
|
29
35
|
GLASS_BREAK = "glassbreak"
|
|
36
|
+
ENTRY_EXIT_NORMAL_DELAY = "entryexitdelay"
|
|
37
|
+
ENTRY_EXIT_LONG_DELAY = "entryexitlongdelay"
|
|
38
|
+
INSTANT_PERIMETER_DW = "instantperimeter"
|
|
39
|
+
INSTANT_INTERIOR_DOOR = "instantinterior"
|
|
40
|
+
AWAY_INSTANT_FOLLOWER_DELAY = "awayinstantfollowerdelay"
|
|
41
|
+
REPORTING_SAFETY_SENSOR = "reportingsafety"
|
|
42
|
+
DELAYED_REPORTING_SAFETY_SENSOR = "delayedreportingsafety"
|
|
43
|
+
AWAY_INSTANT_MOTION = "awayinstantmotion"
|
|
44
|
+
STAY_INSTANT_MOTION = "stayinstantmotion"
|
|
45
|
+
STAY_DELAY_MOTION = "staydelaymotion"
|
|
46
|
+
AWAY_DELAY_MOTION = "awaydelaymotion"
|
|
47
|
+
|
|
30
48
|
|
|
31
49
|
class ZoneStatus(StrEnum):
|
|
32
50
|
ALARMED = "Alarmed"
|
|
@@ -43,6 +61,14 @@ class ZoneStatus(StrEnum):
|
|
|
43
61
|
CONNECTED = "connected"
|
|
44
62
|
DISCONNECTED = "disconnected"
|
|
45
63
|
FAILURE = "Failure"
|
|
64
|
+
NOT_NETWORKED = "Not Networked"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class DeviceCapability(StrEnum):
|
|
68
|
+
SRF = "SRF"
|
|
69
|
+
WIFI = "WiFi"
|
|
70
|
+
POWERG = "POWERG"
|
|
71
|
+
ZWAVE = "Z-Wave"
|
|
46
72
|
|
|
47
73
|
|
|
48
74
|
class ZoneSensorType(StrEnum):
|
|
@@ -93,19 +119,18 @@ class ZoneSensorGroup(StrEnum):
|
|
|
93
119
|
SMOKE_HEAT = "smoke_heat"
|
|
94
120
|
TAMPER_ZONE = "tamperzone"
|
|
95
121
|
SHOCK = "shock"
|
|
122
|
+
ENTRY_EXIT_NORMAL_DELAY = "entryexitdelay"
|
|
123
|
+
ENTRY_EXIT_LONG_DELAY = "entryexitlongdelay"
|
|
124
|
+
INSTANT_PERIMETER_DW = "instantperimeter"
|
|
125
|
+
INSTANT_INTERIOR_DOOR = "instantinterior"
|
|
126
|
+
AWAY_INSTANT_FOLLOWER_DELAY = "awayinstantfollowerdelay"
|
|
127
|
+
REPORTING_SAFETY_SENSOR = "reportingsafety"
|
|
128
|
+
DELAYED_REPORTING_SAFETY_SENSOR = "delayedreportingsafety"
|
|
129
|
+
AWAY_INSTANT_MOTION = "awayinstantmotion"
|
|
130
|
+
STAY_INSTANT_MOTION = "stayinstantmotion"
|
|
131
|
+
STAY_DELAY_MOTION = "staydelaymotion"
|
|
132
|
+
AWAY_DELAY_MOTION = "awaydelaymotion"
|
|
96
133
|
|
|
97
|
-
|
|
98
|
-
# ENTRY_EXIT_NORMAL_DELAY = "" #TBD
|
|
99
|
-
# ENTRY_EXIT_LONG_DELAY = "" #TBD
|
|
100
|
-
# INSTANT_PERIMETER_DW = "" #TBD
|
|
101
|
-
# INSTRANT_INTERIOR_DOOR = "" #TBD
|
|
102
|
-
# AWAY_INSTANT_FOLLOWER_DELAY = "" #TBD
|
|
103
|
-
# REPORTING_SAFETY_SENSOR = "" #TBD
|
|
104
|
-
# DELAYED_REPORTING_SAFETY_SENSOR = "" #TBD
|
|
105
|
-
# AWAY_INSTANT_MOTION = "" #TBD
|
|
106
|
-
# STAY_INSTANT_MOTION = "" #TBD
|
|
107
|
-
# STAY_DELAY_MOTION = "" #TBD
|
|
108
|
-
# AWAY_DELAY_MOTION = "" #TBD
|
|
109
134
|
# TAKEOVER = "" #TBD
|
|
110
135
|
# GARAGE_TILT_SAFETY = "" # TBD
|
|
111
136
|
# WATER_SENSOR = "" # TBD
|
qolsys_controller/enum_zwave.py
CHANGED
|
@@ -1,37 +1,82 @@
|
|
|
1
|
-
from enum import Enum
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class ThermostatMode(Enum):
|
|
5
|
-
OFF: 0x0001
|
|
6
|
-
HEAT: 0x0002
|
|
7
|
-
COOL: 0x0004
|
|
8
|
-
AUTO: 0x0008
|
|
9
|
-
AUX_HEAT: 0x0010
|
|
10
|
-
RESUME: 0x0020
|
|
11
|
-
FAN_ONLY: 0x0040
|
|
12
|
-
FURNACE: 0x0080
|
|
13
|
-
DRY_AIR: 0x0100
|
|
14
|
-
MOIST_AIR: 0x0200
|
|
15
|
-
AUTO_CHANGEOVER: 0x0400
|
|
16
|
-
ENERGY_SAVE_HEAT: 0x0800
|
|
17
|
-
ENERGY_SAVE_COOL: 0x1000
|
|
18
|
-
AWAY: 0x2000
|
|
19
|
-
FULL_POWER: 0x4000
|
|
20
|
-
MANUFACTURER_SPECEFIC: 0x8000
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class ThermostatFanMode(Enum):
|
|
24
|
-
AUTO_LOW: 0x0001
|
|
25
|
-
LOW: 0x0002
|
|
26
|
-
AUTO_HIGH: 0x0004
|
|
27
|
-
HIGH: 0x0008
|
|
28
|
-
AUTO_MEDIUM: 0x0010
|
|
29
|
-
MEDIUM: 0x0020
|
|
30
|
-
CIRCULATION: 0x4000
|
|
31
|
-
HUMIDITY_CIRCULATION: 0x0080
|
|
32
|
-
LEFT_RIGHT: 0x0100
|
|
33
|
-
UP_DOWN: 0x0200
|
|
34
|
-
QUIET: 0x0400
|
|
35
|
-
EXTERNAL_CIRCULATION: 0x0800
|
|
36
|
-
MANUFACTURER_SPECEFIC: 0x1000
|
|
1
|
+
from enum import Enum, IntEnum
|
|
37
2
|
|
|
3
|
+
|
|
4
|
+
class ThermostatMode(IntEnum):
|
|
5
|
+
OFF = 0x0001
|
|
6
|
+
HEAT = 0x0002
|
|
7
|
+
COOL = 0x0004
|
|
8
|
+
AUTO = 0x0008
|
|
9
|
+
AUX_HEAT = 0x0010
|
|
10
|
+
RESUME = 0x0020
|
|
11
|
+
FAN_ONLY = 0x0040
|
|
12
|
+
FURNACE = 0x0080
|
|
13
|
+
DRY_AIR = 0x0100
|
|
14
|
+
MOIST_AIR = 0x0200
|
|
15
|
+
AUTO_CHANGEOVER = 0x0400
|
|
16
|
+
ENERGY_SAVE_HEAT = 0x0800
|
|
17
|
+
ENERGY_SAVE_COOL = 0x1000
|
|
18
|
+
AWAY = 0x2000
|
|
19
|
+
FULL_POWER = 0x4000
|
|
20
|
+
MANUFACTURER_SPECEFIC = 0x8000
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ThermostatFanMode(IntEnum):
|
|
24
|
+
AUTO_LOW = 0x0001
|
|
25
|
+
LOW = 0x0002
|
|
26
|
+
AUTO_HIGH = 0x0004
|
|
27
|
+
HIGH = 0x0008
|
|
28
|
+
AUTO_MEDIUM = 0x0010
|
|
29
|
+
MEDIUM = 0x0020
|
|
30
|
+
CIRCULATION = 0x4000
|
|
31
|
+
HUMIDITY_CIRCULATION = 0x0080
|
|
32
|
+
LEFT_RIGHT = 0x0100
|
|
33
|
+
UP_DOWN = 0x0200
|
|
34
|
+
QUIET = 0x0400
|
|
35
|
+
EXTERNAL_CIRCULATION = 0x0800
|
|
36
|
+
MANUFACTURER_SPECEFIC = 0x1000
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ZwaveCommand(IntEnum):
|
|
40
|
+
SwitchBinary = 0x25
|
|
41
|
+
SwitchMultilevel = 0x26
|
|
42
|
+
ThermostatMode = 0x40
|
|
43
|
+
ThermostatSetPoint = 0x43
|
|
44
|
+
ThermostatFanMode = 0x44
|
|
45
|
+
ThermostatFanState = 0x45
|
|
46
|
+
DoorLock = 0x62
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ZwaveDeviceClass(Enum):
|
|
50
|
+
Unknown = 0x00
|
|
51
|
+
GenericController = 0x01
|
|
52
|
+
StaticController = 0x02
|
|
53
|
+
AVControlPoint = 0x03
|
|
54
|
+
Display = 0x04
|
|
55
|
+
DoorLock = 0x05
|
|
56
|
+
Thermostat = 0x06
|
|
57
|
+
SensorBinary = 0x07
|
|
58
|
+
SensorMultilevel = 0x08
|
|
59
|
+
Meter = 0x09
|
|
60
|
+
EntryControl = 0x0A
|
|
61
|
+
SemiInteroperable = 0x0B
|
|
62
|
+
Button = 0x0C
|
|
63
|
+
RepeaterSlave = 0x0F
|
|
64
|
+
SwitchBinary = 0x10
|
|
65
|
+
SwitchMultilevel = 0x11
|
|
66
|
+
RemoteSwitchBinary = 0x12
|
|
67
|
+
RemoteSwitchMultilevel = 0x13
|
|
68
|
+
SwitchToggleBinary = 0x14
|
|
69
|
+
SwitchToggleMultilevel = 0x15
|
|
70
|
+
ZIPNode = 0x16
|
|
71
|
+
Ventilation = 0x17
|
|
72
|
+
WindowCovering = 0x18
|
|
73
|
+
BarrierOperator = 0x20
|
|
74
|
+
SensorNotification = 0x21
|
|
75
|
+
SoundSwitch = 0x22
|
|
76
|
+
MeterPulse = 0x23
|
|
77
|
+
ColorSwitch = 0x24
|
|
78
|
+
ClimateControlSchedule = 0x25
|
|
79
|
+
RemoteAssociationActivator = 0x26
|
|
80
|
+
SceneController = 0x27
|
|
81
|
+
SceneSceneActuatorConfiguration = 0x28
|
|
82
|
+
SimpleAVControlPoint = 0x30
|
qolsys_controller/errors.py
CHANGED
|
@@ -1,37 +1,34 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from typing import Any
|
|
2
3
|
|
|
3
4
|
LOGGER = logging.getLogger(__name__)
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class QolsysError(Exception):
|
|
7
|
-
|
|
8
|
-
def __init__(self, *args, **kwargs) -> None:
|
|
8
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
9
9
|
super().__init__(*args, **kwargs)
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class QolsysSslError(QolsysError):
|
|
13
|
-
|
|
14
13
|
def __init__(self) -> None:
|
|
15
14
|
super().__init__("QolsysSslError")
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
class QolsysMqttError(QolsysError):
|
|
19
|
-
|
|
20
18
|
def __init__(self) -> None:
|
|
21
19
|
super().__init__("QolsysMqttError")
|
|
22
20
|
|
|
23
21
|
|
|
24
22
|
class QolsysSqlError(QolsysError):
|
|
25
|
-
|
|
26
|
-
def __init__(self, operation: dict) -> None:
|
|
23
|
+
def __init__(self, operation: dict[str, Any]) -> None:
|
|
27
24
|
super().__init__("QolsysSqlError")
|
|
28
25
|
|
|
29
|
-
table = f"QolsysSqlError - table:{operation.get('table',
|
|
30
|
-
query = f"QolsysSqlError - query:{operation.get('query',
|
|
31
|
-
columns = f"QolsysSqlError - columns:{operation.get('columns',
|
|
32
|
-
content_values = f"QolsysSqlError - content_values:{operation.get('content_value',
|
|
33
|
-
selection = f"QolsysSqlError - selection:{operation.get('selection',
|
|
34
|
-
selection_argument = f"QolsysSqlError - selection_argument:{operation.get('selection_argument',
|
|
26
|
+
table = f"QolsysSqlError - table:{operation.get('table', '')}"
|
|
27
|
+
query = f"QolsysSqlError - query:{operation.get('query', '')}"
|
|
28
|
+
columns = f"QolsysSqlError - columns:{operation.get('columns', '')}"
|
|
29
|
+
content_values = f"QolsysSqlError - content_values:{operation.get('content_value', '')}"
|
|
30
|
+
selection = f"QolsysSqlError - selection:{operation.get('selection', '')}"
|
|
31
|
+
selection_argument = f"QolsysSqlError - selection_argument:{operation.get('selection_argument', '')}"
|
|
35
32
|
|
|
36
33
|
e = f"""\n{table}\n{query}\n{columns}\n{content_values}\n{selection}\n{selection_argument}"""
|
|
37
34
|
LOGGER.exception(e)
|
qolsys_controller/mdns.py
CHANGED
|
@@ -5,10 +5,13 @@ from zeroconf.asyncio import AsyncZeroconf
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class QolsysMDNS:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
def __init__(self, ip: str, port: int, external_zero_conf: AsyncZeroconf | None = None) -> None:
|
|
9
|
+
# Add possible external zeroconf instance provided by Home Assistant by example
|
|
10
|
+
# If no external instance is provided, create our own
|
|
11
|
+
if external_zero_conf:
|
|
12
|
+
self.azc = external_zero_conf
|
|
13
|
+
else:
|
|
14
|
+
self.azc = AsyncZeroconf()
|
|
12
15
|
|
|
13
16
|
self.mdns_info = ServiceInfo(
|
|
14
17
|
"_http._tcp.local.",
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import uuid
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
|
+
|
|
6
|
+
from .errors import QolsysMqttError
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
import aiomqtt
|
|
10
|
+
|
|
11
|
+
from .controller import QolsysController
|
|
12
|
+
|
|
13
|
+
LOGGER = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class MQTTCommand:
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
controller: "QolsysController",
|
|
20
|
+
eventName: str,
|
|
21
|
+
) -> None:
|
|
22
|
+
self._controller: QolsysController = controller
|
|
23
|
+
self._client: aiomqtt.Client | None = controller.aiomqtt
|
|
24
|
+
self._topic: str = "mastermeid"
|
|
25
|
+
self._eventName: str = eventName
|
|
26
|
+
self._payload: dict[str, Any] = {}
|
|
27
|
+
self._requestID = str(uuid.uuid4())
|
|
28
|
+
self._qos: int = self._controller.settings.mqtt_qos
|
|
29
|
+
self._responseTopic = "response_" + self._controller.settings.random_mac
|
|
30
|
+
|
|
31
|
+
self.append("requestID", self._requestID)
|
|
32
|
+
self.append("responseTopic", self._responseTopic)
|
|
33
|
+
self.append("eventName", self._eventName)
|
|
34
|
+
self.append("remoteMacAddress", self._controller.settings.random_mac)
|
|
35
|
+
|
|
36
|
+
def append(self, argument: str, value: str | dict[str, Any] | int | bool | list[dict[str, Any]] | Any) -> None:
|
|
37
|
+
self._payload[argument] = value
|
|
38
|
+
|
|
39
|
+
async def send_command(self) -> dict[str, Any]:
|
|
40
|
+
if self._client is None:
|
|
41
|
+
LOGGER.error("MQTT Client not configured")
|
|
42
|
+
raise QolsysMqttError
|
|
43
|
+
|
|
44
|
+
await self._client.publish(topic=self._topic, payload=json.dumps(self._payload), qos=self._qos)
|
|
45
|
+
return await self._controller.mqtt_command_queue.wait_for_response(self._requestID)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class MQTTCommand_IpcCall(MQTTCommand):
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
controller: "QolsysController",
|
|
52
|
+
ipc_service_name: str,
|
|
53
|
+
ipc_interface_name: str,
|
|
54
|
+
ipc_transaction_id: int,
|
|
55
|
+
) -> None:
|
|
56
|
+
super().__init__(controller, "ipcCall")
|
|
57
|
+
self.append("ipcServiceName", ipc_service_name)
|
|
58
|
+
self.append("ipcInterfaceName", ipc_interface_name)
|
|
59
|
+
self.append("ipcTransactionID", ipc_transaction_id)
|
|
60
|
+
|
|
61
|
+
def append_ipc_request(self, ipc_request: list[dict[str, Any]]) -> None:
|
|
62
|
+
self.append("ipcRequest", ipc_request)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class MQTTCommand_Panel(MQTTCommand_IpcCall):
|
|
66
|
+
def __init__(
|
|
67
|
+
self,
|
|
68
|
+
controller: "QolsysController",
|
|
69
|
+
) -> None:
|
|
70
|
+
super().__init__(
|
|
71
|
+
controller=controller,
|
|
72
|
+
ipc_service_name="qinternalservice",
|
|
73
|
+
ipc_interface_name="android.os.IQInternalService",
|
|
74
|
+
ipc_transaction_id=7,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class MQTTCommand_ZWave(MQTTCommand_IpcCall):
|
|
79
|
+
def __init__(
|
|
80
|
+
self,
|
|
81
|
+
controller: "QolsysController",
|
|
82
|
+
node_id: str,
|
|
83
|
+
zwave_command: list[int],
|
|
84
|
+
) -> None:
|
|
85
|
+
super().__init__(
|
|
86
|
+
controller=controller,
|
|
87
|
+
ipc_service_name="qzwaveservice",
|
|
88
|
+
ipc_interface_name="android.os.IQZwaveService",
|
|
89
|
+
ipc_transaction_id=47,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
ipc_request: list[dict[str, Any]] = [
|
|
93
|
+
{
|
|
94
|
+
"dataType": "int",
|
|
95
|
+
"dataValue": int(node_id),
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"dataType": "int",
|
|
99
|
+
"dataValue": 0,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"dataType": "byteArray",
|
|
103
|
+
"dataValue": zwave_command,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"dataType": "int",
|
|
107
|
+
"dataValue": 0,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"dataType": "int",
|
|
111
|
+
"dataValue": 106,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"dataType": "byteArray",
|
|
115
|
+
"dataValue": [0],
|
|
116
|
+
},
|
|
117
|
+
]
|
|
118
|
+
|
|
119
|
+
self.append_ipc_request(ipc_request)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
from typing import Any
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
class QolsysMqttCommandQueue:
|
|
5
6
|
def __init__(self) -> None:
|
|
6
7
|
self.lock = asyncio.Lock()
|
|
7
|
-
self.waiters: dict[str, asyncio.Future] = {}
|
|
8
|
+
self.waiters: dict[str, asyncio.Future[Any]] = {}
|
|
8
9
|
|
|
9
|
-
async def handle_response(self, response: dict) -> None:
|
|
10
|
+
async def handle_response(self, response: dict[str, str]) -> None:
|
|
10
11
|
requestID = response.get("requestID")
|
|
11
12
|
|
|
12
13
|
if not requestID:
|
|
@@ -19,7 +20,7 @@ class QolsysMqttCommandQueue:
|
|
|
19
20
|
if future and not future.done():
|
|
20
21
|
future.set_result(response)
|
|
21
22
|
|
|
22
|
-
async def wait_for_response(self, request_id: str) ->
|
|
23
|
+
async def wait_for_response(self, request_id: str) -> dict[str, Any]:
|
|
23
24
|
if request_id in self.waiters:
|
|
24
25
|
msg = f"Duplicate waiter for request_id: {request_id}"
|
|
25
26
|
raise ValueError(msg)
|
|
@@ -28,4 +29,4 @@ class QolsysMqttCommandQueue:
|
|
|
28
29
|
async with self.lock:
|
|
29
30
|
self.waiters[request_id] = future
|
|
30
31
|
|
|
31
|
-
return await future
|
|
32
|
+
return await future # type: ignore[no-any-return]
|