nwp500-python 7.2.3__tar.gz → 7.3.1__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.
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/CHANGELOG.rst +206 -114
- {nwp500_python-7.2.3/src/nwp500_python.egg-info → nwp500_python-7.3.1}/PKG-INFO +1 -1
- nwp500_python-7.3.1/docs/guides/home_assistant_integration.rst +371 -0
- nwp500_python-7.3.1/docs/guides/unit_conversion.rst +663 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/index.rst +8 -6
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/protocol/device_status.rst +20 -20
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/__init__.py +9 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/api_client.py +15 -4
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/auth.py +23 -10
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/cli/__main__.py +27 -3
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/cli/handlers.py +3 -2
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/cli/output_formatters.py +49 -14
- nwp500_python-7.3.1/src/nwp500/converters.py +481 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/encoding.py +3 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/events.py +3 -2
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/field_factory.py +27 -9
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/models.py +252 -115
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt/client.py +24 -9
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt/connection.py +23 -9
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt/subscriptions.py +12 -2
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt/utils.py +2 -1
- nwp500_python-7.3.1/src/nwp500/temperature.py +373 -0
- nwp500_python-7.3.1/src/nwp500/unit_system.py +128 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1/src/nwp500_python.egg-info}/PKG-INFO +1 -1
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500_python.egg-info/SOURCES.txt +4 -0
- nwp500_python-7.3.1/tests/conftest.py +118 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_mqtt_client_init.py +41 -37
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_temperature_converters.py +24 -0
- nwp500_python-7.3.1/tests/test_unit_switching.py +609 -0
- nwp500_python-7.2.3/src/nwp500/converters.py +0 -165
- nwp500_python-7.2.3/src/nwp500/temperature.py +0 -187
- nwp500_python-7.2.3/tests/conftest.py +0 -10
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/.agent/workflows/pre-completion-testing.md +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/.coveragerc +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/.github/copilot-instructions.md +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/.github/workflows/ci.yml +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/.github/workflows/release.yml +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/.gitignore +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/.pre-commit-config.yaml +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/.readthedocs.yml +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/AUTHORS.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/CONTRIBUTING.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/LICENSE.txt +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/Makefile +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/README.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/RELEASE.md +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/Makefile +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/_static/.gitignore +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/api/nwp500.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/authors.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/changelog.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/conf.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/configuration.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/development/contributing.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/development/history.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/enumerations.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/guides/advanced_features_explained.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/guides/authentication.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/guides/auto_recovery.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/guides/command_queue.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/guides/energy_monitoring.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/guides/event_system.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/guides/mqtt_diagnostics.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/guides/reservations.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/guides/scheduling_features.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/guides/time_of_use.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/installation.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/license.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/openapi.yaml +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/protocol/data_conversions.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/protocol/device_features.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/protocol/error_codes.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/protocol/mqtt_protocol.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/protocol/quick_reference.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/protocol/rest_api.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/python_api/api_client.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/python_api/auth_client.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/python_api/cli.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/python_api/device_control.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/python_api/events.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/python_api/exceptions.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/python_api/models.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/python_api/mqtt_client.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/quickstart.rst +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/docs/requirements.txt +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/.ruff.toml +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/README.md +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/air_filter_reset.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/anti_legionella.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/auto_recovery.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/combined_callbacks.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/demand_response.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/device_capabilities.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/device_status_debug.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/energy_analytics.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/error_code_demo.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/mqtt_diagnostics.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/power_control.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/recirculation_control.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/reconnection_demo.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/reservation_schedule.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/simple_auto_recovery.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/token_restoration.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/tou_openei.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/tou_schedule.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/advanced/water_reservation.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/beginner/01_authentication.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/beginner/02_list_devices.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/beginner/03_get_status.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/beginner/04_set_temperature.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/advanced_auth_patterns.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/command_queue.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/device_status_callback.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/error_handling.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/event_driven_control.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/improved_auth.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/legacy_auth_constructor.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/mqtt_realtime_monitoring.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/periodic_requests.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/set_mode.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/intermediate/vacation_mode.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/mask.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/testing/periodic_device_info.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/testing/simple_periodic_info.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/testing/test_api_client.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/testing/test_mqtt_connection.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/testing/test_mqtt_messaging.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/examples/testing/test_periodic_minimal.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/pyproject.toml +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/scripts/README.md +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/scripts/bump_version.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/scripts/diagnose_mqtt_connection.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/scripts/extract_changelog.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/scripts/format.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/scripts/lint.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/scripts/setup-dev.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/scripts/validate_version.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/setup.cfg +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/setup.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/cli/__init__.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/cli/commands.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/cli/monitoring.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/cli/rich_output.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/cli/token_storage.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/command_decorators.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/config.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/device_capabilities.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/device_info_cache.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/enums.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/exceptions.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/factory.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt/__init__.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt/command_queue.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt/control.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt/diagnostics.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt/periodic.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt/reconnection.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/mqtt_events.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/py.typed +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/topic_builder.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500/utils.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500_python.egg-info/dependency_links.txt +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500_python.egg-info/entry_points.txt +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500_python.egg-info/not-zip-safe +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500_python.egg-info/requires.txt +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/src/nwp500_python.egg-info/top_level.txt +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_api_helpers.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_auth.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_cli_basic.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_cli_commands.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_command_decorators.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_command_queue.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_device_capabilities.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_device_info_cache.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_events.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_exceptions.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_model_converters.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_models.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tests/test_utils.py +0 -0
- {nwp500_python-7.2.3 → nwp500_python-7.3.1}/tox.ini +0 -0
|
@@ -2,21 +2,113 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
Version 7.3.1 (2026-01-25)
|
|
6
|
+
==========================
|
|
7
|
+
|
|
8
|
+
Fixed
|
|
9
|
+
-----
|
|
10
|
+
- **MQTT Client Initialization**: Removed overly strict token validity check from ``NavienMqttClient.__init__()``
|
|
11
|
+
|
|
12
|
+
- The strict token validity check prevented creating MQTT clients with restored tokens that may have expired between application restarts
|
|
13
|
+
- However, ``NavienMqttClient.connect()`` already handles token refresh automatically, making the check redundant
|
|
14
|
+
- This change allows integrations to create MQTT clients with expired tokens and let connect() handle validation
|
|
15
|
+
- Simplifies application code by removing duplicate token refresh calls
|
|
16
|
+
- Enables proper handling of restored authentication sessions
|
|
17
|
+
- Fixes MQTT connection failures when using stored tokens across application restarts
|
|
18
|
+
|
|
19
|
+
Version 7.3.0 (2026-01-19)
|
|
20
|
+
==========================
|
|
21
|
+
|
|
22
|
+
Added
|
|
23
|
+
-----
|
|
24
|
+
- **Dynamic Unit Conversion**: All temperature, flow, and volume measurements now dynamically convert based on user's region preference (Metric/Imperial)
|
|
25
|
+
|
|
26
|
+
- Temperature fields convert between Celsius and Fahrenheit using standard formulas
|
|
27
|
+
- Flow rate fields convert between LPM (Liters Per Minute) and GPM (Gallons Per Minute)
|
|
28
|
+
- Volume fields convert between Liters and Gallons
|
|
29
|
+
- Available devices and regions determine conversion support (validated at runtime)
|
|
30
|
+
- ``get_field_unit()`` method retrieves the correct unit suffix for any field
|
|
31
|
+
- All conversions use Pydantic ``WrapValidator`` for transparent, automatic conversion
|
|
32
|
+
- Comprehensive documentation in ``docs/guides/unit_conversion.rst``
|
|
33
|
+
- Example usage:
|
|
34
|
+
|
|
35
|
+
.. code-block:: python
|
|
36
|
+
|
|
37
|
+
# Get converted value with unit
|
|
38
|
+
temp_f = device_status.flow_rate_target # Returns Fahrenheit if region prefers imperial
|
|
39
|
+
unit = device_status.get_field_unit("flow_rate_target") # Returns "°F" or "°C"
|
|
40
|
+
|
|
41
|
+
# All conversions are transparent - values automatically convert to preferred units
|
|
42
|
+
flow_gpm = device_status.flow_rate_current # GPM if imperial, LPM if metric
|
|
43
|
+
volume_gal = device_status.tank_volume # Gallons if imperial, Liters if metric
|
|
44
|
+
|
|
45
|
+
- Supported conversion fields:
|
|
46
|
+
|
|
47
|
+
- **Temperature**: ``flow_rate_target``, ``flow_rate_current``, ``in_water_temp``, ``out_water_temp``, ``set_temp``, ``in_temp``, ``out_temp``, etc.
|
|
48
|
+
- **Flow Rate**: ``flow_rate_target``, ``flow_rate_current``
|
|
49
|
+
- **Volume**: ``tank_volume`` and related storage fields
|
|
50
|
+
|
|
51
|
+
- Integration patterns for Home Assistant, CLI, and custom integrations documented
|
|
52
|
+
|
|
53
|
+
- **Unit System Override**: Allow applications and CLI users to override the device's temperature preference and explicitly specify Metric or Imperial units
|
|
54
|
+
|
|
55
|
+
- Library-level: Add optional ``unit_system`` parameter to ``NavienAuthClient``, ``NavienMqttClient``, and ``NavienAPIClient`` initialization
|
|
56
|
+
- Set once at initialization; applies to all subsequent data conversions
|
|
57
|
+
- Accepts: ``"metric"`` (Celsius/LPM/Liters), ``"imperial"`` (Fahrenheit/GPM/Gallons), or ``None`` (auto-detect from device)
|
|
58
|
+
- Decouples unit preference from device configuration - users can override what the device is set to
|
|
59
|
+
- Uses context variables for thread-safe and async-safe unit system management
|
|
60
|
+
- Example usage:
|
|
61
|
+
|
|
62
|
+
.. code-block:: python
|
|
63
|
+
|
|
64
|
+
# Library initialization
|
|
65
|
+
from nwp500 import NavienAuthClient, set_unit_system
|
|
66
|
+
auth = NavienAuthClient(email, password, unit_system="metric")
|
|
67
|
+
|
|
68
|
+
# Or set after initialization
|
|
69
|
+
set_unit_system("imperial")
|
|
70
|
+
device_status = await mqtt.request_device_status(device)
|
|
71
|
+
# Values now in F, GPM, gallons regardless of device setting
|
|
72
|
+
|
|
73
|
+
- CLI-level: Add ``--unit-system`` flag for per-command override
|
|
74
|
+
- Example: ``nwp-cli status --unit-system metric``
|
|
75
|
+
- Defaults to device's setting if not specified
|
|
76
|
+
- New exported functions:
|
|
77
|
+
- ``set_unit_system(unit_system)`` - Set the preferred unit system
|
|
78
|
+
- ``get_unit_system()`` - Get the current unit system preference
|
|
79
|
+
- ``reset_unit_system()`` - Reset to auto-detect mode
|
|
80
|
+
|
|
81
|
+
Fixed
|
|
82
|
+
-----
|
|
83
|
+
- **MQTT Unit System Override Bug**: Fixed unit_system CLI flag not applying to device status values
|
|
84
|
+
|
|
85
|
+
- **Issue**: Running ``nwp-cli --unit-system metric status`` displayed values in device's native format (imperial) with metric unit strings (e.g., "104.9 °C" instead of "40.5 °C")
|
|
86
|
+
- **Root Cause**: MQTT callbacks from AWS CRT execute on different threads where context variables are not set. Since Python's context variables are task-local, the unit_system preference was not visible to validators
|
|
87
|
+
- **Solution**: Store unit_system in ``NavienMqttClient`` and ``MqttSubscriptionManager``. Before parsing MQTT messages, explicitly set the context variable in message handlers to ensure validators use the correct unit system regardless of thread context
|
|
88
|
+
- **Result**: Values and units now correctly convert when ``--unit-system`` override is specified
|
|
89
|
+
- **Testing**: All 393 tests pass including new unit system context override tests
|
|
90
|
+
|
|
91
|
+
- **Type Annotation Quotes**: Removed unnecessary quoted type annotations (UP037 violations)
|
|
92
|
+
|
|
93
|
+
- With ``from __future__ import annotations``, explicit string quotes are redundant
|
|
94
|
+
- Updated ``from_dict()`` methods in ``UserInfo``, ``AuthTokens``, ``AuthenticationResponse``, ``DeviceStatus``, ``DeviceFeature``, and ``EnergyUsageResponse``
|
|
95
|
+
- Improves code clarity and passes modern linting standards
|
|
96
|
+
|
|
5
97
|
Version 7.2.3 (2026-01-15)
|
|
6
98
|
==========================
|
|
7
99
|
|
|
8
100
|
Added
|
|
9
101
|
-----
|
|
10
102
|
- **Daily Energy Breakdown by Month**: New ``--month`` option for energy command to show daily energy data for a specific month
|
|
11
|
-
|
|
103
|
+
|
|
12
104
|
.. code-block:: bash
|
|
13
|
-
|
|
105
|
+
|
|
14
106
|
# Daily breakdown for a single month
|
|
15
107
|
nwp-cli energy --year 2025 --month 12
|
|
16
|
-
|
|
108
|
+
|
|
17
109
|
# Monthly summary for multiple months (existing)
|
|
18
110
|
nwp-cli energy --year 2025 --months 10,11,12
|
|
19
|
-
|
|
111
|
+
|
|
20
112
|
- Displays daily energy consumption, efficiency, and heat source breakdown
|
|
21
113
|
- Rich formatted output with progress bars and color-coded efficiency percentages
|
|
22
114
|
- Plain text fallback for non-Rich environments
|
|
@@ -25,25 +117,25 @@ Added
|
|
|
25
117
|
Fixed
|
|
26
118
|
-----
|
|
27
119
|
- **Documentation**: Fixed all warnings and broken cross-references in documentation
|
|
28
|
-
|
|
120
|
+
|
|
29
121
|
- Fixed docstring formatting in field_factory.py module
|
|
30
122
|
- Fixed broken cross-reference links in enumerations.rst, mqtt_diagnostics.rst, cli.rst, and models.rst
|
|
31
123
|
- Fixed invalid JSON syntax in code examples (removed invalid [...] and ... tokens)
|
|
32
124
|
- Suppressed duplicate object description warnings from re-exported classes
|
|
33
|
-
|
|
125
|
+
|
|
34
126
|
- **CLI Documentation**: Updated documentation for all 19 CLI commands
|
|
35
|
-
|
|
127
|
+
|
|
36
128
|
- Added missing device-info command documentation
|
|
37
129
|
- Added --raw flag documentation for status, info, and device-info commands
|
|
38
130
|
- Added --month option documentation to energy command
|
|
39
131
|
- Clarified mutually exclusive options (--months vs --month)
|
|
40
|
-
|
|
132
|
+
|
|
41
133
|
- **RST Title Hierarchy**: Fixed title level inconsistencies in device_control.rst
|
|
42
134
|
|
|
43
135
|
- **Read the Docs Configuration**: Updated Python version requirement to 3.13 in Read the Docs config
|
|
44
136
|
|
|
45
137
|
- **CI Test Failures**: Fixed ``ModuleNotFoundError`` when running tests without CLI dependencies installed
|
|
46
|
-
|
|
138
|
+
|
|
47
139
|
- Wrapped CLI module imports in try-except blocks in test modules
|
|
48
140
|
- Tests are skipped gracefully when optional dependencies (click, rich) are not installed
|
|
49
141
|
- Allows pytest to run without CLI extra, while supporting full test suite with tox
|
|
@@ -59,7 +151,7 @@ Version 7.2.2 (2025-12-25)
|
|
|
59
151
|
Fixed
|
|
60
152
|
-----
|
|
61
153
|
- **TOU Status Always Showing False**: Fixed ``touStatus`` field always reporting ``False`` regardless of actual device state
|
|
62
|
-
|
|
154
|
+
|
|
63
155
|
- Root cause: Version 7.2.1 incorrectly changed ``touStatus`` to use device-specific 1/2 encoding, but the device uses standard 0/1 encoding
|
|
64
156
|
- Solution: Use Python's built-in ``bool()`` for ``touStatus`` field (handles 0=False, 1=True naturally)
|
|
65
157
|
- Updated documentation in ``docs/protocol/quick_reference.rst`` to note ``touStatus`` exception
|
|
@@ -72,21 +164,21 @@ Version 7.2.1 (2025-12-25)
|
|
|
72
164
|
Added
|
|
73
165
|
-----
|
|
74
166
|
- **CLI Command**: New ``device-info`` command to retrieve basic device information from REST API
|
|
75
|
-
|
|
167
|
+
|
|
76
168
|
.. code-block:: bash
|
|
77
|
-
|
|
169
|
+
|
|
78
170
|
# Get basic device info (DeviceInfo model)
|
|
79
171
|
python3 -m nwp500.cli device-info
|
|
80
172
|
python3 -m nwp500.cli device-info --raw
|
|
81
173
|
|
|
82
174
|
- **ConnectionStatus Enum**: New ``ConnectionStatus`` enum for device cloud connection state
|
|
83
|
-
|
|
175
|
+
|
|
84
176
|
- ``ConnectionStatus.DISCONNECTED`` = 1 - Device offline/not connected
|
|
85
177
|
- ``ConnectionStatus.CONNECTED`` = 2 - Device online and reachable
|
|
86
178
|
- Used in ``DeviceInfo.connected`` field with automatic validation
|
|
87
179
|
|
|
88
180
|
- **InstallType Enum**: New ``InstallType`` enum for device installation classification
|
|
89
|
-
|
|
181
|
+
|
|
90
182
|
- ``InstallType.RESIDENTIAL`` = "R" - Residential use
|
|
91
183
|
- ``InstallType.COMMERCIAL`` = "C" - Commercial use
|
|
92
184
|
- Used in ``DeviceInfo.install_type`` field with automatic validation
|
|
@@ -96,7 +188,7 @@ Added
|
|
|
96
188
|
|
|
97
189
|
Changed
|
|
98
190
|
-------
|
|
99
|
-
- **DeviceInfo Model**:
|
|
191
|
+
- **DeviceInfo Model**:
|
|
100
192
|
- ``connected`` field now uses ``ConnectionStatus`` enum instead of plain int
|
|
101
193
|
- ``install_type`` field now uses ``InstallType`` enum instead of plain string
|
|
102
194
|
|
|
@@ -112,12 +204,12 @@ Changed
|
|
|
112
204
|
Removed
|
|
113
205
|
-------
|
|
114
206
|
- **constants.py Module**: Removed empty ``constants.py`` module. ``CommandCode`` enum was already moved to ``enums.py`` in version 4.2.0.
|
|
115
|
-
|
|
207
|
+
|
|
116
208
|
.. code-block:: python
|
|
117
|
-
|
|
209
|
+
|
|
118
210
|
# OLD (removed)
|
|
119
211
|
from nwp500.constants import CommandCode
|
|
120
|
-
|
|
212
|
+
|
|
121
213
|
# NEW (use this)
|
|
122
214
|
from nwp500.enums import CommandCode
|
|
123
215
|
|
|
@@ -140,20 +232,20 @@ Removed
|
|
|
140
232
|
|
|
141
233
|
# OLD (removed)
|
|
142
234
|
from nwp500 import DeviceCapabilityChecker, DeviceInfoCache
|
|
143
|
-
|
|
235
|
+
|
|
144
236
|
# NEW
|
|
145
237
|
from nwp500 import MqttDeviceCapabilityChecker, MqttDeviceInfoCache
|
|
146
238
|
|
|
147
|
-
**Rationale**: The original names were too generic. These classes are specifically designed
|
|
148
|
-
for MQTT client functionality (auto-fetching device info, caching, capability checking).
|
|
149
|
-
The new names make it clear they're MQTT-specific implementations, leaving room for future
|
|
239
|
+
**Rationale**: The original names were too generic. These classes are specifically designed
|
|
240
|
+
for MQTT client functionality (auto-fetching device info, caching, capability checking).
|
|
241
|
+
The new names make it clear they're MQTT-specific implementations, leaving room for future
|
|
150
242
|
REST API versions if needed.
|
|
151
243
|
|
|
152
244
|
**Migration**: Simple find-and-replace:
|
|
153
|
-
|
|
245
|
+
|
|
154
246
|
- ``DeviceCapabilityChecker`` → ``MqttDeviceCapabilityChecker``
|
|
155
247
|
- ``DeviceInfoCache`` → ``MqttDeviceInfoCache``
|
|
156
|
-
|
|
248
|
+
|
|
157
249
|
All functionality remains identical - only the class names changed.
|
|
158
250
|
|
|
159
251
|
Added
|
|
@@ -165,7 +257,7 @@ Added
|
|
|
165
257
|
|
|
166
258
|
# Create both API and MQTT clients in one call
|
|
167
259
|
from nwp500 import create_navien_clients
|
|
168
|
-
|
|
260
|
+
|
|
169
261
|
async with create_navien_clients(email, password) as (api_client, mqtt_client):
|
|
170
262
|
devices = await api_client.get_devices()
|
|
171
263
|
await mqtt_client.connect()
|
|
@@ -183,10 +275,10 @@ Added
|
|
|
183
275
|
.. code-block:: python
|
|
184
276
|
|
|
185
277
|
from nwp500 import VolumeCode
|
|
186
|
-
|
|
278
|
+
|
|
187
279
|
# Enum values: VOLUME_50GAL = 65, VOLUME_65GAL = 66, VOLUME_80GAL = 67
|
|
188
280
|
# Human-readable text available in VOLUME_CODE_TEXT dict
|
|
189
|
-
|
|
281
|
+
|
|
190
282
|
- Maps device codes to actual tank capacities (50, 65, 80 gallons)
|
|
191
283
|
- Used in ``DeviceFeature.volume_code`` field with automatic validation
|
|
192
284
|
- Exported from main package for convenience
|
|
@@ -254,7 +346,7 @@ Changed
|
|
|
254
346
|
from nwp500.mqtt_client import NavienMqttClient
|
|
255
347
|
from nwp500.mqtt_diagnostics import MqttDiagnosticsCollector
|
|
256
348
|
from nwp500.mqtt_utils import MqttConnectionConfig
|
|
257
|
-
|
|
349
|
+
|
|
258
350
|
# NEW imports (preferred)
|
|
259
351
|
from nwp500.mqtt import NavienMqttClient, MqttDiagnosticsCollector, MqttConnectionConfig
|
|
260
352
|
# OR import from main package (recommended)
|
|
@@ -285,12 +377,12 @@ Changed
|
|
|
285
377
|
- Renamed and moved 35+ example scripts for better discoverability
|
|
286
378
|
- Updated ``examples/README.md`` with 'Getting Started' guide and categorized index
|
|
287
379
|
- Added 01-04 beginner series for smooth onboarding:
|
|
288
|
-
|
|
380
|
+
|
|
289
381
|
- ``beginner/01_authentication.py`` - Basic authentication patterns
|
|
290
382
|
- ``beginner/02_list_devices.py`` - Retrieving device information
|
|
291
383
|
- ``beginner/03_get_status.py`` - Getting device status
|
|
292
384
|
- ``beginner/04_set_temperature.py`` - Basic device control
|
|
293
|
-
|
|
385
|
+
|
|
294
386
|
- Intermediate examples: event-driven control, error handling, MQTT monitoring
|
|
295
387
|
- Advanced examples: demand response, recirculation, TOU schedules, diagnostics
|
|
296
388
|
- Testing examples: connection testing, periodic updates, minimal examples
|
|
@@ -427,18 +519,18 @@ Fixed
|
|
|
427
519
|
Version 7.0.0 (2025-12-17)
|
|
428
520
|
==========================
|
|
429
521
|
|
|
430
|
-
**BREAKING CHANGES**:
|
|
522
|
+
**BREAKING CHANGES**:
|
|
431
523
|
- Minimum Python version raised to 3.13
|
|
432
524
|
- Enumerations refactored for type safety and consistency
|
|
433
525
|
|
|
434
526
|
Removed
|
|
435
527
|
-------
|
|
436
528
|
- **Python 3.9-3.12 Support**: Minimum Python version is now 3.13
|
|
437
|
-
|
|
529
|
+
|
|
438
530
|
Home Assistant has deprecated Python 3.12 support, making Python 3.13 the de facto minimum for this ecosystem.
|
|
439
|
-
|
|
531
|
+
|
|
440
532
|
Python 3.13 features and improvements:
|
|
441
|
-
|
|
533
|
+
|
|
442
534
|
- **Experimental free-threaded mode** (PEP 703): Optional GIL removal for true parallelism
|
|
443
535
|
- **JIT compiler** (PEP 744): Just-in-time compilation for performance improvements
|
|
444
536
|
- **Better error messages**: Enhanced suggestions for NameError, AttributeError, and import errors
|
|
@@ -447,16 +539,16 @@ Removed
|
|
|
447
539
|
- PEP 695: New type parameter syntax for generics
|
|
448
540
|
- PEP 701: f-string improvements
|
|
449
541
|
- Built-in ``datetime.UTC`` constant
|
|
450
|
-
|
|
542
|
+
|
|
451
543
|
If you need Python 3.12 support, use version 6.1.x of this library.
|
|
452
544
|
|
|
453
545
|
- **CommandCode moved**: Import from ``nwp500.enums`` instead of ``nwp500.constants``
|
|
454
|
-
|
|
546
|
+
|
|
455
547
|
.. code-block:: python
|
|
456
|
-
|
|
548
|
+
|
|
457
549
|
# OLD (removed)
|
|
458
550
|
from nwp500.constants import CommandCode
|
|
459
|
-
|
|
551
|
+
|
|
460
552
|
# NEW
|
|
461
553
|
from nwp500.enums import CommandCode
|
|
462
554
|
# OR
|
|
@@ -466,14 +558,14 @@ Added
|
|
|
466
558
|
-----
|
|
467
559
|
|
|
468
560
|
- **Python 3.12+ Optimizations**: Leverage latest Python features
|
|
469
|
-
|
|
561
|
+
|
|
470
562
|
- PEP 695: New type parameter syntax (``def func[T](...)`` instead of ``TypeVar``)
|
|
471
563
|
- Use ``datetime.UTC`` constant instead of ``datetime.timezone.utc``
|
|
472
564
|
- Native union syntax (``X | Y`` instead of ``Union[X, Y]``)
|
|
473
565
|
- Cleaner generic type annotations throughout codebase
|
|
474
566
|
|
|
475
567
|
- **Enumerations Module (``src/nwp500/enums.py``)**: Comprehensive type-safe enums for device control and status
|
|
476
|
-
|
|
568
|
+
|
|
477
569
|
- Status value enums: ``OnOffFlag``, ``Operation``, ``DhwOperationSetting``, ``CurrentOperationMode``, ``HeatSource``, ``DREvent``, ``WaterLevel``, ``FilterChange``, ``RecirculationMode``
|
|
478
570
|
- Time of Use enums: ``TouWeekType``, ``TouRateType``
|
|
479
571
|
- Device capability enums: ``CapabilityFlag``, ``TemperatureType``, ``DeviceType``
|
|
@@ -488,7 +580,7 @@ Changed
|
|
|
488
580
|
-------
|
|
489
581
|
|
|
490
582
|
- **Command Code Constants**: Migrated from ``constants.py`` to ``CommandCode`` enum in ``enums.py``
|
|
491
|
-
|
|
583
|
+
|
|
492
584
|
- ``ANTI_LEGIONELLA_ENABLE`` → ``CommandCode.ANTI_LEGIONELLA_ON``
|
|
493
585
|
- ``ANTI_LEGIONELLA_DISABLE`` → ``CommandCode.ANTI_LEGIONELLA_OFF``
|
|
494
586
|
- ``TOU_ENABLE`` → ``CommandCode.TOU_ON``
|
|
@@ -497,19 +589,19 @@ Changed
|
|
|
497
589
|
- All command constants now use consistent naming in ``CommandCode`` enum
|
|
498
590
|
|
|
499
591
|
- **Model Enumerations**: Updated type annotations for clarity and type safety
|
|
500
|
-
|
|
592
|
+
|
|
501
593
|
- ``TemperatureUnit`` → ``TemperatureType`` (matches device protocol field names)
|
|
502
594
|
- All capability flags (e.g., ``power_use``, ``dhw_use``) now use ``CapabilityFlag`` type
|
|
503
595
|
- ``MqttRequest.device_type`` now accepts ``Union[DeviceType, int]`` for flexibility
|
|
504
596
|
|
|
505
597
|
- **Model Serialization**: Enums automatically serialize to human-readable names
|
|
506
|
-
|
|
598
|
+
|
|
507
599
|
- `model_dump()` converts enums to names (e.g., `DhwOperationSetting.HEAT_PUMP` → `"HEAT_PUMP"`)
|
|
508
600
|
- CLI and other consumers benefit from automatic enum name serialization
|
|
509
601
|
- Text mappings available for custom formatting (e.g., `DHW_OPERATION_TEXT[enum]` → "Heat Pump Only")
|
|
510
602
|
|
|
511
603
|
- **Documentation**: Comprehensive updates across protocol and API documentation
|
|
512
|
-
|
|
604
|
+
|
|
513
605
|
- ``docs/guides/time_of_use.rst``: Clarified TOU override status behavior (1=OFF/override active, 2=ON/normal operation)
|
|
514
606
|
- ``docs/protocol/data_conversions.rst``: Updated TOU field descriptions with correct enum values
|
|
515
607
|
- ``docs/protocol/device_features.rst``: Added capability flag pattern explanation (2=supported, 1=not supported)
|
|
@@ -517,14 +609,14 @@ Changed
|
|
|
517
609
|
- ``docs/python_api/models.rst``: Updated model field type annotations
|
|
518
610
|
|
|
519
611
|
- **Examples**: Updated to use new enums for type-safe device control
|
|
520
|
-
|
|
612
|
+
|
|
521
613
|
- ``examples/anti_legionella_example.py``: Uses ``CommandCode`` enum
|
|
522
614
|
- ``examples/device_feature_callback.py``: Uses capability enums
|
|
523
615
|
- ``examples/event_emitter_demo.py``: Uses status enums
|
|
524
616
|
- ``examples/mqtt_diagnostics_example.py``: Uses command enums
|
|
525
617
|
|
|
526
618
|
- **CLI Code Cleanup**: Refactored JSON formatting to use shared utility function
|
|
527
|
-
|
|
619
|
+
|
|
528
620
|
- Extracted repeated `json.dumps()` calls to `format_json_output()` helper
|
|
529
621
|
- Cleaner code with consistent formatting across all commands
|
|
530
622
|
|
|
@@ -572,7 +664,7 @@ Changed
|
|
|
572
664
|
|
|
573
665
|
# OLD (removed)
|
|
574
666
|
build_reservation_entry(..., param=120)
|
|
575
|
-
|
|
667
|
+
|
|
576
668
|
# NEW
|
|
577
669
|
build_reservation_entry(..., temperature_f=140.0)
|
|
578
670
|
|
|
@@ -583,7 +675,7 @@ Changed
|
|
|
583
675
|
|
|
584
676
|
# OLD (removed)
|
|
585
677
|
await mqtt.set_dhw_temperature(device, 120)
|
|
586
|
-
|
|
678
|
+
|
|
587
679
|
# NEW
|
|
588
680
|
await mqtt.set_dhw_temperature(device, 140.0)
|
|
589
681
|
|
|
@@ -604,7 +696,7 @@ Added
|
|
|
604
696
|
.. code-block:: python
|
|
605
697
|
|
|
606
698
|
from nwp500 import fahrenheit_to_half_celsius
|
|
607
|
-
|
|
699
|
+
|
|
608
700
|
param = fahrenheit_to_half_celsius(140.0) # Returns 120
|
|
609
701
|
|
|
610
702
|
Fixed
|
|
@@ -644,7 +736,7 @@ Fixed
|
|
|
644
736
|
|
|
645
737
|
- **Example Code**: Fixed ``device_status_callback.py`` example to use snake_case attribute names consistently
|
|
646
738
|
- **Field Descriptions**: Clarified distinctions between similar fields:
|
|
647
|
-
|
|
739
|
+
|
|
648
740
|
- ``dhw_temperature_setting`` vs ``dhw_target_temperature_setting`` descriptions
|
|
649
741
|
- ``freeze_protection_temp`` descriptions differ between DeviceStatus and DeviceFeature
|
|
650
742
|
- ``eco_use`` descriptions differ between DeviceStatus (current state) and DeviceFeature (capability)
|
|
@@ -656,7 +748,7 @@ Fixed
|
|
|
656
748
|
-----
|
|
657
749
|
|
|
658
750
|
- **CRITICAL Temperature Conversion Bug**: Corrected temperature conversion formula for 8 sensor fields that were displaying values ~100°F higher than expected. The v6.0.4 change incorrectly used division by 5 (pentacelsius) instead of division by 10 (decicelsius) for these fields:
|
|
659
|
-
|
|
751
|
+
|
|
660
752
|
- ``tank_upper_temperature`` - Water tank upper sensor
|
|
661
753
|
- ``tank_lower_temperature`` - Water tank lower sensor
|
|
662
754
|
- ``discharge_temperature`` - Compressor discharge temperature (refrigerant)
|
|
@@ -665,13 +757,13 @@ Fixed
|
|
|
665
757
|
- ``ambient_temperature`` - Ambient air temperature at heat pump
|
|
666
758
|
- ``target_super_heat`` - Target superheat setpoint
|
|
667
759
|
- ``current_super_heat`` - Measured superheat value
|
|
668
|
-
|
|
760
|
+
|
|
669
761
|
**Impact**: These fields now correctly display temperatures in expected ranges:
|
|
670
|
-
|
|
762
|
+
|
|
671
763
|
- Tank temperatures: ~120°F (close to DHW temperature, not ~220°F)
|
|
672
764
|
- Discharge temperature: 120-180°F (not 220-280°F)
|
|
673
765
|
- Suction, evaporator, ambient: Now showing physically realistic values
|
|
674
|
-
|
|
766
|
+
|
|
675
767
|
**Technical details**: Changed from ``PentaCelsiusToF`` (÷5) back to ``DeciCelsiusToF`` (÷10). The correct formula is ``(raw_value / 10.0) * 9/5 + 32``.
|
|
676
768
|
|
|
677
769
|
Changed
|
|
@@ -686,7 +778,7 @@ Fixed
|
|
|
686
778
|
-----
|
|
687
779
|
|
|
688
780
|
- **Temperature Conversion Accuracy**: Corrected temperature conversion logic based on analysis of the decompiled mobile application. Previous conversions used approximations; new logic uses exact formulas from the app:
|
|
689
|
-
|
|
781
|
+
|
|
690
782
|
- Replaced ``Add20`` validator with ``HalfCelsiusToF`` for fields transmitted as half-degrees Celsius
|
|
691
783
|
- Replaced ``DeciCelsiusToF`` with ``PentaCelsiusToF`` for fields scaled by factor of 5
|
|
692
784
|
- Affects multiple temperature sensor readings for improved accuracy
|
|
@@ -818,32 +910,32 @@ Removed
|
|
|
818
910
|
-------
|
|
819
911
|
|
|
820
912
|
- **Constructor Callbacks**: Removed ``on_connection_interrupted`` and ``on_connection_resumed`` constructor parameters from ``NavienMqttClient``
|
|
821
|
-
|
|
913
|
+
|
|
822
914
|
.. code-block:: python
|
|
823
|
-
|
|
915
|
+
|
|
824
916
|
# OLD (removed in v6.0.0)
|
|
825
917
|
mqtt_client = NavienMqttClient(
|
|
826
918
|
auth_client,
|
|
827
919
|
on_connection_interrupted=on_interrupted,
|
|
828
920
|
on_connection_resumed=on_resumed,
|
|
829
921
|
)
|
|
830
|
-
|
|
922
|
+
|
|
831
923
|
# NEW (use event emitter pattern)
|
|
832
924
|
mqtt_client = NavienMqttClient(auth_client)
|
|
833
925
|
mqtt_client.on("connection_interrupted", on_interrupted)
|
|
834
926
|
mqtt_client.on("connection_resumed", on_resumed)
|
|
835
927
|
|
|
836
928
|
- **Backward Compatibility Re-exports**: Removed exception re-exports from ``api_client`` and ``auth`` modules
|
|
837
|
-
|
|
929
|
+
|
|
838
930
|
.. code-block:: python
|
|
839
|
-
|
|
931
|
+
|
|
840
932
|
# OLD (removed in v6.0.0)
|
|
841
933
|
from nwp500.api_client import APIError
|
|
842
934
|
from nwp500.auth import AuthenticationError, TokenRefreshError
|
|
843
|
-
|
|
935
|
+
|
|
844
936
|
# NEW (import from exceptions module)
|
|
845
937
|
from nwp500.exceptions import APIError, AuthenticationError, TokenRefreshError
|
|
846
|
-
|
|
938
|
+
|
|
847
939
|
# OR (import from package root - recommended)
|
|
848
940
|
from nwp500 import APIError, AuthenticationError, TokenRefreshError
|
|
849
941
|
|
|
@@ -854,7 +946,7 @@ Changed
|
|
|
854
946
|
-------
|
|
855
947
|
|
|
856
948
|
- **Migration Benefits**:
|
|
857
|
-
|
|
949
|
+
|
|
858
950
|
- Multiple listeners per event (not just one callback)
|
|
859
951
|
- Consistent API with other events (temperature_changed, mode_changed, etc.)
|
|
860
952
|
- Dynamic listener management (add/remove listeners at runtime)
|
|
@@ -877,7 +969,7 @@ Fixed
|
|
|
877
969
|
-----
|
|
878
970
|
|
|
879
971
|
- **MQTT Future Cancellation**: Fixed InvalidStateError exceptions during disconnect
|
|
880
|
-
|
|
972
|
+
|
|
881
973
|
- Added asyncio.shield() to protect concurrent.futures.Future objects from cancellation
|
|
882
974
|
- Applied consistent cancellation handling across all MQTT operations (connect, disconnect, subscribe, unsubscribe, publish)
|
|
883
975
|
- AWS CRT callbacks can now complete independently without raising InvalidStateError
|
|
@@ -905,7 +997,7 @@ Changed
|
|
|
905
997
|
Version 5.0.0 (2025-10-27)
|
|
906
998
|
==========================
|
|
907
999
|
|
|
908
|
-
**BREAKING CHANGES**: This release introduces a comprehensive enterprise exception architecture.
|
|
1000
|
+
**BREAKING CHANGES**: This release introduces a comprehensive enterprise exception architecture.
|
|
909
1001
|
See migration guide below for details on updating your code.
|
|
910
1002
|
|
|
911
1003
|
Added
|
|
@@ -915,10 +1007,10 @@ Added
|
|
|
915
1007
|
|
|
916
1008
|
- Created ``exceptions.py`` module with comprehensive exception hierarchy
|
|
917
1009
|
- Added ``Nwp500Error`` as base exception for all library errors
|
|
918
|
-
- Added MQTT-specific exceptions: ``MqttError``, ``MqttConnectionError``, ``MqttNotConnectedError``,
|
|
1010
|
+
- Added MQTT-specific exceptions: ``MqttError``, ``MqttConnectionError``, ``MqttNotConnectedError``,
|
|
919
1011
|
``MqttPublishError``, ``MqttSubscriptionError``, ``MqttCredentialsError``
|
|
920
1012
|
- Added validation exceptions: ``ValidationError``, ``ParameterValidationError``, ``RangeValidationError``
|
|
921
|
-
- Added device exceptions: ``DeviceError``, ``DeviceNotFoundError``, ``DeviceOfflineError``,
|
|
1013
|
+
- Added device exceptions: ``DeviceError``, ``DeviceNotFoundError``, ``DeviceOfflineError``,
|
|
922
1014
|
``DeviceOperationError``
|
|
923
1015
|
- All exceptions now include ``error_code``, ``details``, and ``retriable`` attributes
|
|
924
1016
|
- Added ``to_dict()`` method to all exceptions for structured logging
|
|
@@ -946,7 +1038,7 @@ Migration Guide (v4.x to v5.0)
|
|
|
946
1038
|
|
|
947
1039
|
**Breaking Changes Summary**:
|
|
948
1040
|
|
|
949
|
-
The library now uses specific exception types instead of generic ``RuntimeError`` and ``ValueError``.
|
|
1041
|
+
The library now uses specific exception types instead of generic ``RuntimeError`` and ``ValueError``.
|
|
950
1042
|
This improves error handling but requires updates to exception handling code.
|
|
951
1043
|
|
|
952
1044
|
**1. MQTT Connection Errors**
|
|
@@ -962,7 +1054,7 @@ This improves error handling but requires updates to exception handling code.
|
|
|
962
1054
|
|
|
963
1055
|
# NEW CODE (v5.0+)
|
|
964
1056
|
from nwp500 import MqttNotConnectedError, MqttError
|
|
965
|
-
|
|
1057
|
+
|
|
966
1058
|
try:
|
|
967
1059
|
await mqtt_client.request_device_status(device)
|
|
968
1060
|
except MqttNotConnectedError:
|
|
@@ -985,7 +1077,7 @@ This improves error handling but requires updates to exception handling code.
|
|
|
985
1077
|
|
|
986
1078
|
# NEW CODE (v5.0+)
|
|
987
1079
|
from nwp500 import RangeValidationError, ValidationError
|
|
988
|
-
|
|
1080
|
+
|
|
989
1081
|
try:
|
|
990
1082
|
set_vacation_mode(device, days=35)
|
|
991
1083
|
except RangeValidationError as e:
|
|
@@ -1009,7 +1101,7 @@ This improves error handling but requires updates to exception handling code.
|
|
|
1009
1101
|
|
|
1010
1102
|
# NEW CODE (v5.0+)
|
|
1011
1103
|
from nwp500 import MqttCredentialsError
|
|
1012
|
-
|
|
1104
|
+
|
|
1013
1105
|
try:
|
|
1014
1106
|
mqtt_client = NavienMqttClient(auth_client)
|
|
1015
1107
|
except MqttCredentialsError as e:
|
|
@@ -1023,14 +1115,14 @@ This improves error handling but requires updates to exception handling code.
|
|
|
1023
1115
|
|
|
1024
1116
|
# NEW CODE (v5.0+) - catch all library exceptions
|
|
1025
1117
|
from nwp500 import Nwp500Error
|
|
1026
|
-
|
|
1118
|
+
|
|
1027
1119
|
try:
|
|
1028
1120
|
# Any library operation
|
|
1029
1121
|
await mqtt_client.request_device_status(device)
|
|
1030
1122
|
except Nwp500Error as e:
|
|
1031
1123
|
# All nwp500 exceptions inherit from Nwp500Error
|
|
1032
1124
|
logger.error(f"Library error: {e.to_dict()}")
|
|
1033
|
-
|
|
1125
|
+
|
|
1034
1126
|
# Check if retriable
|
|
1035
1127
|
if e.retriable:
|
|
1036
1128
|
await retry_operation()
|
|
@@ -1042,7 +1134,7 @@ All exceptions now include structured information:
|
|
|
1042
1134
|
.. code-block:: python
|
|
1043
1135
|
|
|
1044
1136
|
from nwp500 import MqttPublishError
|
|
1045
|
-
|
|
1137
|
+
|
|
1046
1138
|
try:
|
|
1047
1139
|
await mqtt_client.publish(topic, payload)
|
|
1048
1140
|
except MqttPublishError as e:
|
|
@@ -1055,10 +1147,10 @@ All exceptions now include structured information:
|
|
|
1055
1147
|
# 'details': {},
|
|
1056
1148
|
# 'retriable': True
|
|
1057
1149
|
# }
|
|
1058
|
-
|
|
1150
|
+
|
|
1059
1151
|
# Log for monitoring/alerting
|
|
1060
1152
|
logger.error("Publish failed", extra=error_info)
|
|
1061
|
-
|
|
1153
|
+
|
|
1062
1154
|
# Implement retry logic
|
|
1063
1155
|
if e.retriable:
|
|
1064
1156
|
await asyncio.sleep(1)
|
|
@@ -1116,7 +1208,7 @@ Added
|
|
|
1116
1208
|
-----
|
|
1117
1209
|
|
|
1118
1210
|
- **MQTT Reconnection**: Two-tier reconnection strategy with unlimited retries
|
|
1119
|
-
|
|
1211
|
+
|
|
1120
1212
|
- Implemented quick reconnection (attempts 1-9) for fast recovery from transient network issues
|
|
1121
1213
|
- Implemented deep reconnection (every 10th attempt) with full connection rebuild and credential refresh
|
|
1122
1214
|
- Changed default ``max_reconnect_attempts`` from 10 to -1 (unlimited retries)
|
|
@@ -1132,7 +1224,7 @@ Improved
|
|
|
1132
1224
|
--------
|
|
1133
1225
|
|
|
1134
1226
|
- **Exception Handling**: Replaced 25 catch-all exception handlers with specific exception types
|
|
1135
|
-
|
|
1227
|
+
|
|
1136
1228
|
- ``mqtt_client.py``: Uses ``AwsCrtError``, ``AuthenticationError``, ``TokenRefreshError``, ``RuntimeError``, ``ValueError``, ``TypeError``, ``AttributeError``
|
|
1137
1229
|
- ``mqtt_reconnection.py``: Uses ``AwsCrtError``, ``RuntimeError``, ``ValueError``, ``TypeError``
|
|
1138
1230
|
- ``mqtt_connection.py``: Uses ``AwsCrtError``, ``RuntimeError``, ``ValueError``
|
|
@@ -1142,7 +1234,7 @@ Improved
|
|
|
1142
1234
|
- Added exception handling guidelines to ``.github/copilot-instructions.md``
|
|
1143
1235
|
|
|
1144
1236
|
- **Code Quality**: Multiple readability and safety improvements
|
|
1145
|
-
|
|
1237
|
+
|
|
1146
1238
|
- Simplified nested conditions by extracting to local variables
|
|
1147
1239
|
- Added ``hasattr()`` checks before accessing ``AwsCrtError.name`` attribute
|
|
1148
1240
|
- Optimized ``resubscribe_all()`` to break after first failure per topic (reduces redundant error logs)
|
|
@@ -1153,7 +1245,7 @@ Fixed
|
|
|
1153
1245
|
-----
|
|
1154
1246
|
|
|
1155
1247
|
- **MQTT Reconnection**: Eliminated duplicate "Connection interrupted" log messages
|
|
1156
|
-
|
|
1248
|
+
|
|
1157
1249
|
- Removed duplicate logging from ``mqtt_client.py`` (kept in ``mqtt_reconnection.py``)
|
|
1158
1250
|
|
|
1159
1251
|
Version 3.1.4 (2025-10-26)
|
|
@@ -1163,7 +1255,7 @@ Fixed
|
|
|
1163
1255
|
-----
|
|
1164
1256
|
|
|
1165
1257
|
- **MQTT Reconnection**: Fixed MQTT reconnection failures due to expired AWS credentials
|
|
1166
|
-
|
|
1258
|
+
|
|
1167
1259
|
- Added AWS credential expiration tracking (``_aws_expires_at`` field in ``AuthTokens``)
|
|
1168
1260
|
- Added ``are_aws_credentials_expired`` property to check AWS credential validity
|
|
1169
1261
|
- Modified ``ensure_valid_token()`` to prioritize AWS credential expiration check
|
|
@@ -1180,7 +1272,7 @@ Fixed
|
|
|
1180
1272
|
-----
|
|
1181
1273
|
|
|
1182
1274
|
- **MQTT Reconnection**: Improved MQTT reconnection reliability with active reconnection
|
|
1183
|
-
|
|
1275
|
+
|
|
1184
1276
|
- **Breaking Internal Change**: ``MqttReconnectionHandler`` now requires ``reconnect_func`` parameter (not Optional)
|
|
1185
1277
|
- Implemented active reconnection that always recreates MQTT connection on interruption
|
|
1186
1278
|
- Removed unreliable passive fallback to AWS IoT SDK automatic reconnection
|
|
@@ -1199,7 +1291,7 @@ Fixed
|
|
|
1199
1291
|
-----
|
|
1200
1292
|
|
|
1201
1293
|
- **Authentication**: Fixed 401 authentication errors with automatic token refresh
|
|
1202
|
-
|
|
1294
|
+
|
|
1203
1295
|
- Add automatic token refresh on 401 Unauthorized responses in API client
|
|
1204
1296
|
- Preserve AWS credentials when refreshing tokens (required for MQTT)
|
|
1205
1297
|
- Save refreshed tokens to cache after successful API calls
|
|
@@ -1216,7 +1308,7 @@ Fixed
|
|
|
1216
1308
|
-----
|
|
1217
1309
|
|
|
1218
1310
|
- **MQTT Client**: Fixed connection interrupted callback signature for AWS SDK
|
|
1219
|
-
|
|
1311
|
+
|
|
1220
1312
|
- Updated callback to match latest AWS IoT SDK signature: ``(connection, error, **kwargs)``
|
|
1221
1313
|
- Fixed type annotations in ``MqttConnection`` for proper type checking
|
|
1222
1314
|
- Resolves mypy type checking errors and ensures AWS SDK compatibility
|
|
@@ -1228,14 +1320,14 @@ Version 3.0.0 (Unreleased)
|
|
|
1228
1320
|
**Breaking Changes**
|
|
1229
1321
|
|
|
1230
1322
|
- **REMOVED**: ``OperationMode`` enum has been removed
|
|
1231
|
-
|
|
1323
|
+
|
|
1232
1324
|
- This enum was deprecated in v2.0.0 and has now been fully removed
|
|
1233
1325
|
- Use ``DhwOperationSetting`` for user-configured mode preferences (values 1-6)
|
|
1234
1326
|
- Use ``CurrentOperationMode`` for real-time operational states (values 0, 32, 64, 96)
|
|
1235
1327
|
- Migration was supported throughout the v2.x series
|
|
1236
1328
|
|
|
1237
1329
|
- **REMOVED**: Migration helper functions and deprecation infrastructure
|
|
1238
|
-
|
|
1330
|
+
|
|
1239
1331
|
- Removed ``migrate_operation_mode_usage()`` function
|
|
1240
1332
|
- Removed ``enable_deprecation_warnings()`` function
|
|
1241
1333
|
- Removed migration documentation files (MIGRATION.md, BREAKING_CHANGES_V3.md)
|
|
@@ -1248,7 +1340,7 @@ Version 2.0.0 (Unreleased)
|
|
|
1248
1340
|
|
|
1249
1341
|
- **DEPRECATION**: ``OperationMode`` enum is deprecated and will be removed in v3.0.0
|
|
1250
1342
|
|
|
1251
|
-
|
|
1343
|
+
|
|
1252
1344
|
- Use ``DhwOperationSetting`` for user-configured mode preferences (values 1-6)
|
|
1253
1345
|
- Use ``CurrentOperationMode`` for real-time operational states (values 0, 32, 64, 96)
|
|
1254
1346
|
- See ``MIGRATION.md`` for detailed migration guide
|
|
@@ -1325,7 +1417,7 @@ Added
|
|
|
1325
1417
|
- Standardized ruff configuration across all environments
|
|
1326
1418
|
- Eliminates "passes locally but fails in CI" issues
|
|
1327
1419
|
- Cross-platform support (Linux, macOS, Windows, containers)
|
|
1328
|
-
|
|
1420
|
+
|
|
1329
1421
|
- All MQTT operations (connect, disconnect, subscribe, unsubscribe, publish) use ``asyncio.wrap_future()`` to convert AWS SDK Futures to asyncio Futures
|
|
1330
1422
|
- Eliminates "blocking I/O detected" warnings in Home Assistant and other async applications
|
|
1331
1423
|
- Fully compatible with async event loops without blocking other operations
|
|
@@ -1336,7 +1428,7 @@ Added
|
|
|
1336
1428
|
- Updated documentation with non-blocking implementation details
|
|
1337
1429
|
|
|
1338
1430
|
- **Event Emitter Pattern (Phase 1)**: Event-driven architecture for device state changes
|
|
1339
|
-
|
|
1431
|
+
|
|
1340
1432
|
- ``EventEmitter`` base class with multiple listeners per event
|
|
1341
1433
|
- Async and sync handler support
|
|
1342
1434
|
- Priority-based execution order (higher priority executes first)
|
|
@@ -1354,7 +1446,7 @@ Added
|
|
|
1354
1446
|
- Documentation: ``EVENT_EMITTER.rst``, ``EVENT_QUICK_REFERENCE.rst``, ``EVENT_ARCHITECTURE.rst``
|
|
1355
1447
|
|
|
1356
1448
|
- **Authentication**: Simplified constructor-based authentication
|
|
1357
|
-
|
|
1449
|
+
|
|
1358
1450
|
- ``NavienAuthClient`` now requires ``user_id`` and ``password`` in constructor
|
|
1359
1451
|
- Automatic authentication when entering async context manager
|
|
1360
1452
|
- No need to call ``sign_in()`` manually
|
|
@@ -1363,7 +1455,7 @@ Added
|
|
|
1363
1455
|
- Updated all documentation with new authentication examples
|
|
1364
1456
|
|
|
1365
1457
|
- **MQTT Command Queue**: Automatic command queuing when disconnected
|
|
1366
|
-
|
|
1458
|
+
|
|
1367
1459
|
- Commands sent while disconnected are automatically queued
|
|
1368
1460
|
- Queue processed in FIFO order when connection is restored
|
|
1369
1461
|
- Configurable queue size (default: 100 commands)
|
|
@@ -1376,7 +1468,7 @@ Added
|
|
|
1376
1468
|
- Documentation: ``COMMAND_QUEUE.rst``
|
|
1377
1469
|
|
|
1378
1470
|
- **MQTT Reconnection**: Automatic reconnection with exponential backoff
|
|
1379
|
-
|
|
1471
|
+
|
|
1380
1472
|
- Automatic reconnection on connection interruption
|
|
1381
1473
|
- Configurable exponential backoff (default: 1s, 2s, 4s, 8s, ... up to 120s)
|
|
1382
1474
|
- Configurable max attempts (default: 10)
|
|
@@ -1388,7 +1480,7 @@ Added
|
|
|
1388
1480
|
- Documentation: Added reconnection section to MQTT_CLIENT.rst
|
|
1389
1481
|
|
|
1390
1482
|
- **MQTT Client**: Complete implementation of real-time device communication
|
|
1391
|
-
|
|
1483
|
+
|
|
1392
1484
|
- WebSocket MQTT connection to AWS IoT Core
|
|
1393
1485
|
- Device subscription and message handling
|
|
1394
1486
|
- Status request methods (device info, device status)
|
|
@@ -1397,7 +1489,7 @@ Added
|
|
|
1397
1489
|
- Connection lifecycle management (connect, disconnect, reconnect)
|
|
1398
1490
|
|
|
1399
1491
|
- **Device Control**: Fully implemented and verified control commands
|
|
1400
|
-
|
|
1492
|
+
|
|
1401
1493
|
- Power control (on/off) with correct command codes
|
|
1402
1494
|
- DHW mode control (Heat Pump, Electric, Energy Saver, High Demand)
|
|
1403
1495
|
- DHW temperature control with 20°F offset handling
|
|
@@ -1405,7 +1497,7 @@ Added
|
|
|
1405
1497
|
- Helper method for display-value temperature control
|
|
1406
1498
|
|
|
1407
1499
|
- **Typed Callbacks**: 100% coverage of all MQTT response types
|
|
1408
|
-
|
|
1500
|
+
|
|
1409
1501
|
- ``subscribe_device_status()`` - Automatic parsing of status messages into ``DeviceStatus`` objects
|
|
1410
1502
|
- ``subscribe_device_feature()`` - Automatic parsing of feature messages into ``DeviceFeature`` objects
|
|
1411
1503
|
- ``subscribe_energy_usage()`` - Automatic parsing of energy usage responses into ``EnergyUsageResponse`` objects
|
|
@@ -1414,7 +1506,7 @@ Added
|
|
|
1414
1506
|
- Example scripts demonstrating usage patterns
|
|
1415
1507
|
|
|
1416
1508
|
- **Energy Usage API (EMS)**: Historical energy consumption data
|
|
1417
|
-
|
|
1509
|
+
|
|
1418
1510
|
- ``request_energy_usage()`` - Query daily energy usage for specified month(s)
|
|
1419
1511
|
- ``EnergyUsageResponse`` dataclass with daily breakdown
|
|
1420
1512
|
- ``EnergyUsageTotal`` with percentage calculations
|
|
@@ -1426,7 +1518,7 @@ Added
|
|
|
1426
1518
|
- Efficiency percentage calculations
|
|
1427
1519
|
|
|
1428
1520
|
- **Data Models**: Comprehensive type-safe models
|
|
1429
|
-
|
|
1521
|
+
|
|
1430
1522
|
- ``DeviceStatus`` dataclass with 125 sensor and operational fields
|
|
1431
1523
|
- ``DeviceFeature`` dataclass with 46 capability and configuration fields
|
|
1432
1524
|
- ``EnergyUsageResponse`` dataclass for historical energy data
|
|
@@ -1439,7 +1531,7 @@ Added
|
|
|
1439
1531
|
- Authentication tokens and user info
|
|
1440
1532
|
|
|
1441
1533
|
- **API Client**: High-level REST API client
|
|
1442
|
-
|
|
1534
|
+
|
|
1443
1535
|
- Device listing and information retrieval
|
|
1444
1536
|
- Firmware information queries
|
|
1445
1537
|
- Time-of-Use (TOU) schedule management
|
|
@@ -1448,7 +1540,7 @@ Added
|
|
|
1448
1540
|
- Automatic session management
|
|
1449
1541
|
|
|
1450
1542
|
- **Authentication**: AWS Cognito integration
|
|
1451
|
-
|
|
1543
|
+
|
|
1452
1544
|
- Sign-in with email/password
|
|
1453
1545
|
- Access token management
|
|
1454
1546
|
- Token refresh functionality
|
|
@@ -1456,7 +1548,7 @@ Added
|
|
|
1456
1548
|
- Async context manager support
|
|
1457
1549
|
|
|
1458
1550
|
- **Documentation**: Complete protocol and API documentation
|
|
1459
|
-
|
|
1551
|
+
|
|
1460
1552
|
- MQTT message format specifications
|
|
1461
1553
|
- Energy usage query API documentation (EMS data)
|
|
1462
1554
|
- API client usage guide
|
|
@@ -1468,7 +1560,7 @@ Added
|
|
|
1468
1560
|
- Complete energy data reference (ENERGY_DATA_SUMMARY.md)
|
|
1469
1561
|
|
|
1470
1562
|
- **Examples**: Production-ready example scripts
|
|
1471
|
-
|
|
1563
|
+
|
|
1472
1564
|
- ``device_status_callback.py`` - Real-time status monitoring with typed callbacks
|
|
1473
1565
|
- ``device_feature_callback.py`` - Device capabilities and firmware info
|
|
1474
1566
|
- ``combined_callbacks.py`` - Both status and feature callbacks together
|
|
@@ -1481,7 +1573,7 @@ Changed
|
|
|
1481
1573
|
-------
|
|
1482
1574
|
|
|
1483
1575
|
- **Breaking**: Python version requirement updated to 3.9+
|
|
1484
|
-
|
|
1576
|
+
|
|
1485
1577
|
- Minimum Python version is now 3.9 (was 3.8)
|
|
1486
1578
|
- Migrated to native type hints (PEP 585): ``dict[str, Any]`` instead of ``Dict[str, Any]``
|
|
1487
1579
|
- Removed ``typing.Dict``, ``typing.List``, ``typing.Deque`` imports
|
|
@@ -1490,7 +1582,7 @@ Changed
|
|
|
1490
1582
|
- Updated ruff target-version to py39
|
|
1491
1583
|
|
|
1492
1584
|
- **Breaking**: ``NavienAuthClient`` constructor signature
|
|
1493
|
-
|
|
1585
|
+
|
|
1494
1586
|
- Now requires ``user_id`` and ``password`` as first parameters
|
|
1495
1587
|
- Old: ``NavienAuthClient()`` then ``await client.sign_in(email, password)``
|
|
1496
1588
|
- New: ``NavienAuthClient(email, password)`` - authentication is automatic
|
|
@@ -1499,7 +1591,7 @@ Changed
|
|
|
1499
1591
|
- All documentation updated with new examples
|
|
1500
1592
|
|
|
1501
1593
|
- **Documentation**: Major updates across all files
|
|
1502
|
-
|
|
1594
|
+
|
|
1503
1595
|
- Fixed all RST formatting issues (title underlines, tables)
|
|
1504
1596
|
- Updated authentication examples in 8 documentation files
|
|
1505
1597
|
- Fixed broken documentation links (local file paths)
|
|
@@ -1514,7 +1606,7 @@ Fixed
|
|
|
1514
1606
|
-----
|
|
1515
1607
|
|
|
1516
1608
|
- **Critical Bug**: Thread-safe reconnection task creation from MQTT callbacks
|
|
1517
|
-
|
|
1609
|
+
|
|
1518
1610
|
- Fixed ``RuntimeError: no running event loop`` when connection is interrupted
|
|
1519
1611
|
- Fixed ``RuntimeWarning: coroutine '_reconnect_with_backoff' was never awaited``
|
|
1520
1612
|
- Connection interruption callbacks run in separate threads without event loops
|
|
@@ -1524,7 +1616,7 @@ Fixed
|
|
|
1524
1616
|
- Ensures reconnection tasks are properly awaited and executed
|
|
1525
1617
|
|
|
1526
1618
|
- **Critical Bug**: Thread-safe event emission from MQTT callbacks
|
|
1527
|
-
|
|
1619
|
+
|
|
1528
1620
|
- Fixed ``RuntimeError: no running event loop in thread 'Dummy-1'``
|
|
1529
1621
|
- MQTT callbacks run in separate threads created by AWS IoT SDK
|
|
1530
1622
|
- Implemented ``_schedule_coroutine()`` method for thread-safe scheduling
|
|
@@ -1534,7 +1626,7 @@ Fixed
|
|
|
1534
1626
|
- All event emissions now work correctly from any thread
|
|
1535
1627
|
|
|
1536
1628
|
- **Bug**: Incorrect method parameter passing in temperature control
|
|
1537
|
-
|
|
1629
|
+
|
|
1538
1630
|
- Fixed ``set_dhw_temperature_display()`` calling ``set_dhw_temperature()`` with wrong parameters
|
|
1539
1631
|
- Was passing individual parameters (``device_id``, ``device_type``, ``additional_value``)
|
|
1540
1632
|
- Now correctly passes ``Device`` object as expected by method signature
|
|
@@ -1542,14 +1634,14 @@ Fixed
|
|
|
1542
1634
|
- Updated docstrings to match actual method signatures
|
|
1543
1635
|
|
|
1544
1636
|
- **Enhancement**: Anonymized MAC addresses in documentation
|
|
1545
|
-
|
|
1637
|
+
|
|
1546
1638
|
- Replaced all occurrences of real MAC address (``04786332fca0``) with placeholder (``aabbccddeeff``)
|
|
1547
1639
|
- Updated ``API_CLIENT.rst``, ``MQTT_CLIENT.rst``, ``MQTT_MESSAGES.rst``
|
|
1548
1640
|
- Updated built HTML documentation files
|
|
1549
1641
|
- Protects privacy in public documentation
|
|
1550
1642
|
|
|
1551
1643
|
- **Critical Bug**: Device control command codes
|
|
1552
|
-
|
|
1644
|
+
|
|
1553
1645
|
- Fixed incorrect command code usage causing unintended power-off
|
|
1554
1646
|
- Power-off now uses command code ``33554433``
|
|
1555
1647
|
- Power-on now uses command code ``33554434``
|
|
@@ -1557,7 +1649,7 @@ Fixed
|
|
|
1557
1649
|
- Discovered through network traffic analysis of official app
|
|
1558
1650
|
|
|
1559
1651
|
- **Critical Bug**: MQTT topic pattern matching with wildcards
|
|
1560
|
-
|
|
1652
|
+
|
|
1561
1653
|
- Fixed ``_topic_matches_pattern()`` to correctly handle ``#`` wildcard
|
|
1562
1654
|
- Topics now match when message arrives on base topic (e.g., ``cmd/52/device/res``)
|
|
1563
1655
|
- Topics also match subtopics (e.g., ``cmd/52/device/res/extra``)
|
|
@@ -1565,21 +1657,21 @@ Fixed
|
|
|
1565
1657
|
- Enables callbacks to receive messages correctly
|
|
1566
1658
|
|
|
1567
1659
|
- **Bug**: Missing ``OperationMode.STANDBY`` enum value
|
|
1568
|
-
|
|
1660
|
+
|
|
1569
1661
|
- Added ``STANDBY = 0`` to ``OperationMode`` enum
|
|
1570
1662
|
- Device reports mode 0 when tank is fully charged and no heating is needed
|
|
1571
1663
|
- Added graceful fallback for unknown enum values
|
|
1572
1664
|
- Prevents ``ValueError`` when parsing device status
|
|
1573
1665
|
|
|
1574
1666
|
- **Bug**: Insufficient topic subscriptions
|
|
1575
|
-
|
|
1667
|
+
|
|
1576
1668
|
- Examples now subscribe to broader topic patterns
|
|
1577
1669
|
- Subscribe to ``cmd/{device_type}/{device_topic}/#`` to catch all command messages
|
|
1578
1670
|
- Subscribe to ``evt/{device_type}/{device_topic}/#`` to catch all event messages
|
|
1579
1671
|
- Ensures all device responses are received
|
|
1580
1672
|
|
|
1581
1673
|
- **Enhancement**: Robust enum conversion with fallbacks
|
|
1582
|
-
|
|
1674
|
+
|
|
1583
1675
|
- Added try/except blocks for all enum conversions in ``DeviceStatus.from_dict()``
|
|
1584
1676
|
- Added try/except blocks for all enum conversions in ``DeviceFeature.from_dict()``
|
|
1585
1677
|
- Unknown operation modes default to ``STANDBY``
|
|
@@ -1592,7 +1684,7 @@ Verified
|
|
|
1592
1684
|
--------
|
|
1593
1685
|
|
|
1594
1686
|
- **Device Control**: Real-world testing with Navien NWP500 device
|
|
1595
|
-
|
|
1687
|
+
|
|
1596
1688
|
- Successfully changed DHW mode from Heat Pump to Energy Saver
|
|
1597
1689
|
- Successfully changed DHW mode from Energy Saver to High Demand
|
|
1598
1690
|
- Successfully changed DHW temperature (discovered 20°F offset between message and display)
|