qolsys-controller 0.0.40__tar.gz → 0.0.42__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.

Files changed (77) hide show
  1. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/PKG-INFO +1 -1
  2. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/pyproject.toml +1 -1
  3. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/db.py +19 -0
  4. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/panel.py +27 -3
  5. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/state.py +7 -0
  6. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/zone.py +120 -10
  7. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/.github/workflows/build.yml +0 -0
  8. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/.github/workflows/publish.yml +0 -0
  9. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/.gitignore +0 -0
  10. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/Info_mqtt.md +0 -0
  11. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/LICENSE +0 -0
  12. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/README.md +0 -0
  13. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/bin/qolsys.py +0 -0
  14. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/example.py +0 -0
  15. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/info_pairing.md +0 -0
  16. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/info_qolsys.md +0 -0
  17. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/__init__.py +0 -0
  18. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/controller.py +0 -0
  19. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table.py +0 -0
  20. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_alarmedsensor.py +0 -0
  21. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_automation.py +0 -0
  22. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_country_locale.py +0 -0
  23. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_dashboard_msgs.py +0 -0
  24. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_dimmerlight.py +0 -0
  25. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_doorlock.py +0 -0
  26. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_eu_event.py +0 -0
  27. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_heat_map.py +0 -0
  28. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_history.py +0 -0
  29. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_iqremotesettings.py +0 -0
  30. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_iqrouter_network_config.py +0 -0
  31. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_iqrouter_user_device.py +0 -0
  32. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_master_slave.py +0 -0
  33. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_nest_device.py +0 -0
  34. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_output_rules.py +0 -0
  35. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_partition.py +0 -0
  36. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_pgm_outputs.py +0 -0
  37. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_powerg_device.py +0 -0
  38. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_qolsyssettings.py +0 -0
  39. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_scene.py +0 -0
  40. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_sensor.py +0 -0
  41. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_shades.py +0 -0
  42. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_smartsocket.py +0 -0
  43. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_state.py +0 -0
  44. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_tcc.py +0 -0
  45. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_thermostat.py +0 -0
  46. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_trouble_conditions.py +0 -0
  47. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_user.py +0 -0
  48. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_virtual_device.py +0 -0
  49. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_weather.py +0 -0
  50. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_zigbee_device.py +0 -0
  51. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_zwave_association_group.py +0 -0
  52. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_zwave_history.py +0 -0
  53. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_zwave_node.py +0 -0
  54. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/database/table_zwave_other.py +0 -0
  55. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/enum.py +0 -0
  56. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/enum_zwave.py +0 -0
  57. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/errors.py +0 -0
  58. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/mdns.py +0 -0
  59. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/mqtt_command_queue.py +0 -0
  60. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/observable.py +0 -0
  61. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/partition.py +0 -0
  62. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/pki.py +0 -0
  63. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/plugin.py +0 -0
  64. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/plugin_c4.py +0 -0
  65. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/plugin_remote.py +0 -0
  66. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/scene.py +0 -0
  67. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/settings.py +0 -0
  68. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/task_manager.py +0 -0
  69. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/utils_mqtt.py +0 -0
  70. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/zwave_device.py +0 -0
  71. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/zwave_dimmer.py +0 -0
  72. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/zwave_garagedoor.py +0 -0
  73. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/zwave_generic.py +0 -0
  74. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/zwave_lock.py +0 -0
  75. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/zwave_outlet.py +0 -0
  76. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/qolsys_controller/zwave_thermostat.py +0 -0
  77. {qolsys_controller-0.0.40 → qolsys_controller-0.0.42}/requirements.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qolsys-controller
3
- Version: 0.0.40
3
+ Version: 0.0.42
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "qolsys-controller"
3
- version = "0.0.40"
3
+ version = "0.0.42"
4
4
  authors = [
5
5
  { name="Eric Hylands", email="" },
6
6
  ]
@@ -237,6 +237,25 @@ class QolsysDB:
237
237
 
238
238
  return zones
239
239
 
240
+ def get_powerg(self, short_id: str) -> dict:
241
+ try:
242
+ self.cursor.execute(f"SELECT * FROM {self.table_powerg_device.table} WHERE shortID = ?",short_id)
243
+ self.db.commit()
244
+
245
+ row = self.cursor.fetchone()
246
+
247
+ if row is None:
248
+ LOGGER.debug("%s value not found", short_id)
249
+ return None
250
+
251
+ columns = [description[0] for description in self.cursor.description]
252
+ return dict(zip(columns, row, strict=True))
253
+
254
+ except sqlite3.Error:
255
+ LOGGER.exception("Error getting PowerG device info for shortID %s", short_id)
256
+ return None
257
+
258
+
240
259
  def get_setting_panel(self, setting: str) -> str:
