emerald-hws 0.0.14__py3-none-any.whl → 0.0.16__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.
emerald_hws/emeraldhws.py CHANGED
@@ -39,6 +39,7 @@ class EmeraldHWS():
39
39
  self.properties = {}
40
40
  self.logger = logging.getLogger(__name__)
41
41
  self.update_callback = update_callback
42
+ self._state_lock = threading.RLock() # Thread-safe lock for state operations
42
43
 
43
44
  # Convert minutes to seconds for internal use
44
45
  self.connection_timeout = connection_timeout_minutes * 60.0
@@ -332,11 +333,14 @@ class EmeraldHWS():
332
333
  :param value: value to set
333
334
  """
334
335
 
335
- for properties in self.properties:
336
- heat_pumps = properties.get('heat_pump', [])
337
- for heat_pump in heat_pumps:
338
- if heat_pump['id'] == id:
339
- heat_pump['last_state'][key] = value
336
+ with self._state_lock:
337
+ for properties in self.properties:
338
+ heat_pumps = properties.get('heat_pump', [])
339
+ for heat_pump in heat_pumps:
340
+ if heat_pump['id'] == id:
341
+ heat_pump['last_state'][key] = value
342
+
343
+ # Call callback AFTER releasing lock to avoid potential deadlocks
340
344
  if self.update_callback is not None:
341
345
  self.update_callback()
342
346
 
@@ -365,11 +369,13 @@ class EmeraldHWS():
365
369
  if not self.properties:
366
370
  self.connect()
367
371
 
368
- for properties in self.properties:
369
- heat_pumps = properties.get('heat_pump', [])
370
- for heat_pump in heat_pumps:
371
- if heat_pump['id'] == id:
372
- return heat_pump
372
+ with self._state_lock:
373
+ for properties in self.properties:
374
+ heat_pumps = properties.get('heat_pump', [])
375
+ for heat_pump in heat_pumps:
376
+ if heat_pump['id'] == id:
377
+ return heat_pump
378
+ return None
373
379
 
374
380
  def sendControlMessage(self, id, payload):
375
381
  """ Sends a message via MQTT to the HWS
@@ -381,6 +387,8 @@ class EmeraldHWS():
381
387
  self.connect()
382
388
 
383
389
  hwsdetail = self.getFullStatus(id)
390
+ if not hwsdetail:
391
+ raise Exception(f"Unable to find HWS with ID {id}")
384
392
 
