nwp500-python 6.0.0__tar.gz → 6.0.2__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.
Files changed (136) hide show
  1. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/.github/copilot-instructions.md +5 -5
  2. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/.gitignore +1 -0
  3. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/CHANGELOG.rst +23 -0
  4. {nwp500_python-6.0.0/src/nwp500_python.egg-info → nwp500_python-6.0.2}/PKG-INFO +2 -2
  5. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/development/history.rst +20 -34
  6. nwp500_python-6.0.2/docs/guides/advanced_features_explained.rst +495 -0
  7. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/guides/auto_recovery.rst +12 -12
  8. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/guides/event_system.rst +2 -2
  9. nwp500_python-6.0.2/docs/guides/scheduling_features.rst +401 -0
  10. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/index.rst +2 -0
  11. nwp500_python-6.0.2/docs/protocol/data_conversions.rst +636 -0
  12. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/protocol/device_features.rst +3 -3
  13. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/python_api/api_client.rst +5 -5
  14. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/python_api/auth_client.rst +1 -1
  15. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/python_api/cli.rst +10 -10
  16. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/python_api/constants.rst +2 -2
  17. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/python_api/events.rst +4 -4
  18. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/python_api/models.rst +11 -11
  19. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/python_api/mqtt_client.rst +2 -2
  20. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/quickstart.rst +3 -3
  21. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/README.md +1 -1
  22. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/api_client_example.py +19 -15
  23. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/auth_constructor_example.py +1 -1
  24. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/authenticate.py +7 -5
  25. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/auto_recovery_example.py +6 -6
  26. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/combined_callbacks.py +9 -9
  27. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/command_queue_demo.py +23 -19
  28. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/device_feature_callback.py +11 -11
  29. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/device_status_callback.py +11 -11
  30. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/device_status_callback_debug.py +16 -14
  31. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/energy_usage_example.py +9 -9
  32. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/event_emitter_demo.py +24 -20
  33. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/exception_handling_example.py +19 -19
  34. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/improved_auth_pattern.py +4 -4
  35. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/mqtt_client_example.py +13 -13
  36. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/periodic_requests.py +2 -2
  37. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/reconnection_demo.py +8 -8
  38. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/simple_auto_recovery.py +4 -4
  39. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/test_api_client.py +37 -27
  40. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/test_mqtt_connection.py +18 -14
  41. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/test_mqtt_messaging.py +23 -19
  42. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/token_restoration_example.py +5 -5
  43. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/scripts/README.md +7 -7
  44. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/scripts/bump_version.py +3 -26
  45. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/scripts/format.py +5 -5
  46. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/scripts/lint.py +5 -5
  47. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/scripts/setup-dev.py +5 -5
  48. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/scripts/validate_version.py +69 -39
  49. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/setup.cfg +1 -1
  50. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/auth.py +22 -4
  51. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/models.py +6 -0
  52. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/mqtt_connection.py +14 -0
  53. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/mqtt_periodic.py +17 -6
  54. {nwp500_python-6.0.0 → nwp500_python-6.0.2/src/nwp500_python.egg-info}/PKG-INFO +2 -2
  55. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500_python.egg-info/SOURCES.txt +3 -0
  56. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500_python.egg-info/requires.txt +1 -1
  57. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/.coveragerc +0 -0
  58. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/.github/workflows/ci.yml +0 -0
  59. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/.github/workflows/release.yml +0 -0
  60. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/.pre-commit-config.yaml +0 -0
  61. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/.readthedocs.yml +0 -0
  62. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/AUTHORS.rst +0 -0
  63. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/CONTRIBUTING.rst +0 -0
  64. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/LICENSE.txt +0 -0
  65. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/Makefile +0 -0
  66. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/README.rst +0 -0
  67. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/RELEASE.md +0 -0
  68. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/Makefile +0 -0
  69. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/_static/.gitignore +0 -0
  70. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/authors.rst +0 -0
  71. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/changelog.rst +0 -0
  72. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/conf.py +0 -0
  73. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/configuration.rst +0 -0
  74. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/development/contributing.rst +0 -0
  75. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/guides/command_queue.rst +0 -0
  76. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/guides/energy_monitoring.rst +0 -0
  77. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/guides/reservations.rst +0 -0
  78. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/guides/time_of_use.rst +0 -0
  79. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/installation.rst +0 -0
  80. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/license.rst +0 -0
  81. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/openapi.yaml +0 -0
  82. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/protocol/device_status.rst +0 -0
  83. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/protocol/error_codes.rst +0 -0
  84. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/protocol/firmware_tracking.rst +0 -0
  85. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/protocol/mqtt_protocol.rst +0 -0
  86. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/protocol/rest_api.rst +0 -0
  87. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/python_api/exceptions.rst +0 -0
  88. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/docs/requirements.txt +0 -0
  89. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/.ruff.toml +0 -0
  90. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/anti_legionella_example.py +0 -0
  91. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/mask.py +0 -0
  92. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/periodic_device_info.py +0 -0
  93. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/power_control_example.py +0 -0
  94. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/reservation_schedule_example.py +0 -0
  95. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/set_dhw_temperature_example.py +0 -0
  96. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/set_mode_example.py +0 -0
  97. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/simple_periodic_info.py +0 -0
  98. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/simple_periodic_status.py +0 -0
  99. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/test_periodic_minimal.py +0 -0
  100. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/tou_openei_example.py +0 -0
  101. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/examples/tou_schedule_example.py +0 -0
  102. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/pyproject.toml +0 -0
  103. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/setup.py +0 -0
  104. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/__init__.py +0 -0
  105. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/api_client.py +0 -0
  106. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/cli/__init__.py +0 -0
  107. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/cli/__main__.py +0 -0
  108. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/cli/commands.py +0 -0
  109. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/cli/monitoring.py +0 -0
  110. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/cli/output_formatters.py +0 -0
  111. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/cli/token_storage.py +0 -0
  112. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/config.py +0 -0
  113. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/constants.py +0 -0
  114. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/encoding.py +0 -0
  115. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/events.py +0 -0
  116. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/exceptions.py +0 -0
  117. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/mqtt_client.py +0 -0
  118. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/mqtt_command_queue.py +0 -0
  119. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/mqtt_device_control.py +0 -0
  120. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/mqtt_reconnection.py +0 -0
  121. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/mqtt_subscriptions.py +0 -0
  122. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/mqtt_utils.py +0 -0
  123. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/py.typed +0 -0
  124. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500/utils.py +0 -0
  125. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500_python.egg-info/dependency_links.txt +0 -0
  126. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500_python.egg-info/entry_points.txt +0 -0
  127. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500_python.egg-info/not-zip-safe +0 -0
  128. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/src/nwp500_python.egg-info/top_level.txt +0 -0
  129. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/tests/conftest.py +0 -0
  130. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/tests/test_api_helpers.py +0 -0
  131. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/tests/test_auth.py +0 -0
  132. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/tests/test_command_queue.py +0 -0
  133. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/tests/test_events.py +0 -0
  134. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/tests/test_exceptions.py +0 -0
  135. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/tests/test_utils.py +0 -0
  136. {nwp500_python-6.0.0 → nwp500_python-6.0.2}/tox.ini +0 -0
