qolsys-controller 0.0.15__py3-none-any.whl → 0.0.18__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.
Files changed (51) hide show
  1. qolsys_controller/database/db.py +12 -3
  2. qolsys_controller/database/table.py +44 -16
  3. qolsys_controller/database/table_alarmedsensor.py +3 -16
  4. qolsys_controller/database/table_automation.py +2 -33
  5. qolsys_controller/database/table_country_locale.py +1 -24
  6. qolsys_controller/database/table_dashboard_msgs.py +2 -18
  7. qolsys_controller/database/table_dimmerlight.py +2 -23
  8. qolsys_controller/database/table_doorlock.py +1 -23
  9. qolsys_controller/database/table_eu_event.py +2 -5
  10. qolsys_controller/database/table_heat_map.py +1 -14
  11. qolsys_controller/database/table_history.py +2 -17
  12. qolsys_controller/database/table_iqremotesettings.py +1 -13
  13. qolsys_controller/database/table_iqrouter_network_config.py +1 -6
  14. qolsys_controller/database/table_iqrouter_user_device.py +2 -6
  15. qolsys_controller/database/table_master_slave.py +1 -30
  16. qolsys_controller/database/table_nest_device.py +1 -6
  17. qolsys_controller/database/table_output_rules.py +1 -6
  18. qolsys_controller/database/table_partition.py +1 -11
  19. qolsys_controller/database/table_pgm_outputs.py +2 -6
  20. qolsys_controller/database/table_powerg_device.py +2 -6
  21. qolsys_controller/database/table_qolsyssettings.py +2 -11
  22. qolsys_controller/database/table_scene.py +2 -21
  23. qolsys_controller/database/table_sensor.py +1 -58
  24. qolsys_controller/database/table_shades.py +1 -5
  25. qolsys_controller/database/table_smartsocket.py +1 -5
  26. qolsys_controller/database/table_state.py +1 -13
  27. qolsys_controller/database/table_tcc.py +1 -8
  28. qolsys_controller/database/table_thermostat.py +1 -42
  29. qolsys_controller/database/table_trouble_conditions.py +1 -14
  30. qolsys_controller/database/table_user.py +12 -17
  31. qolsys_controller/database/table_virtual_device.py +1 -5
  32. qolsys_controller/database/table_weather.py +2 -17
  33. qolsys_controller/database/table_zigbee_device.py +1 -6
  34. qolsys_controller/database/table_zwave_association_group.py +1 -20
  35. qolsys_controller/database/table_zwave_history.py +1 -23
  36. qolsys_controller/database/table_zwave_node.py +8 -74
  37. qolsys_controller/database/table_zwave_other.py +1 -6
  38. qolsys_controller/enum_zwave.py +37 -0
  39. qolsys_controller/panel.py +21 -0
  40. qolsys_controller/partition.py +9 -7
  41. qolsys_controller/plugin_remote.py +121 -8
  42. qolsys_controller/scene.py +79 -0
  43. qolsys_controller/settings.py +5 -0
  44. qolsys_controller/state.py +72 -0
  45. qolsys_controller/zone.py +1 -1
  46. qolsys_controller/zwave_thermostat.py +56 -0
  47. {qolsys_controller-0.0.15.dist-info → qolsys_controller-0.0.18.dist-info}/METADATA +2 -1
  48. qolsys_controller-0.0.18.dist-info/RECORD +68 -0
  49. qolsys_controller-0.0.15.dist-info/RECORD +0 -66
  50. {qolsys_controller-0.0.15.dist-info → qolsys_controller-0.0.18.dist-info}/WHEEL +0 -0
  51. {qolsys_controller-0.0.15.dist-info → qolsys_controller-0.0.18.dist-info}/licenses/LICENSE +0 -0
@@ -39,8 +39,8 @@ class QolsysPartition(QolsysObservable):
39
39
 
40
40
  # Other
41
41
  self._command_exit_sounds = True
42
- self._command_silent_disarming = False
43
42
  self._command_arm_stay_instant = True
43
+ self._command_arm_stay_silent_disarming = False
44
44
 
45
45
  @property
46
46
  def id(self) -> int:
@@ -83,12 +83,8 @@ class QolsysPartition(QolsysObservable):
83
83
  return self._command_arm_stay_instant
84
84
 
85
85
  @property
86
- def command_silent_disarming(self) -> bool:
87
- return self._command_silent_disarming
88
-
89
- @command_silent_disarming.setter
90
- def command_silent_disarming(self, value: bool) -> None:
91
- self._command_silent_disarming = value
86
+ def command_arm_stay_silent_disarming(self) -> bool:
87
+ return self._command_arm_stay_silent_disarming
92
88
 
93
89
  @system_status.setter
94
90
  def system_status(self, new_value: PartitionSystemStatus) -> None:
@@ -188,6 +184,12 @@ class QolsysPartition(QolsysObservable):
188
184
  LOGGER.debug("Partition%s (%s) - arm_stay_instant: %s", self._id, self._name, value)
