nwp500-python 9.4.0__tar.gz → 9.4.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-9.4.0 → nwp500_python-9.4.1}/CHANGELOG.rst +14 -0
- {nwp500_python-9.4.0/src/nwp500_python.egg-info → nwp500_python-9.4.1}/PKG-INFO +1 -1
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/explanation/tank-energy.rst +7 -7
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/protocol/data_conversions.rst +1 -1
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/python_api/models.rst +1 -1
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/converters.py +1 -1
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/reconnection.py +7 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1/src/nwp500_python.egg-info}/PKG-INFO +1 -1
- nwp500_python-9.4.1/src/nwp500_python.egg-info/scm_version.json +8 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_mqtt_reliability.py +39 -0
- nwp500_python-9.4.0/src/nwp500_python.egg-info/scm_version.json +0 -8
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/.coveragerc +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/.github/RESOLVING_PR_COMMENTS.md +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/.github/copilot-instructions.md +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/.github/workflows/ci.yml +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/.github/workflows/release.yml +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/.gitignore +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/.pre-commit-config.yaml +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/.readthedocs.yml +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/AUTHORS.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/CONTRIBUTING.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/LICENSE.txt +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/Makefile +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/README.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/RELEASE.md +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/Makefile +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/_static/.gitignore +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/conf.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/explanation/advanced-features.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/explanation/architecture.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/explanation/index.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/explanation/tou-recovery-cap.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/explanation/unknown-values.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/authenticate.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/auto-recovery.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/diagnose-mqtt.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/home-assistant.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/index.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/maintenance.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/manage-units.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/monitor-status.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/optimize-tou.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/queue-commands.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/schedule-operation.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/how-to/track-energy.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/index.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/openapi.yaml +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/project/authors.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/project/changelog.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/project/contributing.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/project/history.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/project/license.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/configuration.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/enumerations.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/index.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/installation.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/protocol/device_features.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/protocol/device_status.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/protocol/error_codes.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/protocol/mqtt_protocol.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/protocol/quick_reference.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/protocol/rest_api.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/python_api/api_client.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/python_api/auth_client.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/python_api/cli.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/python_api/events.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/python_api/exceptions.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/reference/python_api/mqtt_client.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/requirements.txt +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/docs/tutorials/getting-started.rst +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/.ruff.toml +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/README.md +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/air_filter_reset.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/anti_legionella.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/auto_recovery.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/combined_callbacks.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/demand_response.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/device_capabilities.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/device_status_debug.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/energy_analytics.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/error_code_demo.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/firmware_payload_capture.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/mqtt_diagnostics.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/power_control.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/recirculation_control.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/reconnection_demo.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/reservation_schedule.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/simple_auto_recovery.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/token_restoration.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/tou_openei.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/tou_schedule.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/advanced/water_reservation.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/beginner/01_authentication.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/beginner/02_list_devices.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/beginner/03_get_status.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/beginner/04_set_temperature.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/advanced_auth_patterns.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/command_queue.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/device_status_callback.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/error_handling.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/event_driven_control.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/improved_auth.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/legacy_auth_constructor.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/mqtt_realtime_monitoring.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/periodic_requests.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/set_mode.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/vacation_mode.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/mask.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/testing/periodic_device_info.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/testing/simple_periodic_info.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/testing/test_api_client.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/testing/test_mqtt_connection.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/testing/test_mqtt_messaging.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/testing/test_periodic_minimal.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/pyproject.toml +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/scripts/README.md +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/scripts/bump_version.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/scripts/diagnose_mqtt_connection.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/scripts/extract_changelog.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/scripts/format.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/scripts/lint.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/scripts/setup-dev.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/scripts/validate_version.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/setup.cfg +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/setup.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/__init__.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/_base.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/api_client.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/auth.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/cli/__init__.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/cli/__main__.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/cli/handlers.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/cli/monitoring.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/cli/output_formatters.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/cli/presentation.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/cli/rich_output.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/cli/token_storage.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/command_decorators.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/config.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/device_capabilities.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/device_info_cache.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/encoding.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/enums.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/events.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/exceptions.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/factory.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/field_factory.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/__init__.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/_converters.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/device.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/diagnostics.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/energy.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/feature.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/firmware.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/mqtt_models.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/schedule.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/status.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/models/tou.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/__init__.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/_control_commands.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/_device_subscriptions.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/client.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/command_queue.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/connection.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/control.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/diagnostics.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/periodic.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/state_tracker.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/subscriptions.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/types.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt/utils.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/mqtt_events.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/openei.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/py.typed +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/reservations.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/temperature.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/topic_builder.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/tou_schedule.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/unit_system.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500/utils.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500_python.egg-info/SOURCES.txt +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500_python.egg-info/dependency_links.txt +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500_python.egg-info/entry_points.txt +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500_python.egg-info/not-zip-safe +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500_python.egg-info/requires.txt +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500_python.egg-info/scm_file_list.json +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/src/nwp500_python.egg-info/top_level.txt +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/conftest.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_api_helpers.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_app_queries.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_auth.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_auth_session_lifecycle.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_bug_fixes.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_canonical_schedule.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_cli_basic.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_cli_commands.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_cli_tristate_presentation.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_command_decorators.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_command_queue.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_device_capabilities.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_device_info_cache.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_device_rest_models.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_events.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_exceptions.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_model_converters.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_models.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_mqtt_clean_session_resume.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_mqtt_client_init.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_mqtt_events.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_mqtt_hypothesis.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_mqtt_reconnection.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_mqtt_reconnection_storm.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_multi_device.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_openei.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_protocol_correctness.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_public_api.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_reservations.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_temperature_converters.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_threading_model.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_token_storage.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_tou_api.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_tou_schedule.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_unit_switching.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_unit_system_process_wide.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_utility_modules.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tests/test_utils.py +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/tox.ini +0 -0
- {nwp500_python-9.4.0 → nwp500_python-9.4.1}/uv.lock +0 -0
|
@@ -5,6 +5,20 @@ Changelog
|
|
|
5
5
|
Unreleased
|
|
6
6
|
==========
|
|
7
7
|
|
|
8
|
+
Version 9.4.1 (2026-09-17)
|
|
9
|
+
==========================
|
|
10
|
+
|
|
11
|
+
Fixed
|
|
12
|
+
-----
|
|
13
|
+
- **The reconnect attempt counter never reset after a successful quick or
|
|
14
|
+
deep reconnect.** Both build a new connection, so the SDK never calls
|
|
15
|
+
``on_connection_resumed``, the only place the counter was reset. Each
|
|
16
|
+
later interruption started where the last one stopped: its first delay
|
|
17
|
+
was longer and it reached the deep-reconnect threshold sooner. A
|
|
18
|
+
long-running client saw the first delay grow from about 1 s to 12 s
|
|
19
|
+
over five daily AWS IoT disconnects. The counter now resets whenever the
|
|
20
|
+
backoff loop ends connected.
|
|
21
|
+
|
|
8
22
|
Version 9.4.0 (2026-09-12)
|
|
9
23
|
==========================
|
|
10
24
|
|
|
@@ -3,7 +3,7 @@ Tank Energy
|
|
|
3
3
|
===========
|
|
4
4
|
|
|
5
5
|
The NWP500 reports two energy figures, ``totalEnergyCapacity`` and
|
|
6
|
-
``availableEnergyCapacity``. Both names mislead, and before
|
|
6
|
+
``availableEnergyCapacity``. Both names mislead, and before v9.3.0 this
|
|
7
7
|
library also scaled them wrongly. This page explains what they
|
|
8
8
|
actually measure and shows the evidence for the correction.
|
|
9
9
|
|
|
@@ -33,7 +33,7 @@ The short version
|
|
|
33
33
|
whenever the setpoint moves.
|
|
34
34
|
|
|
35
35
|
Both are raw counts of 4 Wh each, not Watt-hours. Library versions before
|
|
36
|
-
|
|
36
|
+
9.3.0 multiplied by 10, overstating tank energy by 2.5x.
|
|
37
37
|
|
|
38
38
|
Both are also measured **from the setpoint**, so both describe potential
|
|
39
39
|
rather than content: move the setpoint and both change while the water in
|
|
@@ -226,7 +226,7 @@ coefficient of performance:
|
|
|
226
226
|
* - 4 Wh/count (corrected)
|
|
227
227
|
- 2.89
|
|
228
228
|
- Normal for a heat pump water heater
|
|
229
|
-
* - 10 Wh/count (pre-
|
|
229
|
+
* - 10 Wh/count (pre-9.3.0)
|
|
230
230
|
- 7.02
|
|
231
231
|
- Physically impossible
|
|
232
232
|
|
|
@@ -236,7 +236,7 @@ A heat pump water heater in a 72 degF room runs at a COP of roughly 2 to
|
|
|
236
236
|
This argument is worth stating separately because it needs no tank
|
|
237
237
|
volume, specific heat or stratification model - only the device's own
|
|
238
238
|
reported energy and its own reported power. It cannot tell you what the
|
|
239
|
-
quantum *is*, but it rules out the pre-
|
|
239
|
+
quantum *is*, but it rules out the pre-9.3.0 value regardless of anything
|
|
240
240
|
assumed elsewhere on this page.
|
|
241
241
|
|
|
242
242
|
.. _two branches:
|
|
@@ -403,8 +403,8 @@ the heat capacity is 156 Wh per degF:
|
|
|
403
403
|
drawable_Wh = 156 * (tank_mean_temperature - your_floor_degF)
|
|
404
404
|
|
|
405
405
|
|
|
406
|
-
Migrating from before
|
|
407
|
-
|
|
406
|
+
Migrating from before v9.3.0
|
|
407
|
+
============================
|
|
408
408
|
|
|
409
409
|
.. list-table::
|
|
410
410
|
:header-rows: 1
|
|
@@ -429,7 +429,7 @@ rename that is missed fails immediately with ``AttributeError`` instead
|
|
|
429
429
|
of silently returning a number 2.5x too large.
|
|
430
430
|
|
|
431
431
|
If you logged these values historically, the stored series needs
|
|
432
|
-
rescaling by 0.4 to be comparable with values from
|
|
432
|
+
rescaling by 0.4 to be comparable with values from v9.3.0 onward.
|
|
433
433
|
|
|
434
434
|
|
|
435
435
|
See also
|
|
@@ -367,7 +367,7 @@ Power and Energy Fields
|
|
|
367
367
|
candidate implying a water volume below the nameplate. Two further
|
|
368
368
|
checks agree -- 183 heating recoveries give 4.11 Wh/count by a
|
|
369
369
|
noisier route, and the same recoveries imply a heat-pump COP of 2.89.
|
|
370
|
-
The library uses 4.0. Versions before
|
|
370
|
+
The library uses 4.0. Versions before 9.3.0 used 10, which overstated
|
|
371
371
|
reported tank energy by 2.5x and implied a physically impossible COP
|
|
372
372
|
of 7.0. See :doc:`../../explanation/tank-energy`.
|
|
373
373
|
|
|
@@ -263,7 +263,7 @@ Complete real-time device status with 100+ fields.
|
|
|
263
263
|
|
|
264
264
|
.. warning::
|
|
265
265
|
These replace ``total_energy_capacity`` and
|
|
266
|
-
``available_energy_capacity``, which were **removed** in
|
|
266
|
+
``available_energy_capacity``, which were **removed** in v9.3.0. The
|
|
267
267
|
old names were misleading -- ``available_energy_capacity`` is the
|
|
268
268
|
energy *needed*, not the energy available -- and both were scaled
|
|
269
269
|
2.5x too large. For energy you can actually draw, see
|
|
@@ -45,7 +45,7 @@ __all__ = [
|
|
|
45
45
|
#: p90 4.45), agreeing to within 2% by a noisier route
|
|
46
46
|
#: * the same recoveries imply a heat pump COP of 2.89 at 4 Wh/count
|
|
47
47
|
#:
|
|
48
|
-
#: Library versions before
|
|
48
|
+
#: Library versions before 9.3.0 used 10 Wh/count, which overstated reported
|
|
49
49
|
#: tank energy by 2.5x and implied a physically impossible COP of 7.0.
|
|
50
50
|
#:
|
|
51
51
|
#: See ``docs/explanation/tank-energy.rst`` for the full derivation.
|
|
@@ -347,6 +347,13 @@ class MqttReconnectionHandler:
|
|
|
347
347
|
f"Error during reconnection attempt: {e}", exc_info=True
|
|
348
348
|
)
|
|
349
349
|
|
|
350
|
+
# A successful quick or deep reconnect builds a new connection, so
|
|
351
|
+
# the SDK never calls on_connection_resumed for it. Reset the
|
|
352
|
+
# counter here, or every later interruption starts with a longer
|
|
353
|
+
# backoff and an earlier deep reconnect than the first one did.
|
|
354
|
+
if self._is_connected_func():
|
|
355
|
+
self._reconnect_attempts = 0
|
|
356
|
+
|
|
350
357
|
# Check final state: report failure when retries are exhausted
|
|
351
358
|
# (limited mode) or a fatal error stopped the loop.
|
|
352
359
|
attempts_exhausted = (
|
|
@@ -231,6 +231,45 @@ class TestReconnectLoopExceptionHandling:
|
|
|
231
231
|
assert all(d <= config.max_reconnect_delay for d in sleeps)
|
|
232
232
|
assert all(d > 0 for d in sleeps)
|
|
233
233
|
|
|
234
|
+
@pytest.mark.asyncio
|
|
235
|
+
@pytest.mark.parametrize("deep", [False, True])
|
|
236
|
+
async def test_successful_reconnect_resets_attempt_count(self, deep):
|
|
237
|
+
"""Regression: a quick or deep reconnect makes a new connection, so
|
|
238
|
+
on_connection_resumed never fires and the counter kept growing
|
|
239
|
+
across interruptions, lengthening each later backoff."""
|
|
240
|
+
connected = False
|
|
241
|
+
attempts = []
|
|
242
|
+
|
|
243
|
+
async def reconnect():
|
|
244
|
+
nonlocal connected
|
|
245
|
+
attempts.append(1)
|
|
246
|
+
# Fail the first try of each interruption, then succeed.
|
|
247
|
+
if len(attempts) % 2 == 0:
|
|
248
|
+
connected = True
|
|
249
|
+
return
|
|
250
|
+
raise MqttNotConnectedError("down")
|
|
251
|
+
|
|
252
|
+
kwargs = {"deep_reconnect_func": reconnect} if deep else {}
|
|
253
|
+
config = _fast_config(
|
|
254
|
+
max_reconnect_attempts=-1,
|
|
255
|
+
deep_reconnect_threshold=1,
|
|
256
|
+
)
|
|
257
|
+
handler = _make_handler(
|
|
258
|
+
config,
|
|
259
|
+
lambda: connected,
|
|
260
|
+
reconnect,
|
|
261
|
+
**kwargs,
|
|
262
|
+
)
|
|
263
|
+
handler.enable()
|
|
264
|
+
|
|
265
|
+
for _ in range(3):
|
|
266
|
+
connected = False
|
|
267
|
+
await handler._reconnect_with_backoff()
|
|
268
|
+
assert connected
|
|
269
|
+
assert handler.attempt_count == 0
|
|
270
|
+
|
|
271
|
+
assert len(attempts) == 6
|
|
272
|
+
|
|
234
273
|
|
|
235
274
|
class TestDisconnectDuringInterruption:
|
|
236
275
|
"""disconnect() must fully shut down even when not connected."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/legacy_auth_constructor.py
RENAMED
|
File without changes
|
{nwp500_python-9.4.0 → nwp500_python-9.4.1}/examples/intermediate/mqtt_realtime_monitoring.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|