nwp500-python 9.4.0__py3-none-any.whl → 9.4.2__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.
nwp500/converters.py CHANGED
@@ -45,7 +45,7 @@ __all__ = [
45
45
  #: p90 4.45), agreeing to within 2% by a noisier route
46
46
  #: * the same recoveries imply a heat pump COP of 2.89 at 4 Wh/count
47
47
  #:
48
- #: Library versions before 10.0 used 10 Wh/count, which overstated reported
48
+ #: Library versions before 9.3.0 used 10 Wh/count, which overstated reported
49
49
  #: tank energy by 2.5x and implied a physically impossible COP of 7.0.
50
50
  #:
51
51
  #: See ``docs/explanation/tank-energy.rst`` for the full derivation.
@@ -347,6 +347,13 @@ class MqttReconnectionHandler:
347
347
  f"Error during reconnection attempt: {e}", exc_info=True
348
348
  )
349
349
 
350
+ # A successful quick or deep reconnect builds a new connection, so
351
+ # the SDK never calls on_connection_resumed for it. Reset the
352
+ # counter here, or every later interruption starts with a longer
353
+ # backoff and an earlier deep reconnect than the first one did.
354
+ if self._is_connected_func():
355
+ self._reconnect_attempts = 0
356
+
350
357
  # Check final state: report failure when retries are exhausted
351
358
  # (limited mode) or a fatal error stopped the loop.