189
185
  self.notify()
190
186
 
187
+ @command_arm_stay_silent_disarming.setter
188
+ def command_arm_stay_silent_disarming(self, value: bool) -> None:
189
+ self._command_arm_stay_silent_disarming = value
190
+ LOGGER.debug("Partition%s (%s) - arm_stay_silent_disarming: %s", self._id, self._name, value)
191
+ self.notify()
192
+
191
193
  def update_partition(self, data: dict) -> None:
192
194
  # Check if we are updating same partition_id
193
195
  partition_id_update = data.get("partition_id", "")
@@ -19,6 +19,7 @@ from .settings import QolsysSettings
19
19
  from .state import QolsysState
20
20
  from .task_manager import QolsysTaskManager
21
21
  from .utils_mqtt import generate_random_mac
22
+ from .enum_zwave import ThermostateFanMode, ThermostatMode
22
23
 
23
24
  LOGGER = logging.getLogger(__name__)
24
25
 
@@ -197,15 +198,15 @@ class QolsysPluginRemote(QolsysPlugin):
197
198
  await self.aiomqtt.subscribe("iq2meid")
198
199
 
199
200
  # Subscribte to MQTT commands response
200
- await self.aiomqtt.subscribe("response_" + self.settings.random_mac, qos=0)
201
+ await self.aiomqtt.subscribe("response_" + self.settings.random_mac, qos=self.settings.mqtt_qos)
201
202
 
202
203
  # Only log mastermeid traffic for debug purposes
203
204
  if self.log_mqtt_mesages:
204
205
  # Subscribe to MQTT commands send to panel by other devices
205
- await self.aiomqtt.subscribe("mastermeid", qos=0)
206
+ await self.aiomqtt.subscribe("mastermeid", qos=self.settings.mqtt_qos)
206
207
 
207
208
  # Subscribe to all topics
208
- #await self.aiomqtt.subscribe("#", qos=0)
209
+ await self.aiomqtt.subscribe("#", qos=self.settings.mqtt_qos)
209
210
 
210
211
  # Start mqtt_listent_task and mqtt_ping_task
211
212
  self._task_manager.cancel(self._mqtt_task_listen_label)
@@ -455,7 +456,7 @@ class QolsysPluginRemote(QolsysPlugin):
455
456
  LOGGER.error("MQTT Client not configured")
456
457
  raise QolsysMqttError
457
458
 
458
- await self.aiomqtt.publish(topic=topic, payload=json.dumps(json_payload), qos=0)
459
+ await self.aiomqtt.publish(topic=topic, payload=json.dumps(json_payload), qos=self.settings.mqtt_qos)
459
460
  return await self._mqtt_command_queue.wait_for_response(request_id)
460
461
 
461
462
  async def command_connect(self) -> dict:
@@ -816,7 +817,6 @@ class QolsysPluginRemote(QolsysPlugin):
816
817
  mqtt_disarm_command = await get_mqtt_disarm_command(silent_disarming)
817
818
  LOGGER.debug("MQTT: Sending disarm command - check_user_code:%s", self.check_user_code_on_disarm)
818
819
 