241
260
  self.cursor.execute(f"""SELECT value FROM {self.table_qolsyssettings.table}
242
261
  WHERE name = ? and partition_id = ? """, (setting, "0"))
@@ -406,7 +406,7 @@ class QolsysPanel(QolsysObservable):
406
406
  case self.db.table_sensor.uri:
407
407
  self.db.table_sensor.update(selection, selection_argument, content_values)
408
408
  zoneid = content_values.get("zoneid", "")
409
- zone = self._state.zone(zoneid)
409
+ zone = self._state.zone(zone_id=zoneid)
410
410
  if zone is not None:
411
411
  zone.update(content_values)
412
412
 
@@ -521,7 +521,14 @@ class QolsysPanel(QolsysObservable):
521
521
  self.db.table_eu_event.update(selection,selection_argument,content_values)
522
522
  # No action needed
523
523
 
524
-
524
+ # Update PowerG Device
525
+ case self.db.table_powerg_device:
526
+ self.db.table_powerg_device.update(selection,selection_argument,content_values)
527
+ short_id = content_values.get("shortID", "")
528
+ zone = self._state.zone_from_short_id(short_id)
529
+ if zone is not None:
530
+ LOGGER.debug("iq2meid updating powerg device for zoneid(%s):%s", zone.zone_id,content_values)
531
+ zone.update_powerg(content_values)
525
532
 
526
533
  case _:
527
534
  LOGGER.debug("iq2meid updating unknow uri:%s", uri)
@@ -601,6 +608,9 @@ class QolsysPanel(QolsysObservable):
601
608
  case self.db.table_eu_event:
602
609
  self.db.table_eu_event.delete(selection,selection_argument)
603
610
 
611
+ case self.db.table_powerg_device:
612
+ self.db.table_powerg_device.delete(selection,selection_argument)
613
+
604
614
  case _:
605
615
  LOGGER.debug("iq2meid deleting unknown uri:%s", uri)
606
616
  LOGGER.debug(data)
@@ -729,6 +739,10 @@ class QolsysPanel(QolsysObservable):
729
739
  case self.db.table_eu_event:
730
740
  self.db.table_eu_event.insert(data=content_values)
731
741
 
742
+ # PowerG Device
743
+ case self.db.table_powerg_device:
744
+ self.db.table_powerg_device.insert(data=content_values)
745
+
732
746
  case _:
733
747
  LOGGER.debug("iq2meid inserting unknow uri:%s", uri)
734
748
  LOGGER.debug(data)
@@ -820,7 +834,17 @@ class QolsysPanel(QolsysObservable):
820
834
 
821
835
  # Create sensors array
822
836
  for zone_info in zones_list:
823
- zones.append(QolsysZone(zone_info,self._settings))
837
+
838
+ new_zone = QolsysZone(zone_info,self._settings)
839
+
840
+ if new_zone.current_capability == "POWERG":
841
+ LOGGER.debug("Loading PowerG device info for zone %s", new_zone.id)
842
+ powerg_dict = self.db.get_powerg(short_id= new_zone.shortID)
843
+ LOGGER.debug("PowerG device info: %s", powerg_dict)
844
+ if powerg_dict is not None:
845
+ new_zone.update_powerg(powerg_dict)
846
+
847
+ zones.append(new_zone)
824
848
 
825
849
  return zones
826
850
 
@@ -149,6 +149,12 @@ class QolsysState(QolsysObservable):
149
149
  return zone
150
150
  return None
151
151
 
152
+ def zone_from_short_id(self, short_id: int) -> QolsysZone | None:
153
+ for zone in self.zones:
154
+ if zone.shortID == short_id:
155
+ return zone
156
+ return None
157
+
152
158
  def zone_add(self, new_zone: QolsysZone) -> None:
153
159
  for zone in self.zones:
154
160
  if new_zone.zone_id == zone.zone_id:
@@ -299,6 +305,7 @@ class QolsysState(QolsysObservable):
299
305
  if state_zone.zone_id == db_zone.zone_id:
300
306
  LOGGER.debug("sync_data - update Zone%s", state_zone.zone_id)