385
393
  msg = [{"device_id":id,
386
394
  "namespace":"business",
@@ -439,35 +447,54 @@ class EmeraldHWS():
439
447
  """ Returns true if the specified HWS is currently on
440
448
  :param id: The UUID of the HWS to query
441
449
  """
442
- switch_status = self.getFullStatus(id).get("last_state").get("switch")
443
- return (switch_status == 1 or switch_status == "on")
450
+ full_status = self.getFullStatus(id)
451
+ if full_status and full_status.get("last_state"):
452
+ switch_status = full_status.get("last_state").get("switch")
453
+ return (switch_status == 1 or switch_status == "on")
454
+ return False
444
455
 
445
456
  def isHeating(self, id):
446
457
  """ Returns true if the specified HWS is currently heating
447
458
  :param id: The UUID of the HWS to query
448
459
  """
449
- heating_status = self.getFullStatus(id).get("device_operation_status")
450
- return (heating_status == 1)
460
+ full_status = self.getFullStatus(id)
461
+ if full_status:
462
+ # Try to get work_state from last_state (updated via MQTT)
463
+ if full_status.get("last_state") and "work_state" in full_status.get("last_state"):
464
+ work_state = full_status.get("last_state").get("work_state")
465
+ # work_state: 0=off/idle, 1=actively heating, 2=on but not heating
466
+ return (work_state == 1)
467
+
468
+ # Fallback to device_operation_status if work_state not available yet
469
+ # (e.g., before first MQTT update after initialization)
470
+ heating_status = full_status.get("device_operation_status")
471
+ return (heating_status == 1)
472
+
473
+ return False
451
474
 
452
475
  def currentMode(self, id):
453
476
  """ Returns an integer specifying the current mode (0==boost, 1==normal, 2==quiet)
454
477
  :param id: The UUID of the HWS to query
455
478
  """
456
- mode_status = self.getFullStatus(id).get("last_state").get("mode")
457
- return mode_status
479
+ full_status = self.getFullStatus(id)
480
+ if full_status and full_status.get("last_state"):
481
+ mode_status = full_status.get("last_state").get("mode")
482
+ return mode_status
483
+ return None
458
484
 
459
485
  def getInfo(self, id):
460
486
  """ Returns identifying details for the specified HWS
461
487
  :param id: The UUID of the HWS to query
462
488
  """
463
489
  full_status = self.getFullStatus(id)
464
-
465
- return {'id': id,
466
- 'serial_number': full_status.get("serial_number"),
467
- 'brand': full_status.get("brand"),
468
- 'hw_version': full_status.get("hw_version"),
469
- 'soft_version': full_status.get("soft_version")
470
- }
490
+ if full_status:
491
+ return {'id': id,
492
+ 'serial_number': full_status.get("serial_number"),
493
+ 'brand': full_status.get("brand"),
494
+ 'hw_version': full_status.get("hw_version"),
495
+ 'soft_version': full_status.get("soft_version")
496
+ }
497
+ return None
471
498
 
472
499
  def listHWS(self):
473
500
  """ Returns a list of UUIDs of all discovered HWS
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: emerald_hws
3
- Version: 0.0.14
3
+ Version: 0.0.16
4
4
  Summary: A package to manipulate and monitor Emerald Heat Pump Hot Water Systems
5
5
  Author-email: Ross Williamson <ross@inertia.net.nz>
6
6
  License-Expression: MIT
@@ -0,0 +1,7 @@
1
+ emerald_hws/__init__.py,sha256=uukjQ-kiPYKWvGT3jLL6kJA1DCNAxtw4HlLKqPSypXs,61
2
+ emerald_hws/emeraldhws.py,sha256=in2F-kUyKXGQApvm00L2DH3CSXFj4H_1Vapnxkfa7xM,23416
3
+ emerald_hws/__assets__/SFSRootCAG2.pem,sha256=hw9W0AnYrrlbcWsOewAgIl1ULEsoO57Ylu35dCjWcS4,1424
4
+ emerald_hws-0.0.16.dist-info/METADATA,sha256=X2bALg477JBnh4JUPD8MaEgWJiEjyh0INb5QMbGiHxE,2534
5
+ emerald_hws-0.0.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
+ emerald_hws-0.0.16.dist-info/top_level.txt,sha256=ZCiUmnBkDr2n4QVkTet1s_AKiGJjuz3heuCR5w5ZqLY,12
7
+ emerald_hws-0.0.16.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- emerald_hws/__init__.py,sha256=uukjQ-kiPYKWvGT3jLL6kJA1DCNAxtw4HlLKqPSypXs,61
2
- emerald_hws/emeraldhws.py,sha256=7q-T6jaujtxplGXb4GdnuiBHZLwMrdSlJT14pmn6nw0,22100
3
- emerald_hws/__assets__/SFSRootCAG2.pem,sha256=hw9W0AnYrrlbcWsOewAgIl1ULEsoO57Ylu35dCjWcS4,1424
4
- emerald_hws-0.0.14.dist-info/METADATA,sha256=RRcMNq_lWNHsZigorD4i1tlYfOlAf-9PCBPYMGUlUDs,2534
5
- emerald_hws-0.0.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
- emerald_hws-0.0.14.dist-info/top_level.txt,sha256=ZCiUmnBkDr2n4QVkTet1s_AKiGJjuz3heuCR5w5ZqLY,12
7
- emerald_hws-0.0.14.dist-info/RECORD,,