@@ -74,9 +74,9 @@ Report the results of these checks in your final summary, including:
74
74
 
75
75
  ### After Completing a Task
76
76
  Document validation results:
77
- - **Linting**: All checks passed
78
- - **Type checking**: No errors found
79
- - **Tests**: X/X passed (or "N/A - no existing tests for this feature")
77
+ - **Linting**: All checks passed
78
+ - **Type checking**: No errors found
79
+ - **Tests**: X/X passed (or "N/A - no existing tests for this feature")
80
80
 
81
81
  ## Patterns & Conventions
82
82
  - **Async context managers** for authentication: `async with NavienAuthClient(email, password) as auth_client:`
@@ -156,8 +156,8 @@ Removed
156
156
  ```
157
157
  ## Final Results
158
158
  **Starting point:** X errors
159
- **Ending point:** 0 errors
160
- **Tests:** All passing
159
+ **Ending point:** 0 errors
160
+ **Tests:** All passing
161
161
 
162
162
  ## What Was Fixed
163
163
  - Module 1 - Brief description (N errors)
@@ -55,3 +55,4 @@ venv*/
55
55
  .python-version
56
56
  .secrets
57
57
  reference/*
58
+ resources/*
@@ -2,6 +2,29 @@
2
2
  Changelog
3
3
  =========
4
4
 
5
+ Version 6.0.2 (2025-11-15)
6
+ ==========================
7
+
8
+ Fixed
9
+ -----
10
+
11
+ - DNS resolution in containerized environments using ThreadedResolver
12
+ - Updated AWS IoT library version
13
+ - Device status field conversions
14
+
15
+ Changed
16
+ -------
17
+
18
+ - Refactored ThreadedResolver session creation into helper method
19
+
20
+ Version 6.0.1 (2025-11-06)
21
+ ==========================
22
+
23
+ Fixed
24
+ -----
25
+
26
+ - Minor bug fixes and improvements
27
+
5
28
  Version 6.0.0 (2025-11-02)
6
29
  ==========================
7
30
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nwp500-python
3
- Version: 6.0.0
3
+ Version: 6.0.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
@@ -23,7 +23,7 @@ Requires-Python: >=3.9
23
23
  Description-Content-Type: text/x-rst; charset=UTF-8
24
24
  License-File: LICENSE.txt
25
25
  Requires-Dist: aiohttp>=3.8.0
26
- Requires-Dist: awsiotsdk>=1.25.0
26
+ Requires-Dist: awsiotsdk>=1.26.0
27
27
  Provides-Extra: testing
28
28
  Requires-Dist: setuptools; extra == "testing"
29
29
  Requires-Dist: pytest; extra == "testing"
@@ -23,24 +23,22 @@ providing:
23
23
  Current Status
24
24
  --------------
25
25
 
26
- **Production Ready** ✅
27
-
28
26
  The library is feature-complete with:
29
27
 
30
- - Complete authentication (AWS Cognito + JWT)
31
- - REST API client (all endpoints)
32
- - MQTT client with real-time communication
33
- - Event emitter pattern (Phase 1 complete)
34
- - Automatic reconnection with exponential backoff
35
- - Command queue for disconnection handling
36
- - Device control (power, temperature, modes)
37
- - Real-time monitoring (status, features, energy)
38
- - Historical energy usage data (daily breakdown)
39
- - Thread-safe event emission from MQTT callbacks
40
- - Comprehensive documentation
41
- - Working examples for all features
42
- - Unit tests with good coverage
43
- - Python 3.9+ with modern type hints
28
+ - Complete authentication (AWS Cognito + JWT)
29
+ - REST API client (all endpoints)
30
+ - MQTT client with real-time communication
31
+ - Event emitter pattern (Phase 1 complete)
32
+ - Automatic reconnection with exponential backoff
33
+ - Command queue for disconnection handling
34
+ - Device control (power, temperature, modes)
35
+ - Real-time monitoring (status, features, energy)
36
+ - Historical energy usage data (daily breakdown)
37
+ - Thread-safe event emission from MQTT callbacks
38
+ - Comprehensive documentation
39
+ - Working examples for all features
40
+ - Unit tests with good coverage
41
+ - Python 3.9+ with modern type hints
44
42
 
45
43
  Implementation Milestones
46
44
  -------------------------
@@ -116,7 +114,7 @@ query example
116
114
  Energy Data API (October 7, 2025)
117
115
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118
116
 
119
- **Status:** Implemented
117
+ **Status:** Implemented
120
118
 
121
119
  Complete energy monitoring capabilities including historical data:
122
120
 
@@ -175,18 +173,18 @@ Testing & Verification
175
173
 
176
174
  All components have been tested with real Navien NWP500 devices:
177
175
 
178
- **Authentication:** Verified with production API - Sign-in flow
176
+ **Authentication:** Verified with production API - Sign-in flow
179
177
  working - Token refresh working - AWS credentials properly obtained
180
178
 
181
- **REST API:** All endpoints tested - Device listing working - Device
179
+ **REST API:** All endpoints tested - Device listing working - Device
182
180
  info retrieval working - Firmware info working
183
181
 
184
- **MQTT Client:** Real-time communication verified - WebSocket
182
+ **MQTT Client:** Real-time communication verified - WebSocket
185
183
  connection established - Commands sent and acknowledged - Status
186
184
  messages received and parsed - Device control working (power,
187
185
  temperature, mode)
188
186
 
189
- **Test Coverage:** Comprehensive - Unit tests for data models -
187
+ **Test Coverage:** Comprehensive - Unit tests for data models -
190
188
  Integration tests with real API - Interactive examples for all features
191
189
 
192
190
  Architecture Decisions
@@ -282,7 +280,7 @@ MQTT callbacks run in separate threads (e.g., 'Dummy-1') created by AWS IoT SDK.
282
280
  Command Queue Implementation
283
281
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
284
282
 
285
- **Status:** Implemented
283
+ **Status:** Implemented
286
284
 
287
285
  Automatic command queuing for reliable communication during network
288
286
  interruptions:
@@ -321,18 +319,6 @@ Modernized codebase to use Python 3.9+ native type hints (PEP 585):
321
319
  - Python version classifiers added (3.9-3.13)
322
320
  - ruff target-version updated to py39
323
321
 
324
- Future Enhancements
325
- -------------------
326
-
327
- Potential areas for future development:
328
-
329
- 1. **Event System Phase 2:** Event filtering with lambda conditions, event middleware, event buffering and replay
330
- 2. **Event System Phase 3:** Event namespacing with wildcards (``device.*``), event history and time-travel debugging, performance metrics and monitoring
331
- 3. **Multiple Devices:** Efficient handling of multiple simultaneous device connections
332
- 4. **Configuration Validation:** Validate settings against device capabilities
333
- 5. **Command Priority Queue:** Different priority levels for different command types
334
- 6. **Queue Persistence:** Save queue to disk for recovery after restart
335
-
336
322
  References
337
323
  ----------
338
324
 
@@ -0,0 +1,495 @@
1
+ Advanced Features Explained: Weather-Responsive Heating, Demand Response, and Tank Stratification
2
+ ==================================================================================================
3
+
4
+ This document provides comprehensive technical documentation for three advanced NWP500 features.
5
+
6
+ Overview of Advanced Features
7
+ -----------------------------
8
+
9
+ The NWP500 heat pump water heater implements sophisticated algorithms for grid integration, environmental responsiveness, and efficiency optimization:
10
+
11
+ 1. **Weather-Responsive Heating** - Adjusts heating strategy based on ambient temperature conditions
12
+ 2. **Demand Response Integration** - Responds to grid signals for demand/response events (CTA-2045)
13
+ 3. **Tank Stratification Optimization** - Uses dual temperature sensors for enhanced heating efficiency
14
+
15
+ Weather-Responsive Heating
16
+ ==========================
17
+
18
+ Feature Overview
19
+ ^^^^^^^^^^^^^^^^
20
+
21
+ The device continuously monitors ambient air temperature to optimize heat pump performance and adjust heating strategies. This enables the system to maintain comfort while adapting to seasonal conditions automatically.
22
+
23
+ Technical Implementation
24
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
25
+
26
+ **Data Sources**:
27
+
28
+ - ``ambientTemperature`` (decicelsius_to_f): Heat pump outlet air temperature measurement
29
+ - ``outsideTemperature`` (raw integer): Weather data temperature from cloud API/device configuration
30
+ - ``evaporatorTemperature`` (decicelsius_to_f): Evaporator coil temperature during heat pump operation
31
+
32
+
33
+ How It Works
34
+ ^^^^^^^^^^^^
35
+
36
+ **Temperature Thresholds and Heating Adjustments**:
37
+
38
+ 1. **High Ambient Temperature (>70°F / 21°C)**
39
+ - Heat pump COP (Coefficient of Performance) is high
40
+ - Device prioritizes heat pump operation over electric heating
41
+ - Lower superheat targets for efficient operation
42
+ - Reduced compressor activation frequency
43
+
44
+ 2. **Moderate Ambient Temperature (50-70°F / 10-21°C)**
45
+ - Balanced hybrid approach
46
+ - Heat pump and electric elements coordinate
47
+ - Optimal range for most climates
48
+ - Device operates with default efficiency settings
49
+
50
+ 3. **Cold Ambient Temperature (<50°F / 10°C)**
51
+ - Heat pump efficiency decreases significantly
52
+ - Device pre-charges tank before peak demand periods
53
+ - Electric heating elements engage more frequently
54
+ - At freezing (32°F / 0°C), COP drops 40-50% from optimal
55
+
56
+ 4. **Extreme Cold (<20°F / -7°C)**
57
+ - Heat pump operation becomes inefficient
58
+ - Device may default to electric-only mode during these periods
59
+ - Freeze protection mechanisms activate automatically
60
+ - Recovery time increases significantly
61
+
62
+ **Algorithm Parameters**:
63
+
64
+ The device maintains internal target superheat values that adjust based on ambient conditions. Superheat represents the temperature difference between evaporator outlet and compressor suction:
65
+
66
+ .. code-block:: text
67
+
68
+ Ideal superheat target: 10-20°F (5.5-11°C)
69
+
70
+ Ambient 90°F: Target = 12°F (easier to achieve)
71
+ Ambient 60°F: Target = 15°F (standard)
72
+ Ambient 30°F: Target = 18°F (challenging, may not be achievable)
73
+
74
+ **Compressor Control Adjustments**:
75
+
76
+ - **High Ambient**: Lower ON/OFF temperature setpoints, reduced cycle frequency
77
+ - **Low Ambient**: Higher ON/OFF temperature setpoints, increased cycle frequency
78
+ - **Recovery Override**: Pre-charging during known demand periods (morning peak)
79
+
80
+ Practical Applications
81
+ ^^^^^^^^^^^^^^^^^^^^^^^
82
+
83
+ **Morning Peak Scenario (40°F Ambient)**:
84
+
85
+ 1. Device detects low ambient temperature overnight
86
+ 2. If reservation calls for 140°F by 7 AM, device may start pre-charging at 5 AM
87
+ 3. Uses both heat pump and electric elements (hybrid mode)
88
+ 4. Reaches 140°F with hybrid approach, avoiding delay
89
+
90
+ **Cold Spell Scenario (20°F Ambient)**:
91
+
92
+ 1. Device measures 20°F ambient, knows COP is ~1.8
93
+ 2. Switches to electric-only mode if heating needed
94
+ 3. Avoids inefficient heat pump cycles
95
+ 4. Reduces overall energy consumption despite higher per-BTU cost
96
+
97
+ **Seasonal Optimization (Summer 90°F)**:
98
+
99
+ 1. Device sees high ambient temperature
100
+ 2. Enables heat pump operation even for small heating demand
101
+ 3. Operates compressor at lower speeds for precise temperature control
102
+ 4. Achieves 3.5+ COP (for every 1 kW electrical, 3.5 kW of heat)
103
+
104
+ Integration with MQTT Status Message
105
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
106
+
107
+ The ``outsideTemperature`` field is transmitted in the device status update. Python clients can monitor this field:
108
+
109
+ .. code-block:: python
110
+
111
+ # From device status updates
112
+ status = await mqtt_client.get_status()
113
+
114
+ # Access ambient temperature data
115
+ outdoor_temp = status.outside_temperature # Raw integer value
116
+ measured_ambient = status.ambient_temperature # Heat pump inlet measurement
117
+ evaporator_temp = status.evaporator_temperature # Coil temperature
118
+
119
+ Demand Response Integration (CTA-2045)
120
+ ======================================
121
+
122
+ Feature Overview
123
+ ^^^^^^^^^^^^^^^^
124
+
125
+ The NWP500 supports demand response signals per the CTA-2045 (Consumer Technology Association) standard, enabling integration with smart grid programs and demand response events.
126
+
127
+ **CTA-2045 Standard**:
128
+
129
+ A protocol that allows utilities to send control signals to networked devices (like water heaters) to manage demand during peak periods or grid stress conditions.
130
+
131
+ Technical Implementation
132
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
133
+ DR Event Status Field
134
+ ^^^^^^^^^^^^^^^^^^^^^
135
+
136
+ **Field**: ``drEventStatus`` (bitfield)
137
+
138
+ **Type**: Integer (bitfield, each bit represents a different DR signal)
139
+
140
+ **Values**:
141
+ - ``0``: No active DR events
142
+ - Non-zero: One or more DR signals active (specific bits depend on utility implementation)
143
+
144
+ **Typical Signal Meanings**:
145
+
146
+ .. list-table::
147
+ :header-rows: 1
148
+ :widths: 15 15 30 40
149
+
150
+ * - Signal
151
+ - Typical Cost
152
+ - Expected Duration
153
+ - Device Response
154
+ * - Shed (Bit 0)
155
+ - Very High
156
+ - 30-60 minutes
157
+ - Stop heating, reduce temperature
158
+ * - Reduce (Bit 1)
159
+ - High
160
+ - 1-4 hours
161
+ - Reduce heating, use heat pump only
162
+ * - Normal (Bit 2)
163
+ - Moderate
164
+ - Continuous
165
+ - Standard operation
166
+ * - Pre-charge (Bit 3)
167
+ - Low
168
+ - 1-2 hours
169
+ - Pre-heat tank before event
170
+ * - Emergency (Bit 4)
171
+ - Critical
172
+ - Minutes to hours
173
+ - Immediate halt/shutdown
174
+
175
+ **Example DR Event Sequence**:
176
+
177
+ .. code-block:: text
178
+
179
+ Time Event drEventStatus Device Action
180
+ ---- ----- -------------- ----------------
181
+ 2:00 PM Grid operator predicts peak (Normal operation)
182
+ 2:30 PM Pre-charge signal issued 0b00001000 Start heating now
183
+ 3:00 PM Peak period begins 0b00000010 Stop heating, reduce
184
+ 3:30 PM Peak continues 0b00000010 Heat pump only (low power)
185
+ 4:00 PM Peak period ends 0b00000001 Recover tank charge
186
+ 4:30 PM Normal operation restored 0b00000000 Resume standard schedule
187
+
188
+ DR Override Status Field
189
+ ^^^^^^^^^^^^^^^^^^^^^^^^
190
+
191
+ **Field**: ``drOverrideStatus`` (integer flag)
192
+
193
+ **Purpose**: Tracks user-initiated overrides of demand response commands
194
+
195
+ **Values**:
196
+ - ``0``: No override active, device responding to DR commands
197
+ - Non-zero: Override active for specified period (typically up to 72 hours)
198
+
199
+ **User Override Scenario**:
200
+
201
+ 1. Grid issues "shed" command (stop all heating)
202
+ 2. Device would halt heating for 1 hour
203
+ 3. User needs hot water for emergency task
204
+ 4. User presses "Override" in mobile app
205
+ 5. Device allows heating for next 30 minutes (or configured duration)
206
+ 6. ``drOverrideStatus`` set to non-zero, indicating override active
207
+ 7. After override period expires, device returns to DR command compliance
208
+
209
+ Implementation in Device Firmware
210
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
211
+
212
+ **Decision Tree** (inferred from status fields):
213
+
214
+ .. code-block:: text
215
+
216
+ IF drOverrideStatus != 0:
217
+ Allow all heating operations
218
+ Decrement override timer
219
+ ELSE IF drEventStatus != 0:
220
+ Determine signal type from drEventStatus bits
221
+ Apply corresponding power reduction
222
+ Adjust setpoints or compressor behavior
223
+ ELSE:
224
+ Execute normal reservation/TOU/mode schedule
225
+
226
+ **Practical Grid Integration Benefits**:
227
+
228
+ 1. **Peak Shaving**: Reduce demand during 3-7 PM peak periods, saving 20-30% during those hours
229
+ 2. **Rate Optimization**: Auto-respond to time-of-use pricing signals
230
+ 3. **Grid Stability**: Participate in demand response events, earn utility incentives
231
+ 4. **Cost Reduction**: Shift heating to low-price periods automatically
232
+
233
+ Utility Integration Requirements
234
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
235
+
236
+ To use demand response with your NWP500:
237
+
238
+
239
+ Tank Temperature Sensors
240
+ ^^^^^^^^^^^^^^^^^^^^^^^^
241
+
242
+ **Upper Tank Sensor** (``tankUpperTemperature``)
243
+
244
+ - **Location**: Near tank top, typically 12-18" below top
245
+ - **Measurement**: ``decicelsius_to_f`` conversion (tenths of Celsius to Fahrenheit)
246
+ - **Typical Range**: 110-160°F (43-71°C)
247
+ - **Purpose**: Indicates hot water availability for immediate draw
248
+ - **Control Target**: Used to trigger upper electric heating element and upper heat pump stage
249
+
250
+ **Lower Tank Sensor** (``tankLowerTemperature``)
251
+
252
+ - **Location**: Near tank bottom, typically 6-12" above lowest point
253
+ - **Measurement**: ``decicelsius_to_f`` conversion (tenths of Celsius to Fahrenheit)
254
+ - **Typical Range**: 95-155°F (35-68°C)
255
+ - **Purpose**: Monitors bulk tank heating progress
256
+ - **Control Target**: Used to trigger lower electric heating element and lower heat pump stage
257
+
258
+ Tank Stratification Explained
259
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
260
+
261
+ **What Is Stratification?**
262
+
263
+ In a vertical tank, naturally occurring density differences create layers:
264
+
265
+ .. code-block:: text
266
+
267
+ 155°F (68°C) ┌─────────────┐ ← Upper sensor (HOT)
268
+ │ Hot zone │
269
+ │ (stratif) │ Recently heated water
270
+ 120°F (49°C) ├─────────────┤ ← Dividing line (thermocline)
271
+ │ Warm zone │ Transitional temperature
272
+ │ │
273
+ 95°F (35°C) ├─────────────┤ ← Lower sensor (COOL)
274
+ │ Cool zone │ Being heated by compressor
275
+ └─────────────┘
276
+
277
+ **Why Stratification Matters**:
278
+
279
+ 1. **Efficiency Benefit**: Thermostat setpoints work on upper sensor only until recovery needed
280
+ 2. **Recovery Speed**: Lower element heating doesn't start until really needed (stratification maintained)
281
+ 3. **Cost Savings**: Avoids unnecessary full-tank heating; only heats lower section when depleted
282
+ 4. **User Comfort**: Upper zone always available at target temperature for draw
283
+
284
+ Practical Stratification Scenarios
285
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
286
+
287
+ **Scenario 1: Excellent Stratification (Efficient)**
288
+
289
+ .. code-block:: text
290
+
291
+ Time Upper Temp Lower Temp Differential Status
292
+ ---- ---------- ---------- ----------- --------
293
+ 9:00 AM 140°F 110°F 30°F Good stratification
294
+ 9:15 AM 138°F 110°F 28°F Still good (light draw)
295
+ 10:00 AM 140°F 112°F 28°F Heat pump maintains lower
296
+
297
+ → Device operates efficiently: upper element/HP just maintains top, lower recovers slowly
298
+ → User gets hot water from top layer without full-tank heating
299
+
300
+ **Scenario 2: Poor Stratification (Inefficient)**
301
+
302
+ .. code-block:: text
303
+
304
+ Time Upper Temp Lower Temp Differential Status
305
+ ---- ---------- ---------- ----------- --------
306
+ 3:00 PM 100°F 98°F 2°F Bad stratification
307
+ 3:30 PM 102°F 100°F 2°F Tank too uniform
308
+ 4:00 PM 95°F 94°F 1°F Almost no difference
309
+
310
+ → Device detects poor stratification
311
+ → Triggers full tank heating (both elements active)
312
+ → Inefficient: heats entire volume instead of targeted zones
313
+ → Recovery slower due to element capacity
314
+
315
+ **Scenario 3: Failed Sensor or Mixing Issue**
316
+
317
+ .. code-block:: text
318
+
319
+ Time Upper Temp Lower Temp Differential Status
320
+ ---- ---------- ---------- ----------- --------
321
+ 10:00 AM 155°F 160°F -5°F ERROR: Lower hotter than upper!
322
+
323
+ → Impossible condition: lower can't be hotter than upper
324
+ → Indicates failed sensor or severe mixing/circulation issue
325
+ → Device may alert or switch to safety mode
326
+
327
+ Device Control Strategy Based on Stratification
328
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
329
+
330
+ **Two-Stage Heating with Stratification**:
331
+
332
+ .. list-table::
333
+ :header-rows: 1
334
+ :widths: 15 20 20 45
335
+
336
+ * - Condition
337
+ - Upper Element
338
+ - Lower Element
339
+ - Device Action
340
+ * - Upper <110°F, Lower <90°F
341
+ - OFF
342
+ - ON (primary)
343
+ - Heat entire tank from bottom; creates stratification
344
+ * - Upper 110-130°F, Lower <90°F
345
+ - OFF
346
+ - ON
347
+ - Maintain stratification: let upper stay ready, heat lower
348
+ * - Upper >130°F, Lower >120°F
349
+ - OFF
350
+ - OFF
351
+ - Both satisfied, coast on heat retention
352
+ * - Upper <100°F, Lower >120°F
353
+ - ON (priority)
354
+ - OFF
355
+ - Restore top zone quickly (likely hot water draw)
356
+ * - Upper ~Upper set, Lower <100°F
357
+ - ON
358
+ - ON
359
+ - Full recovery needed; both elements heating
360
+
361
+ **Stratification Efficiency Gains**:
362
+
363
+ - **Upper heating only**: 15-25% less energy vs. full tank heating
364
+ - **Lower heating only**: 20-30% longer recovery time but 40-60% lower cost per cycle
365
+ - **Optimal**: ~25-30°F differential maximizes recovery time vs. efficiency tradeoff
366
+
367
+ Heat Pump Integration with Stratification
368
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
369
+
370
+ The two-stage control extends to heat pump operation:
371
+
372
+ - **Upper Heat Pump**: Activates when upper sensor drops below setpoint (quick, efficient recovery)
373
+ - **Lower Heat Pump**: Activates when lower sensor needs charging (low COP but maintains heating)
374
+
375
+ Modern control systems may use "superheat modulation" where:
376
+
377
+ - Heat pump adjusts compressor speed based on stratification degree
378
+ - Tighter superheat (more efficient) when stratification good
379
+ - Looser superheat (safer operation) when stratification poor
380
+
381
+ Monitoring Stratification from Python
382
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
383
+
384
+ .. code-block:: python
385
+
386
+ from nwp500.mqtt_client import NavienMQTTClient
387
+ from nwp500.models import DeviceStatus
388
+
389
+ async def monitor_stratification(mqtt_client: NavienMQTTClient, device_id: str):
390
+ """Monitor tank stratification quality"""
391
+
392
+ status = await mqtt_client.get_status(device_id)
393
+
394
+ upper_temp = status.tank_upper_temperature # float in °F
395
+ lower_temp = status.tank_lower_temperature # float in °F
396
+
397
+ stratification_delta = upper_temp - lower_temp
398
+
399
+ if stratification_delta < 5:
400
+ print(f"WARNING: Poor stratification (Δ={stratification_delta}°F)")
401
+ print(" → Full tank heating required")
402
+ print(" → Efficiency reduced, recovery slower")
403
+ elif stratification_delta > 25:
404
+ print(f"GOOD: Excellent stratification (Δ={stratification_delta}°F)")
405
+ print(" → Efficient targeted heating")
406
+ print(" → Quick hot water availability")
407
+ else:
408
+ print(f"INFO: Normal stratification (Δ={stratification_delta}°F)")
409
+ print(" → Balanced efficiency and recovery")
410
+
411
+ return {
412
+ 'upper_temp': upper_temp,
413
+ 'lower_temp': lower_temp,
414
+ 'stratification_delta': stratification_delta,
415
+ 'quality': 'excellent' if stratification_delta > 25 else 'poor' if stratification_delta < 5 else 'normal'
416
+ }
417
+
418
+ Factors Affecting Stratification
419
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
420
+
421
+ **Positive Factors** (Preserve Stratification):
422
+
423
+ 1. **Tank Insulation Quality**: Well-insulated tanks maintain temperature differences longer
424
+ 2. **Slow Heating**: Gentle heating from bottom maintains distinct layers
425
+ 3. **Low Draw Velocity**: Slow water draws don't turbulently mix layers
426
+ 4. **Minimal Circulation**: Recirculation pumps can destroy stratification if running
427
+ 5. **Vertical Tank Orientation**: Tall narrow tanks maintain stratification better than squat tanks
428
+
429
+ **Negative Factors** (Degrade Stratification):
430
+ - Morning peak hour starting (6-7 AM)
431
+ - Reservation calls for 140°F
432
+
433
+ Device Decision:
434
+ 1. Weather-responsive: 25°F ambient → COP low, expect user needs
435
+ 2. Tank stratification: Delta only 5°F → full-tank heating needed
436
+ 3. Demand response: Reduce signal → lower compressor priority
437
+
438
+ Action Taken:
439
+ - Electric lower element activated (ignores DR, local override)
440
+ - Heat pump compressor disabled (responds to DR reduce signal)
441
+ - Target: Warm tank from bottom, allow sufficient top recovery
442
+ - Result: 140°F achieved in 45 min (slower due to DR, but cold ambient expected)
443
+
444
+ Formula Confirmation
445
+ ====================
446
+
447
+ **Formula**:
448
+
449
+ The temperature conversion formula is:
450
+
451
+ .. code-block:: text
452
+
453
+ Formula: displayed_value = raw_value + 20
454
+
455
+ Application Evidence:
456
+ - Application handled by NaviLink
457
+ - Implementation in device status messages
458
+ - Fields: dhwTemperature, tankUpperTemperature, tankLowerTemperature, etc.
459
+ - Conversion: Applied uniformly to all add_20 type fields in device status
460
+ - Raw value range: 0-130 (representing -4°F to 150°F)
461
+ - Display range: 20-150°F
462
+
463
+ **Related Documentation**:
464
+
465
+ See :doc:`../protocol/data_conversions` for complete field conversion reference and formula applications.
466
+
467
+ Summary and Recommendations
468
+ ============================
469
+
470
+ **Weather-Responsive Heating**:
471
+ - Automatically adapts heat pump efficiency based on ambient conditions
472
+ - Enables pre-charging for predictable demand peaks
473
+ - Monitors ambient via ``outsideTemperature`` field in device status
474
+ - Integrate ambient data into recovery time predictions
475
+
476
+ **Demand Response Integration**:
477
+ - Enables grid-aware operation and potential utility incentive payments
478
+ - Monitor ``drEventStatus`` and ``drOverrideStatus`` fields
479
+ - User can override DR events temporarily (up to 72 hours typical)
480
+ - Integrate DR status into user notifications and UI displays
481
+
482
+ **Tank Stratification Optimization**:
483
+ - Dual sensors enable smart two-stage heating
484
+ - Monitor stratification delta (upper - lower) for efficiency insights
485
+ - Target 20-30°F delta for optimal efficiency
486
+ - Alert users when stratification poor (indicates maintenance need)
487
+ - Use stratification data for predictive recovery time estimation
488
+
489
+ See Also
490
+ --------
491
+
492
+ * :doc:`../protocol/data_conversions` - Temperature field conversions (add_20, decicelsius_to_f)
493
+ * :doc:`../protocol/device_status` - Complete device status field reference
494
+ * :doc:`scheduling_features` - Reservation and TOU integration points
495
+ * :doc:`../python_api/models` - DeviceStatus model field definitions