819
-
820
820
  disarm_command = {
821
821
  "operation_name": mqtt_disarm_command,
822
822
  "userID": user_id,
@@ -851,8 +851,20 @@ class QolsysPluginRemote(QolsysPlugin):
851
851
 
852
852
  return True
853
853
 
854
- async def command_zwave_switch_multi_level(self, node_id: int, level: int) -> None:
854
+ async def command_zwave_thermostat_setpoint_set(self, node_id: int, mode:ThermostatMode, setpoint:float) -> None:
855
+ # Command 67
856
+ LOGGER.debug("MQTT: Sending zwave_thermostat_setpoint_set command: NOT IMPLEMENTED")
857
+
858
+ async def command_zwave_thermostat_mode_set(self, node_id: int, mode:ThermostatMode) -> None:
859
+ # Command 64
860
+ LOGGER.debug("MQTT: Sending zwave_thermostat_mode_set command: NOT IMPLEMENTED")
855
861
 
862
+ async def command_zwave_thermostat_fan_mode_set(self, node_id: int, fan_mode:ThermostateFanMode) -> None:
863
+ # Command 68
864
+ LOGGER.debug("MQTT: Sending zwave_thermostat_fan_mode_set command: NOT IMPLEMENTED")
865
+
866
+ async def command_zwave_switch_multi_level(self, node_id: int, level: int) -> None:
867
+ LOGGER.debug("MQTT: Sending zwave_switch_multi_level command")
856
868
  ipcRequest = [{
857
869
  "dataType": "int", # Node ID
858
870
  "dataValue": node_id,
@@ -862,8 +874,10 @@ class QolsysPluginRemote(QolsysPlugin):
862
874
  "dataValue": 0,
863
875
  },
864
876
  {
865
- "dataType": "byteArray", # ZWAVE MULTILEVELSWITCH COMMAND
866
- "dataValue": [38, 1, level],
877
+ # [38,1,level] ZWAVE MULTILEVELSWITCH SET (level 255 to set to previous state)
878
+ # [38,2] ZWAVE MULTILEVELSWITCH GET
879
+ "dataType": "byteArray",
880
+ "dataValue": [38,1,level],
867
881
  },
868
882
  {
869
883
  "dataType": "int", # ?
@@ -898,6 +912,62 @@ class QolsysPluginRemote(QolsysPlugin):
898
912
  "remoteMacAddress": remoteMacAddress}
899
913
 
900
914
  await self.send_command(topic, payload, requestID)
915
+ LOGGER.debug("MQTT: Receiving zwave_switch_multi_level command")
916
+
917
+ async def command_zwave_switch_binary(self, node_id: int, status:bool) -> None:
918
+ LOGGER.debug("MQTT:Sending zwave_switch_binary command")
919
+
920
+ level = 0
921
+ if status:
922
+ level = 99
923
+
924
+ ipcRequest = [{
925
+ "dataType": "int",
926
+ "dataValue": node_id,
927
+ },
928
+ {
929
+ "dataType": "int",
930
+ "dataValue": 0,
931
+ },
932
+ {
933
+ "dataType": "byteArray",
934
+ "dataValue": [37,1,level],
935
+ },
936
+ {
937
+ "dataType": "int",
938
+ "dataValue": 0,
939
+ },
940
+ {
941
+ "dataType": "int",
942
+ "dataValue": 106,
943
+ },
944
+ {
945
+ "dataType": "byteArray",
946
+ "dataValue": [0],
947
+ },
948
+ ]
949
+
950
+ topic = "mastermeid"
951
+ eventName = "ipcCall"
952
+ ipcServiceName = "qzwaveservice"
953
+ ipcInterfaceName = "android.os.IQZwaveService"
954
+ ipcTransactionID = 47
955
+ requestID = str(uuid.uuid4())
956
+ remoteMacAddress = self.settings.random_mac
957
+ responseTopic = "response_" + self.settings.random_mac
958
+
959
+ payload = {"eventName": eventName,
960
+ "ipcServiceName": ipcServiceName,
961
+ "ipcInterfaceName": ipcInterfaceName,
962
+ "ipcTransactionID": ipcTransactionID,
963
+ "ipcRequest": ipcRequest,
964
+ "requestID": requestID,
965
+ "responseTopic": responseTopic,
966
+ "remoteMacAddress": remoteMacAddress}
967
+
968
+ await self.send_command(topic, payload, requestID)
969
+ LOGGER.debug("MQTT:Receiving zwave_switch_binary command")
970
+
901
971
 
902
972
  async def command_arm(self, partition_id: str, arming_type: str, user_code: str = "", exit_sounds: bool = False,
903
973
  instant_arm: bool = False) -> bool:
@@ -979,3 +1049,46 @@ class QolsysPluginRemote(QolsysPlugin):
979
1049
  await self.send_command(topic, payload, requestID)
980
1050
 
981
1051
  return True
1052
+
1053
+ async def command_execute_scene(self,scene_id:str) -> bool:
1054
+ LOGGER.debug("MQTT: Sending execute_scene command")
1055
+
1056
+ scene = self.state.scene(scene_id)
1057
+ if not scene:
1058
+ LOGGER.debug("MQTT: command_execute_scene Erro - Unknow Scene: %s", scene_id)
1059
+ return False
1060
+
1061
+ scene_command = {
1062
+ "operation_name": "execute_scene",
1063
+ "scene_id": scene.scene_id,
1064
+ "operation_source": 1,
1065
+ "macAddress": self.settings.random_mac,
1066
+ }
1067
+
1068
+ topic = "mastermeid"
1069
+ eventName = "ipcCall"
1070
+ ipcServiceName = "qinternalservice"
1071
+ ipcInterfaceName = "android.os.IQInternalService"
1072
+ ipcTransactionID = 7
1073
+ requestID = str(uuid.uuid4())
1074
+ remoteMacAddress = self.settings.random_mac
1075
+ responseTopic = "response_" + self.settings.random_mac
1076
+
1077
+ payload = {
1078
+ "eventName": eventName,
1079
+ "ipcServiceName": ipcServiceName,
1080
+ "ipcInterfaceName": ipcInterfaceName,
1081
+ "ipcTransactionID": ipcTransactionID,
1082
+ "ipcRequest": [{
1083
+ "dataType": "string",
1084
+ "dataValue": json.dumps(scene_command),
1085
+ }],
1086
+ "requestID": requestID,
1087
+ "responseTopic": responseTopic,
1088
+ "remoteMacAddress": remoteMacAddress,
1089
+ }
1090
+
1091
+ await self.send_command(topic, payload, requestID)
1092
+ LOGGER.debug("MQTT: Receiving execute_scene command")
1093
+
1094
+ return False
@@ -0,0 +1,79 @@
1
+ import logging
2
+
3
+ from .observable import QolsysObservable
4
+
5
+ LOGGER = logging.getLogger(__name__)
6
+
7
+
8
+ class QolsysScene(QolsysObservable):
9
+
10
+ def __init__(self, data: dict) -> None:
11
+ super().__init__()
12
+
13
+ self._scene_id = data.get("scene_id", "")
14
+ self._name = data.get("name", "")
15
+ self._icon = data.get("icon", "")
16
+ self._color = data.get("color", "")
17
+
18
+ def update(self, data: dict) -> None:
19
+
20
+ scene_id_update = data.get("scene_id", "")
21
+ if scene_id_update != self._scene_id:
22
+ LOGGER.error("Updating Scene%s (%s) with Scene%s (different id)", self._scene_id, self.sensorname, scene_id_update)
23
+ return
24
+
25
+ self.start_batch_update()
26
+
27
+ # Update name
28
+ if "name" in data:
29
+ self.sensorname = data.get("name")
30
+
31
+ if "color" in data:
32
+ self.color = data.get("color")
33
+
34
+ if "icon" in data:
35
+ self.icon = data.get("icon")
36
+
37
+ self.end_batch_update()
38
+
39
+ @property
40
+ def scene_id(self) -> str:
41
+ return self._scene_id
42
+
43
+ @property
44
+ def name(self) -> str:
45
+ return self._name
46
+
47
+ @property
48
+ def icon(self) -> str:
49
+ return self._icon
50
+
51
+ @property
52
+ def color(self) -> str:
53
+ return self._color
54
+
55
+ @name.setter
56
+ def name(self, value: str) -> None:
57
+ if self._name != value:
58
+ self._name = value
59
+ self.notify()
60
+
61
+ @icon.setter
62
+ def icon(self, value: str) -> None:
63
+ if self._icon != value:
64
+ self._icon = value
65
+ self.notify()
66
+
67
+ @color.setter
68
+ def color(self, value: str) -> None:
69
+ if self._color != value:
70
+ self._color = value
71
+ self.notify()
72
+
73
+ def to_dict(self) -> dict:
74
+ return {
75
+ "scene_id": self.scene_id,
76
+ "name": self.name,
77
+ "color": self.color,
78
+ "icon": self.icon,
79
+ }
@@ -25,6 +25,7 @@ class QolsysSettings:
25
25
  # MQTT
26
26
  self._mqtt_timeout: int = 30
27
27
  self._mqtt_ping: int = 600
28
+ self._mqtt_qos:int = 0
28
29
  self._mqtt_remote_client_id = ""
29
30
 
30
31
  @property
@@ -94,6 +95,10 @@ class QolsysSettings:
94
95
  def mqtt_ping(self, ping:int) -> None:
95
96
  self._mqtt_ping = ping
96
97
 
98
+ @property
99
+ def mqtt_qos(self) -> int:
100
+ return self._mqtt_qos
101
+
97
102
  @property
98
103
  def mqtt_remote_client_id(self) -> str:
99
104
  return self._mqtt_remote_client_id
@@ -2,6 +2,7 @@ import logging
2
2
 
3
3
  from .observable import QolsysObservable
4
4
  from .partition import QolsysPartition
5
+ from .scene import QolsysScene
5
6
  from .zone import QolsysZone
6
7
  from .zwave_device import QolsysZWaveDevice
7
8
  from .zwave_dimmer import QolsysDimmer
@@ -20,10 +21,12 @@ class QolsysState(QolsysObservable):
20
21
  self._partitions = []
21
22
  self._zones = []
22
23
  self._zwave_devices = []
24
+ self._scenes = []
23
25
 
24
26
  self._state_partition_observer = QolsysObservable()
25
27
  self._state_zone_observer = QolsysObservable()
26
28
  self._state_zwave_observer = QolsysObservable()
29
+ self._state_scene_observer = QolsysObservable()
27
30
 
28
31
  @property
29
32
  def partitions(self) -> list[QolsysPartition]:
@@ -37,6 +40,10 @@ class QolsysState(QolsysObservable):
37
40
  def zones(self) -> list[QolsysZone]:
38
41
  return self._zones
39
42
 
43
+ @property
44
+ def scenes(self) -> list[QolsysScene]:
45
+ return self._scenes
46
+
40
47
  @property
41
48
  def zwave_dimmers(self) -> list[QolsysDimmer]:
42
49
  dimmers = []
@@ -76,6 +83,10 @@ class QolsysState(QolsysObservable):
76
83
  def state_zwave_observer(self) -> QolsysObservable:
77
84
  return self._state_zwave_observer
78
85
 
86
+ @property
87
+ def state_scene_observer(self) -> QolsysObservable:
88
+ return self._state_scene_observer
89
+
79
90
  def partition(self, partition_id: str) -> QolsysPartition:
80
91
  for partition in self.partitions:
81
92
  if partition.id == partition_id:
@@ -103,6 +114,32 @@ class QolsysState(QolsysObservable):
103
114
  self.partitions.remove(partition)
104
115
  self.state_partition_observer.notify()
105
116
 
117
+ def scene(self, scene_id: str) -> QolsysScene:
118
+ for scene in self.scenes:
119
+ if scene.scene_id == scene_id:
120
+ return scene
121
+
122
+ return None
123
+
124
+ def scene_add(self, new_scene: QolsysScene) -> None:
125
+ for scene in self.scenes:
126
+ if new_scene.scene_id == scene.scene_id:
127
+ LOGGER.debug("Adding Scene to State, Scene%s (%s) - Allready in Scene List", new_scene.scene_id, scene.name )
128
+ return
129
+
130
+ self.scenes.append(new_scene)
131
+ self.state_scene_observer.notify()
132
+
133
+ def scene_delete(self, scene_id: str) -> None:
134
+ scene = self.scene(scene_id)
135
+
136
+ if scene is None:
137
+ LOGGER.debug("Deleting Scene from State, Scene%s not found", scene_id)
138
+ return
139
+
140
+ self.scenes.remove(scene)
141
+ self.state_scene_observer.notify()
142
+
106
143
  def zone(self, zone_id: str) -> QolsysZone:
107
144
  for zone in self.zones:
108
145
  if zone.zone_id == zone_id:
@@ -212,6 +249,36 @@ class QolsysState(QolsysObservable):
212
249
  LOGGER.debug("sync_data - delete ZWave%s", state_zwave.none_id)
213
250
  self.zwave_delete(int(state_zwave.node_id))
214
251
 
252
+ def sync_scenes_data(self, db_scenes: list[QolsysScene]) -> None:
253
+ db_scene_list = []
254
+ for db_scene in db_scenes:
255
+ db_scene_list.append(db_scene.scene_id)
256
+
257
+ state_scene_list = []
258
+ for state_scene in self.scenes:
259
+ state_scene_list.append(state_scene.scene_id)
260
+
261
+ # Update existing scenes
262
+ for state_scene in self.scenes:
263
+ if state_scene.scene_id in db_scene_list:
264
+ for db_scene in db_scenes:
265
+ if state_scene.scene_id == db_scene.scene_id:
266
+ LOGGER.debug("sync_data - update Scene%s", state_scene.scene_id)
267
+ state_scene.update(db_scene.to_dict())
268
+ break
269
+
270
+ # Delete scenes
271
+ for state_scene in self.scenes:
272
+ if state_scene.scene_id not in db_scene_list:
273
+ LOGGER.debug("sync_data - delete Scene%s", state_scene.scene_id)
274
+ self.scene_delete(int(state_scene.scene_id))
275
+
276
+ # Add new scene
277
+ for db_scene in db_scenes:
278
+ if db_scene.scene_id not in state_scene_list:
279
+ LOGGER.debug("sync_data - add Scene%s", db_scene.scene_id)
280
+ self.scene_add(db_scene)
281
+
215
282
  def sync_zones_data(self, db_zones: list[QolsysZone]) -> None: # noqa: C901
216
283
  db_zone_list = []
217
284
  for db_zone in db_zones:
@@ -338,3 +405,8 @@ class QolsysState(QolsysObservable):
338
405
  LOGGER.debug("Generic%s (%s) - battery_level: %s", zid, name, zwave.node_battery_level)
339
406
  LOGGER.debug("Generic%s (%s) - battery_level_vale: %s", zid, name, zwave.node_battery_level_value)
340
407
  continue
408
+
409
+ for scene in self.scenes:
410
+ sid = scene.scene_id
411
+ name = scene.name
412
+ LOGGER.debug("Scene%s (%s)",sid, name)
qolsys_controller/zone.py CHANGED
@@ -245,7 +245,7 @@ class QolsysZone(QolsysObservable):
245
245
  @time.setter
246
246
  def time(self, value: str) -> None:
247
247
  if self._time != value:
248
- LOGGER.debug("Zone%s (%s) - time: %s", self.zone_id, self.sensorname, value)
248
+ #LOGGER.debug("Zone%s (%s) - time: %s", self.zone_id, self.sensorname, value)
249
249
  self._time = value
250
250
  self.notify()
251
251
 
@@ -1,6 +1,8 @@
1
1
  import logging
2
2
 
3
3
  from .zwave_device import QolsysZWaveDevice
4
+ from .enum_zwave import ThermostateFanMode, ThermostatMode
5
+ import ast
4
6
 
5
7
  LOGGER = logging.getLogger(__name__)
6
8
 
@@ -249,3 +251,57 @@ class QolsysThermostat(QolsysZWaveDevice):
249
251
  "endpoint": self._thermostat_endpoint,
250
252
  "configuration_parameter": self._thermostat_configuration_parameter,
251
253
  }
254
+
255
+ def thermostat_mode(self) -> ThermostatMode:
256
+ thermostat_mode = int(self._thermostat_mode)
257
+ for mode in ThermostatMode:
258
+ if thermostat_mode == mode:
259
+ return mode
260
+ return None
261
+
262
+ def available_thermostat_mode(self) -> list[ThermostatMode]:
263
+
264
+ int_list = [int(x) for x in self._thermostat_mode_bitmask.split(",")]
265
+ byte_array = bytes(int_list)
266
+ bitmask = int.from_bytes(byte_array, byteorder="little")
267
+
268
+ mode_array = []
269
+ for mode in ThermostateFanMode:
270
+ if mode.value & bitmask:
271
+ mode_array.append(mode)
272
+
273
+ return mode_array
274
+
275
+ def thermostat_fan_mode(self) -> ThermostateFanMode:
276
+ thermostat_fan_mode = int(self._thermostat_fan_mode)
277
+ for mode in ThermostatMode:
278
+ if thermostat_fan_mode == mode:
279
+ return mode
280
+ return None
281
+
282
+ def available_thermostat_fan_mode(self) -> list[ThermostateFanMode]:
283
+
284
+ int_list = [int(x) for x in self._thermostat_fan_mode_bitmask.split(",")]
285
+ byte_array = bytes(int_list)
286
+ bitmask = int.from_bytes(byte_array, byteorder="little")
287
+
288
+ fan_mode_array = []
289
+ for mode in ThermostateFanMode:
290
+ if mode.value & bitmask:
291
+ fan_mode_array.append(mode)
292
+
293
+ return fan_mode_array
294
+
295
+ def available_thermostat_set_point_mode(self) -> list[ThermostatMode]:
296
+
297
+ int_list = [int(x) for x in self._thermostat_set_point_mode_bitmask.split(",")]
298
+ byte_array = bytes(int_list)
299
+ bitmask = int.from_bytes(byte_array, byteorder="little")
300
+
301
+ set_point_mode_array = []
302
+ for mode in ThermostatMode:
303
+ if mode.value & bitmask:
304
+ set_point_mode_array.append(mode)
305
+
306
+ return set_point_mode_array
307
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qolsys-controller
3
- Version: 0.0.15
3
+ Version: 0.0.18
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
@@ -35,6 +35,7 @@ A Python module that emulates a virtual IQ Remote device, enabling full **local
35
35
  | **Partitions** | Arming status | ✅ |
36
36
  | | Set Exit sounds | ✅ |
37
37
  | | Home Instant arming | ✅ |
38
+ | | Home Silent Disarm | ✅ |
38
39
  | | Alarm state and type | ✅ |
39
40
  | | Disarm pictures | 🛠️ WIP |
40
41
  |---|---|---|
@@ -0,0 +1,68 @@
1
+ qolsys_controller/__init__.py,sha256=TkjMFBP9VNyGLC84JQZ_tTeD8nJImkGgPMkQFGr2428,88
2
+ qolsys_controller/controller.py,sha256=rLjMMZBJCPqrE9oY_vZRMFZAsIm5UlXyRtUao3F4Qr0,1309
3
+ qolsys_controller/enum.py,sha256=oIOY0NE7L7b8zMp69sQghUnCG90IJU-RXbPqKP1Xx04,3294
4
+ qolsys_controller/enum_zwave.py,sha256=DOCPvjzuXRjAs40CqS5KBFVFPT_51Sm06cfjaPYuhWE,741
5
+ qolsys_controller/errors.py,sha256=Z_eVJ4XqWucdn1lu_83DPnEKEG4L3FMfjhz5iO6RuBM,1176
6
+ qolsys_controller/mdns.py,sha256=3_d-_K5Fyxc-2s0Fo1advTSpD72P369Hou1Ko0z__Ag,606
7
+ qolsys_controller/mqtt_command_queue.py,sha256=FjSbjK3_3SXV5eQPfQ-k8HOI5Tbu2aWzAxe4uXymK64,937
8
+ qolsys_controller/observable.py,sha256=X7uMnBHGpklPTa-RHKldXA0Rq38Cs1yOIuxl8ODeKV4,1049
9
+ qolsys_controller/panel.py,sha256=rJRFSq_A0EW-fThfQo3rLILD8gMdOihXTlXdgtuMcio,40265
10
+ qolsys_controller/partition.py,sha256=j8FrWvA19_MpQvXDLKl5VvkqX_rcs4GWfFGwyQ2VFw4,8525
11
+ qolsys_controller/pki.py,sha256=_e0tiNF8Hypb37cHr7x8yqUZDaqbzRzP45AitTtmzk4,8663
12
+ qolsys_controller/plugin.py,sha256=Qh0irFbuw9R2QF3jOFTJw70ceVxK1ld5_sW7VnpOrA8,819
13
+ qolsys_controller/plugin_c4.py,sha256=71o5Y7Y13GO0vWCPIsCtpqXxrplryyqt8ua5L8F4StQ,382
14
+ qolsys_controller/plugin_remote.py,sha256=rgrVCcBJQNVaho-Efulb8lQlwlulQQ1M_Qyo1wAjkus,42603
15
+ qolsys_controller/scene.py,sha256=inRZNpAQ0BmQoSbeCSYc4HAP97srncBj1jqZDgGEjLI,1900
16
+ qolsys_controller/settings.py,sha256=ywtlSN4TNUi0NRDjw77lr28fcUD8qYPHNVP67dCuGiQ,5421
17
+ qolsys_controller/state.py,sha256=VeJ5dzbxTQQ4aYkjKMAZLmrTuLOWkqSnLMJbcrFxLME,16904
18
+ qolsys_controller/task_manager.py,sha256=IBFi1l9aId950wvRpvP6d4PHZhr3v1hnnt8NVulM3BI,1139
19
+ qolsys_controller/utils_mqtt.py,sha256=2hf9_BnQbsWi8t0KBiK5MSsDgGjlbWVJi-Sd3H5VVt0,575
20
+ qolsys_controller/zone.py,sha256=2CPtYHbAhPqe74yKsDFrwLYHnS27HDPrAvw85IwSMGE,11366
21
+ qolsys_controller/zwave_device.py,sha256=wMu89b1uJnjkGzaRqE7zryFJVPVfEgGZc6lfP16OrRA,9309
22
+ qolsys_controller/zwave_dimmer.py,sha256=aOAolbptoDpmJCxcPwpn6cIqR5CE1AxCSfz1WxIQJZA,5153
23
+ qolsys_controller/zwave_garagedoor.py,sha256=xoR1I_qm4S0Ir6XvOC2Q9asq69NeJnJ4ZkVy7VC1P6Q,189
24
+ qolsys_controller/zwave_generic.py,sha256=gadtyUfPGsIzJaGc2zT5AQoFVxR_RsoagHE7x7knRzc,245
25
+ qolsys_controller/zwave_lock.py,sha256=j80McYDNHFjSuaTxG6PJpYWjnQKlrAHlN3rSUUNlzL4,4979
26
+ qolsys_controller/zwave_outlet.py,sha256=lxGB-jth11dHPUkT7jC411GdLCGDdct4mAGu05SndCA,185
27
+ qolsys_controller/zwave_thermostat.py,sha256=5FZ0g79rUreIUSCafnU8Sex90DxaU75N3ZLMHBvanL4,14629
28
+ qolsys_controller/database/db.py,sha256=Je1owq3HbSbd63hqx0U_fOBLLYRwMUpmtVpX74KVops,14510
29
+ qolsys_controller/database/table.py,sha256=IBhNToCfLTum0Yu2cUcwaUGU7HvSm-oHu5lFVUgdFKQ,5871
30
+ qolsys_controller/database/table_alarmedsensor.py,sha256=BZ6K9CQbcXRw0rf6WODS0NFf1wptu5CxuRtsLQrCsSQ,808
31
+ qolsys_controller/database/table_automation.py,sha256=1qCdSIX2ALSdGxkZdMbHWT43VjqX4WgmNed4HcC7wc8,1287
32
+ qolsys_controller/database/table_country_locale.py,sha256=OkjqGhYhYaGptZGN74eJI-dkRYSv_Cpex_zCs93v1Wo,1013
33
+ qolsys_controller/database/table_dashboard_msgs.py,sha256=uImI4hHO-34vpTqmdXGFveiW5Nyo84nbMwFb7hB3l3w,847
34
+ qolsys_controller/database/table_dimmerlight.py,sha256=XMknGgah2h7_6SpdLMe3c8lqePOg2jo9begcy0t3BXo,926
35
+ qolsys_controller/database/table_doorlock.py,sha256=ebeYZcgUNKuXMjm4Y9X4QpVKLoxPyfbinfuoUT77qqo,952
36
+ qolsys_controller/database/table_eu_event.py,sha256=D9tGGTX8oNBxSijcixCykOyqSOV_WbU8VqW_KYZOUGI,557
37
+ qolsys_controller/database/table_heat_map.py,sha256=EtqlVajcMIBBN1USWyA-we76b1LsTA1UoM33TwEQaTY,747
38
+ qolsys_controller/database/table_history.py,sha256=-8RRZGejDnF_-cNc4DoqPJZ0bbqpGPocdENpbkcsbhQ,798
39
+ qolsys_controller/database/table_iqremotesettings.py,sha256=Wuiw9GwMJcVpX7weJxa91AzroxWftFWtxsFolhNfGpw,750
40
+ qolsys_controller/database/table_iqrouter_network_config.py,sha256=DnHJshZcbsYTBKHExa9BFPu-K2-0rDp0PCnE-7KPckI,625
41
+ qolsys_controller/database/table_iqrouter_user_device.py,sha256=FC7ZOJsvbT8mClNNr7ArlJg04NsbYlLYLwT6EEgryzE,614
42
+ qolsys_controller/database/table_master_slave.py,sha256=wLmVzK0rGut_7dQ0ws8hFf-5G8rzSEz_Yq7AKM2goFw,1152
43
+ qolsys_controller/database/table_nest_device.py,sha256=Kgm2dsWQoCZoeAjlQSV_ZkehA8ji_w3vKje9sHQrgOI,567
44
+ qolsys_controller/database/table_output_rules.py,sha256=pYs1PQ1rv3-fIDcEI0i-jKOwH1L6nLhzAT3iCk0I5L4,571
45
+ qolsys_controller/database/table_partition.py,sha256=u1239frG6KwnXCk3-xcACZVvzrnxsdV17f175_oL9TE,672
46
+ qolsys_controller/database/table_pgm_outputs.py,sha256=hZyR4tpTss1kP6UCVBBbJHH5LYBMNHAHbcCoeQcCc38,568
47
+ qolsys_controller/database/table_powerg_device.py,sha256=TpXcA9nGkMeVwUG7eo7DQr9M-kHiWLtgIM3MtyMj_Fg,576
48
+ qolsys_controller/database/table_qolsyssettings.py,sha256=qqqCVRAb7pQYjWCYnaavShorn-Uo_YM_tUNhW6e1E6o,684
49
+ qolsys_controller/database/table_scene.py,sha256=DmUuWRSRUfpXxuFh_CzgYm_GkyyNe6DKQHhgl3AFkMs,846
50
+ qolsys_controller/database/table_sensor.py,sha256=UbGhMpbyfeuqknnesfpswL8pHlvpOpPou-h-c6JxI5E,1765
51
+ qolsys_controller/database/table_shades.py,sha256=Gzbh3VH89O9jYW-4Gf0wY14Jl6eSVGT_-IerMZ4-OHo,550
52
+ qolsys_controller/database/table_smartsocket.py,sha256=bSBkiwbtDsQzH3teDtDmLzjqsmRcsoj70jI10vh8WhY,571
53
+ qolsys_controller/database/table_state.py,sha256=amHZB0jFm_Z_DEg-9ChSGIxkJeXC70AW8N247GB8yww,681
54
+ qolsys_controller/database/table_tcc.py,sha256=jhURc5TnEIhXSMQY4pJjr-r5s66Apv8ncEHFTIIy1O0,565
55
+ qolsys_controller/database/table_thermostat.py,sha256=DIM_D_sKjMWW1Ey-awT_QOgft6UbyItGABoi4ORK_PE,1550
56
+ qolsys_controller/database/table_trouble_conditions.py,sha256=2qnejp13C-WV2xdAs3xDNRT1HrnhlemmNhxV4EB72AQ,792
57
+ qolsys_controller/database/table_user.py,sha256=VFKkQznQscanuaQG3UjFrMNx0xuv8wayQF5iBdj-Sao,1106
58
+ qolsys_controller/database/table_virtual_device.py,sha256=AksA7HiUTIsBXtqqWcu884zr-XdS1i3WXP4MsHchEqM,580
59
+ qolsys_controller/database/table_weather.py,sha256=wA3SGpGtpu75fO9OM4zokVmOWd1Fg72dcGBUV1zcsn0,816
60
+ qolsys_controller/database/table_zigbee_device.py,sha256=weB-ijTNWs-rLbkVauIdiz1oPM23JAgFgRf4t1EjyqI,574
61
+ qolsys_controller/database/table_zwave_association_group.py,sha256=B8SHPU335a2wh8vPC9iJ0iVuPOo6PqO0t6vJzlf7ioM,942
62
+ qolsys_controller/database/table_zwave_history.py,sha256=iLCkRZOsQmc5TQT0-IngyNkrG78kQrEhITPChmNt1bM,942
63
+ qolsys_controller/database/table_zwave_node.py,sha256=hAsC7Qn6riqqViAJ61cBaCs5tmD9TmIv4_KynzkJFpU,2567
64
+ qolsys_controller/database/table_zwave_other.py,sha256=RzWuWMQA3czUNRWAP8SaAk6tiTeUgGl3J97npzW6AA0,573
65
+ qolsys_controller-0.0.18.dist-info/METADATA,sha256=_4DP5poVnjNeQk0knS6ZT2_Hma0KxN0CMptiK-e0ORI,4252
66
+ qolsys_controller-0.0.18.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
67
+ qolsys_controller-0.0.18.dist-info/licenses/LICENSE,sha256=GBHv9eggdA5ablDMW1xiLzGDZ2gCIhcKGW__c2aVIOc,1069
68
+ qolsys_controller-0.0.18.dist-info/RECORD,,