352
359
  attempts_exhausted = (
@@ -40,7 +40,12 @@ from ..mqtt_events import (
40
40
  from ..topic_builder import MqttTopicBuilder
41
41
  from .state_tracker import DeviceStateTracker
42
42
  from .types import QoS, to_awscrt_qos
43
- from .utils import get_response_data, redact_topic, topic_matches_pattern
43
+ from .utils import (
44
+ get_response_data,
45
+ redact_mac,
46
+ redact_topic,
47
+ topic_matches_pattern,
48
+ )
44
49
 
45
50
  if TYPE_CHECKING:
46
51
  from ..device_info_cache import MqttDeviceInfoCache
@@ -614,13 +619,45 @@ class MqttSubscriptionManager:
614
619
  """
615
620
 
616
621
  def handler(topic: str, message: dict[str, Any]) -> None:
622
+ # Every branch that declines a message says so at debug level.
623
+ # Silence here is expensive to diagnose: a caller watching for a
624
+ # reply that never reaches its callback cannot tell a dropped
625
+ # message from one the cloud never sent, and the two want
626
+ # opposite fixes. The logs are the only evidence either way.
627
+ #
628
+ # Each log is guarded: redact_topic runs a dozen regexes, and
629
+ # these branches are the normal case for a handler registered
630
+ # under the device wildcard, which sees every message for that
631
+ # device and keeps only its own.
617
632
  if topic_suffix and not topic.endswith(topic_suffix):
633
+ if _logger.isEnabledFor(logging.DEBUG):
634
+ _logger.debug(
635
+ "Ignoring a message on %s: the topic does not end "
636
+ "with %r, which this handler requires",
637
+ redact_topic(topic),
638
+ topic_suffix,
639
+ )
618
640
  return
619
641
  try:
620
642
  data = get_response_data(message, key)
621
643
  if not data:
644
+ if _logger.isEnabledFor(logging.DEBUG):
645
+ _logger.debug(
646
+ "Ignoring a message on %s: no %s data to parse "
647
+ "as %s",
648
+ redact_topic(topic),
649
+ f"{key!r}" if key else "response",
650
+ model.__name__,
651
+ )
622
652
  return
623
653
  if only_mac and not _same_device(data, message, only_mac):
654
+ if _logger.isEnabledFor(logging.DEBUG):
655
+ _logger.debug(
656
+ "Ignoring a message on %s: it names another "
657
+ "device, not %s",
658
+ redact_topic(topic),
659
+ redact_mac(only_mac),
660
+ )
624
661
  return
625
662
 
626
663
  parsed = parse(data) if parse else model.model_validate(data)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nwp500-python
3
- Version: 9.4.0
3
+ Version: 9.4.2
4
4
  Summary: A library for controlling Navien NWP500 Water Heaters via NaviLink
5
5
  Home-page: https://github.com/eman/nwp500-python
6
6
  Author: Emmanuel Levijarvi
@@ -4,7 +4,7 @@ nwp500/api_client.py,sha256=4O4hV4mNwxXpbDFu-cEN36-edNW2-fGl9akzF4a437E,18342
4
4
  nwp500/auth.py,sha256=_XRmkCiFtxQ7H_xwF7tF1kJW8tce2qhJMVfKK9bgZo4,33783
5
5
  nwp500/command_decorators.py,sha256=VV0DC9lxA0tQJvGmkxMVmeD7BTRuSOx7SXFiz6US6rI,4947
6
6
  nwp500/config.py,sha256=S47toIsQJuuEZgYt7xiWFnFjWm4Cp0cBS2VPR6lYejY,299
7
- nwp500/converters.py,sha256=o4EOdtm0wIbAsMcXlhRf2fnooI8ms284qkbuVWQr-HE,7392
7
+ nwp500/converters.py,sha256=FZE3treCCUQYLE0J9ewlMtHKpVv6rgiYn9En90Ibsw8,7393
8
8
  nwp500/device_capabilities.py,sha256=FXoV6eOhO9aYF3UFQVa89t0Bw180afQvLM8D3Ihua2c,4685
9
9
  nwp500/device_info_cache.py,sha256=8AdPbY-zA-ajwTTMI3Tnthd8BOE2GY4Lj6c6FH-0GgI,6150
10
10
  nwp500/encoding.py,sha256=RhtbUS7K72jEMBDLDOD42hv40VgQHxb3lKqccvx8Ngg,19223
@@ -50,14 +50,14 @@ nwp500/mqtt/connection.py,sha256=fNrOtBJxsqk054YDUmipnwI3yfBHx1anXb_07e0X9XU,177
50
50
  nwp500/mqtt/control.py,sha256=tw4Ih7ZClpHIE2oqcPQZuw5E174RiiJvuccPKYQWsr0,41071
51
51
  nwp500/mqtt/diagnostics.py,sha256=NDkPExS4FObGCWJXAhENqNQUm8Bda5GDBR7_o3ylSAo,15723
52
52
  nwp500/mqtt/periodic.py,sha256=WKyyO61yTZJfOm9JAtBp6Onyk-XNj0U544sYMCKvTZw,14729
53
- nwp500/mqtt/reconnection.py,sha256=5SEj1vV5_QWXlApnKnUeFWAT-MgWnnu6M_vhiqTQh14,16129
53
+ nwp500/mqtt/reconnection.py,sha256=g9OuLlf1lVx_pbV6d7QHq7IcCflKkypPYSLSDTp58tQ,16499
54
54
  nwp500/mqtt/state_tracker.py,sha256=uZlDFNYn7DOXmXPbk-8jXva_QKEvLES9T_BYbQSkhvM,6364
55
- nwp500/mqtt/subscriptions.py,sha256=iCcXwP8KDRXqShlxdkbxGFk9e11i4YrD88kWKcp8cP8,38094
55
+ nwp500/mqtt/subscriptions.py,sha256=lBO4IM_5bQbexhARy-PNf36aKNJNx9iiWQMgiMe5Y_0,39853
56
56
  nwp500/mqtt/types.py,sha256=86R7gwsc1XabA_ABWeALeC5EImlTziFFn1DrP1x8Yy4,1605
57
57
  nwp500/mqtt/utils.py,sha256=qXafc9GDpVY9o9o8DQLKBM8t0E401j3EPpZ0rC4snCY,13415
58
- nwp500_python-9.4.0.dist-info/licenses/LICENSE.txt,sha256=EUOsypJ3iEqJ-9tdo_TSZHwB0Rd-7p0JzToEI5CMBJU,1085
59
- nwp500_python-9.4.0.dist-info/METADATA,sha256=iP_DrnoAtfIryvqV3oX57MTTSn2bNoDDVHbcs7MQxIQ,5091
60
- nwp500_python-9.4.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
61
- nwp500_python-9.4.0.dist-info/entry_points.txt,sha256=p8vGDEbUIOT_TzDG-XnJ3lw-9yaeHrDPNN7fAx4-78I,52
62
- nwp500_python-9.4.0.dist-info/top_level.txt,sha256=DRPIenxKnssWeaetq428gYfwrKjLGN1z2NOtztIvxZE,7
63
- nwp500_python-9.4.0.dist-info/RECORD,,
58
+ nwp500_python-9.4.2.dist-info/licenses/LICENSE.txt,sha256=EUOsypJ3iEqJ-9tdo_TSZHwB0Rd-7p0JzToEI5CMBJU,1085
59
+ nwp500_python-9.4.2.dist-info/METADATA,sha256=rF8G2SyPDoYEgSQJl3dTjKhkLW40a0ISpD8hx1dx5Xs,5091
60
+ nwp500_python-9.4.2.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
61
+ nwp500_python-9.4.2.dist-info/entry_points.txt,sha256=p8vGDEbUIOT_TzDG-XnJ3lw-9yaeHrDPNN7fAx4-78I,52
62
+ nwp500_python-9.4.2.dist-info/top_level.txt,sha256=DRPIenxKnssWeaetq428gYfwrKjLGN1z2NOtztIvxZE,7
63
+ nwp500_python-9.4.2.dist-info/RECORD,,