301
307
  state_zone.update(db_zone.to_dict())
308
+ state_zone.update_powerg(db_zone.to_powerg_dict())
302
309
 
303
310
  # Delete zones
304
311
  for state_zone in self.zones:
@@ -11,7 +11,7 @@ LOGGER = logging.getLogger(__name__)
11
11
 
12
12
  class QolsysZone(QolsysObservable):
13
13
 
14
- def __init__(self, data: dict, settings: QolsysSettings) -> None:
14
+ def __init__(self, data: dict, settings: QolsysSettings) -> None: # noqa: PLR0915
15
15
  super().__init__()
16
16
 
17
17
  self._settings = settings
@@ -27,6 +27,9 @@ class QolsysZone(QolsysObservable):
27
27
  self._averagedBm = data.get("averagedBm", "")
28
28
  self._latestdBm = data.get("latestdBm", "")
29
29
  self._ac_status = data.get("ac_status", "")
30
+ self._shortID = data.get("shortID", "")
31
+ self._device_capability = data.get("device_capability", "")
32
+ self._current_capability = data.get("current_capability", "")
30
33
 
31
34
  self._id = data.get("_id", "")
32
35
  self._zone_type = data.get("zone_type", "")
@@ -56,14 +59,69 @@ class QolsysZone(QolsysObservable):
56
59
  self._created_by = data.get("created_by", "")
57
60
  self._updated_by = data.get("updated_by", "")
58
61
  self._updated_date = data.get("updated_date", "")
59
- self._shortID = data.get("shortID", "")
60
62
  self._diag_24hr = data.get("diag_24hr", "")
61
- self._device_capability = data.get("device_capability", "")
62
63
  self._sub_type = data.get("sub_type", "")
63
64
  self._powerg_manufacture_id = data.get("powerg_manufacture_id", "")
64
65
  self._parent_node = data.get("parent_node", "")
65
66
  self._extras = data.get("extras", "")
66
67
 
68
+ # EXTRA POWERG ATTRIBUTES
69
+ self._powerg_long_id = ""
70
+ self._powerg_status_data:str = ""
71
+ self._powerg_temperature:str = ""
72
+ self._powerg_light:str = ""
73
+ self._powerg_notification_period = ""
74
+ self._powerg_average_link_quality = ""
75
+ self._powerg_link_quality = ""
76
+ self._powerg_link_status = ""
77
+ self._powerg_battery_voltage = ""
78
+
79
+ def is_powerg_enabled(self) -> bool:
80
+ return self._current_capability == "PowerG"
81
+
82
+ def is_powerg_temperature_enabled(self) -> bool:
83
+ return self._powerg_temperature != ""
84
+
85
+ def is_powerg_light_enabled(self) -> bool:
86
+ return self._powerg_light != ""
87
+
88
+ def update_powerg(self, data: dict) -> None:
89
+ short_id_update = data.get("shortID", "")
90
+ if short_id_update != self.shortID:
91
+ LOGGER.error("Updating Zone%s PowerG Attribute (%s) with Zone%s (different shortID)", self._zone_id, self.sensorname, short_id_update)
92
+ return
93
+
94
+ self.start_batch_update()
95
+
96
+ if "longID" in data:
97
+ self._powerg_long_id = data.get("longID")
98
+
99
+ if "status_data" in data:
100
+ self.powerg_status_data = data.get("status_data")
101
+
102
+ if "temperature" in data:
103
+ self.powerg_temperature = data.get("temperature")
104
+
105
+ if "light" in data:
106
+ self.powerg_light = data.get("light")
107
+
108
+ if "notification_period" in data:
109
+ self._powerg_notification_period = data.get("notification_period")
110
+
111
+ if "average_link_quality" in data:
112
+ self._powerg_average_link_quality = data.get("average_link_quality")
113
+
114
+ if "link_quality" in data:
115
+ self._powerg_link_quality = data.get("link_quality")
116
+
117
+ if "link_status" in data:
118
+ self._powerg_link_status = data.get("link_status")
119
+
120
+ if "battery_voltage" in data:
121
+ self._powerg_battery_voltage = data.get("battery_voltage")
122
+
123
+ self.end_batch_update()
124
+
67
125
  def update(self, data: dict) -> None: # noqa: C901, PLR0912, PLR0915
68
126
 
69
127
  zone_id_update = data.get("zoneid", "")
@@ -73,31 +131,24 @@ class QolsysZone(QolsysObservable):
73
131
 
74
132
  self.start_batch_update()
75
133
 
76
- # Update sensor_name
77
134
  if "sensorname" in data:
78
135
  self.sensorname = data.get("sensorname")
79
136
 
80
- # Update sensorsatus
81
137
  if "sensorstatus" in data:
82
138
  self.sensorstatus = ZoneStatus(data.get("sensorstatus"))
83
139
 
84
- # Update battery_status
85
140
  if "battery_status" in data:
86
141
  self.battery_status = data.get("battery_status")
87
142
 
88
- # Update time
89
143
  if "time" in data:
90
144
  self.time = data.get("time")
91
145
 
92
- # Update partition_id
93
146
  if "partition_id" in data:
94
147
  self._partition_id = data.get("partition_id")
95
148
 
96
- # Update lastestdBm
97
149
  if "lastestdBm" in data:
98
150
  self.latestdBm = data.get("latestdBm")
99
151
 
100
- # Update averagedBm
101
152
  if "averagedBm" in data:
102
153
  self.averagedBm = data.get("averagedBm")
103
154
 
@@ -205,10 +256,18 @@ class QolsysZone(QolsysObservable):
205
256
  def partition_id(self) -> str:
206
257
  return self._partition_id
207
258
 
259
+ @property
260
+ def shortID(self) -> str:
261
+ return self._shortID
262
+
208
263
  @property
209
264
  def time(self) -> str:
210
265
  return self._time
211
266
 
267
+ @property
268
+ def current_capability(self) -> str:
269
+ return self._current_capability
270
+
212
271
  @property
213
272
  def latestdBm(self) -> str:
214
273
  return self._latestdBm
@@ -217,6 +276,43 @@ class QolsysZone(QolsysObservable):
217
276
  def averagedBm(self) -> str:
218
277
  return self._averagedBm
219
278
 
279
+ @property
280
+ def device_capability(self) -> str:
281
+ return self._device_capability
282
+
283
+ @property
284
+ def powerg_temperature(self) -> float | None:
285
+ return self._powerg_temperature
286
+
287
+ @property
288
+ def powerg_light(self) -> float | None:
289
+ return self._powerg_light
290
+
291
+ @property
292
+ def powerg_status_data(self) -> str:
293
+ return self._powerg_status_data
294
+
295
+ @powerg_temperature.setter
296
+ def powerg_temperature(self, value: str) -> None:
297
+ if self._powerg_temperature != value:
298
+ LOGGER.debug("Zone%s (%s) - powerg_temperature: %s", self._zone_id, self.sensorname, value)
299
+ self._powerg_temperature = value
300
+ self.notify()
301
+
302
+ @powerg_light.setter
303
+ def powerg_light(self, value: str) -> None:
304
+ if self._powerg_light != value:
305
+ LOGGER.debug("Zone%s (%s) - powerg_light: %s", self._zone_id, self.sensorname, value)
306
+ self._powerg_light = value
307
+ self.notify()
308
+
309
+ @powerg_status_data.setter
310
+ def powerg_status_data(self, value: str) -> None:
311
+ if self._powerg_status_data != value:
312
+ LOGGER.debug("Zone%s (%s) - powerg_status_data: %s", self._zone_id, self.sensorname, value)
313
+ self._powerg_status_data = value
314
+ self.notify()
315
+
220
316
  @averagedBm.setter
221
317
  def averagedBm(self, value: str) -> None:
222
318
  if self._averagedBm != value:
@@ -303,6 +399,20 @@ class QolsysZone(QolsysObservable):
303
399
  self.partition_id = value
304
400
  self.notify()
305
401
 
402
+ def to_powerg_dict(self) -> dict:
403
+ return {
404
+ "shortID": self.shortID,
405
+ "longID": self._powerg_long_id,
406
+ "status_data": self._powerg_status_data,
407
+ "temperature": self._powerg_temperature,
408
+ "light": self._powerg_light,
409
+ "notification_period": self._powerg_notification_period,
410
+ "average_link_quality": self._powerg_average_link_quality,
411
+ "link_quality": self._powerg_link_quality,
412
+ "link_status": self._powerg_link_status,
413
+ "battery_voltage": self._powerg_battery_voltage,
414
+ }
415
+
306
416
  def to_dict(self) -> dict:
307
417
  return {
308
418
  "_id": self.id,