nwp500-python 6.1.1__tar.gz → 7.0.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-6.1.1 → nwp500_python-7.0.1}/.github/workflows/ci.yml +1 -1
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/.github/workflows/release.yml +1 -1
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/CHANGELOG.rst +118 -1
- {nwp500_python-6.1.1/src/nwp500_python.egg-info → nwp500_python-7.0.1}/PKG-INFO +5 -11
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/README.rst +2 -4
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/development/history.rst +2 -2
- nwp500_python-7.0.1/docs/enumerations.rst +293 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/guides/time_of_use.rst +3 -3
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/index.rst +1 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/installation.rst +3 -3
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/protocol/data_conversions.rst +2 -2
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/protocol/device_features.rst +29 -20
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/protocol/mqtt_protocol.rst +449 -23
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/python_api/models.rst +38 -136
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/python_api/mqtt_client.rst +10 -6
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/quickstart.rst +1 -1
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/anti_legionella_example.py +6 -6
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/combined_callbacks.py +5 -2
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/device_feature_callback.py +22 -21
- nwp500_python-7.0.1/examples/error_code_demo.py +155 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/event_emitter_demo.py +10 -3
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/mask.py +4 -5
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/mqtt_diagnostics_example.py +25 -15
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/pyproject.toml +2 -2
- nwp500_python-7.0.1/scripts/diagnose_mqtt_connection.py +174 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/scripts/extract_changelog.py +9 -9
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/scripts/lint.py +2 -2
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/setup.cfg +2 -6
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/__init__.py +33 -6
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/api_client.py +7 -7
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/auth.py +32 -15
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/cli/commands.py +28 -48
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/cli/output_formatters.py +7 -8
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/cli/token_storage.py +1 -2
- nwp500_python-7.0.1/src/nwp500/constants.py +34 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/encoding.py +6 -7
- nwp500_python-7.0.1/src/nwp500/enums.py +501 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/events.py +6 -5
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/exceptions.py +9 -9
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/models.py +192 -102
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/mqtt_client.py +116 -5
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/mqtt_command_queue.py +11 -5
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/mqtt_connection.py +10 -9
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/mqtt_device_control.py +11 -13
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/mqtt_diagnostics.py +21 -18
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/mqtt_periodic.py +6 -5
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/mqtt_reconnection.py +8 -6
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/mqtt_subscriptions.py +5 -2
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/mqtt_utils.py +8 -4
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/utils.py +5 -6
- {nwp500_python-6.1.1 → nwp500_python-7.0.1/src/nwp500_python.egg-info}/PKG-INFO +5 -11
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500_python.egg-info/SOURCES.txt +7 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500_python.egg-info/requires.txt +1 -1
- nwp500_python-7.0.1/tests/test_cli_basic.py +24 -0
- nwp500_python-7.0.1/tests/test_cli_commands.py +151 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/tests/test_command_queue.py +3 -3
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/tests/test_models.py +4 -3
- nwp500_python-7.0.1/tests/test_mqtt_client_init.py +828 -0
- nwp500_python-6.1.1/src/nwp500/constants.py +0 -85
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/.agent/workflows/pre-completion-testing.md +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/.coveragerc +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/.github/copilot-instructions.md +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/.gitignore +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/.pre-commit-config.yaml +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/.readthedocs.yml +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/AUTHORS.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/CONTRIBUTING.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/LICENSE.txt +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/Makefile +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/RELEASE.md +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/MQTT_DIAGNOSTICS.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/Makefile +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/_static/.gitignore +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/api/nwp500.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/authors.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/changelog.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/conf.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/configuration.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/development/contributing.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/guides/advanced_features_explained.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/guides/auto_recovery.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/guides/command_queue.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/guides/energy_monitoring.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/guides/event_system.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/guides/reservations.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/guides/scheduling_features.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/license.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/openapi.yaml +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/protocol/device_status.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/protocol/error_codes.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/protocol/firmware_tracking.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/protocol/rest_api.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/python_api/api_client.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/python_api/auth_client.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/python_api/cli.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/python_api/constants.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/python_api/events.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/python_api/exceptions.rst +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/docs/requirements.txt +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/.ruff.toml +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/README.md +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/api_client_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/auth_constructor_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/authenticate.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/auto_recovery_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/command_queue_demo.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/device_status_callback.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/device_status_callback_debug.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/energy_usage_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/exception_handling_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/improved_auth_pattern.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/mqtt_client_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/periodic_device_info.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/periodic_requests.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/power_control_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/reconnection_demo.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/reservation_schedule_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/set_dhw_temperature_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/set_mode_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/simple_auto_recovery.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/simple_periodic_info.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/simple_periodic_status.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/test_api_client.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/test_mqtt_connection.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/test_mqtt_messaging.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/test_periodic_minimal.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/token_restoration_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/tou_openei_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/examples/tou_schedule_example.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/scripts/README.md +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/scripts/bump_version.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/scripts/format.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/scripts/setup-dev.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/scripts/validate_version.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/setup.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/cli/__init__.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/cli/__main__.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/cli/monitoring.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/config.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500/py.typed +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500_python.egg-info/dependency_links.txt +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500_python.egg-info/entry_points.txt +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500_python.egg-info/not-zip-safe +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/src/nwp500_python.egg-info/top_level.txt +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/tests/conftest.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/tests/test_api_helpers.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/tests/test_auth.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/tests/test_events.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/tests/test_exceptions.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/tests/test_utils.py +0 -0
- {nwp500_python-6.1.1 → nwp500_python-7.0.1}/tox.ini +0 -0
|
@@ -2,6 +2,123 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
Version 7.0.1 (2025-12-18)
|
|
6
|
+
==========================
|
|
7
|
+
|
|
8
|
+
Fixed
|
|
9
|
+
-----
|
|
10
|
+
- Minor bug fixes and improvements
|
|
11
|
+
|
|
12
|
+
Version 7.0.0 (2025-12-17)
|
|
13
|
+
==========================
|
|
14
|
+
|
|
15
|
+
**BREAKING CHANGES**:
|
|
16
|
+
- Minimum Python version raised to 3.13
|
|
17
|
+
- Enumerations refactored for type safety and consistency
|
|
18
|
+
|
|
19
|
+
Removed
|
|
20
|
+
-------
|
|
21
|
+
- **Python 3.9-3.12 Support**: Minimum Python version is now 3.13
|
|
22
|
+
|
|
23
|
+
Home Assistant has deprecated Python 3.12 support, making Python 3.13 the de facto minimum for this ecosystem.
|
|
24
|
+
|
|
25
|
+
Python 3.13 features and improvements:
|
|
26
|
+
|
|
27
|
+
- **Experimental free-threaded mode** (PEP 703): Optional GIL removal for true parallelism
|
|
28
|
+
- **JIT compiler** (PEP 744): Just-in-time compilation for performance improvements
|
|
29
|
+
- **Better error messages**: Enhanced suggestions for NameError, AttributeError, and import errors
|
|
30
|
+
- **Type system enhancements**: TypeVars with defaults (PEP 696), @deprecated decorator (PEP 702), ReadOnly TypedDict (PEP 705)
|
|
31
|
+
- **Performance**: ~5-10% faster overall, optimized dictionary/set operations, better function calls
|
|
32
|
+
- PEP 695: New type parameter syntax for generics
|
|
33
|
+
- PEP 701: f-string improvements
|
|
34
|
+
- Built-in ``datetime.UTC`` constant
|
|
35
|
+
|
|
36
|
+
If you need Python 3.12 support, use version 6.1.x of this library.
|
|
37
|
+
|
|
38
|
+
- **CommandCode moved**: Import from ``nwp500.enums`` instead of ``nwp500.constants``
|
|
39
|
+
|
|
40
|
+
.. code-block:: python
|
|
41
|
+
|
|
42
|
+
# OLD (removed)
|
|
43
|
+
from nwp500.constants import CommandCode
|
|
44
|
+
|
|
45
|
+
# NEW
|
|
46
|
+
from nwp500.enums import CommandCode
|
|
47
|
+
# OR
|
|
48
|
+
from nwp500 import CommandCode # Still works
|
|
49
|
+
|
|
50
|
+
Added
|
|
51
|
+
-----
|
|
52
|
+
|
|
53
|
+
- **Python 3.12+ Optimizations**: Leverage latest Python features
|
|
54
|
+
|
|
55
|
+
- PEP 695: New type parameter syntax (``def func[T](...)`` instead of ``TypeVar``)
|
|
56
|
+
- Use ``datetime.UTC`` constant instead of ``datetime.timezone.utc``
|
|
57
|
+
- Native union syntax (``X | Y`` instead of ``Union[X, Y]``)
|
|
58
|
+
- Cleaner generic type annotations throughout codebase
|
|
59
|
+
|
|
60
|
+
- **Enumerations Module (``src/nwp500/enums.py``)**: Comprehensive type-safe enums for device control and status
|
|
61
|
+
|
|
62
|
+
- Status value enums: ``OnOffFlag``, ``Operation``, ``DhwOperationSetting``, ``CurrentOperationMode``, ``HeatSource``, ``DREvent``, ``WaterLevel``, ``FilterChange``, ``RecirculationMode``
|
|
63
|
+
- Time of Use enums: ``TouWeekType``, ``TouRateType``
|
|
64
|
+
- Device capability enums: ``CapabilityFlag``, ``TemperatureType``, ``DeviceType``
|
|
65
|
+
- Device control command enum: ``CommandCode`` (all MQTT command codes)
|
|
66
|
+
- Error code enum: ``ErrorCode`` with complete error code mappings
|
|
67
|
+
- Human-readable text mappings for all enums (e.g., ``DHW_OPERATION_SETTING_TEXT``, ``ERROR_CODE_TEXT``)
|
|
68
|
+
- Exported from main package: ``from nwp500 import OnOffFlag, ErrorCode, CommandCode``
|
|
69
|
+
- Comprehensive documentation in ``docs/enumerations.rst``
|
|
70
|
+
- Example usage in ``examples/error_code_demo.py``
|
|
71
|
+
|
|
72
|
+
Changed
|
|
73
|
+
-------
|
|
74
|
+
|
|
75
|
+
- **Command Code Constants**: Migrated from ``constants.py`` to ``CommandCode`` enum in ``enums.py``
|
|
76
|
+
|
|
77
|
+
- ``ANTI_LEGIONELLA_ENABLE`` → ``CommandCode.ANTI_LEGIONELLA_ON``
|
|
78
|
+
- ``ANTI_LEGIONELLA_DISABLE`` → ``CommandCode.ANTI_LEGIONELLA_OFF``
|
|
79
|
+
- ``TOU_ENABLE`` → ``CommandCode.TOU_ON``
|
|
80
|
+
- ``TOU_DISABLE`` → ``CommandCode.TOU_OFF``
|
|
81
|
+
- ``TOU_SETTINGS`` → ``CommandCode.TOU_RESERVATION``
|
|
82
|
+
- All command constants now use consistent naming in ``CommandCode`` enum
|
|
83
|
+
|
|
84
|
+
- **Model Enumerations**: Updated type annotations for clarity and type safety
|
|
85
|
+
|
|
86
|
+
- ``TemperatureUnit`` → ``TemperatureType`` (matches device protocol field names)
|
|
87
|
+
- All capability flags (e.g., ``power_use``, ``dhw_use``) now use ``CapabilityFlag`` type
|
|
88
|
+
- ``MqttRequest.device_type`` now accepts ``Union[DeviceType, int]`` for flexibility
|
|
89
|
+
|
|
90
|
+
- **Model Serialization**: Enums automatically serialize to human-readable names
|
|
91
|
+
|
|
92
|
+
- `model_dump()` converts enums to names (e.g., `DhwOperationSetting.HEAT_PUMP` → `"HEAT_PUMP"`)
|
|
93
|
+
- CLI and other consumers benefit from automatic enum name serialization
|
|
94
|
+
- Text mappings available for custom formatting (e.g., `DHW_OPERATION_TEXT[enum]` → "Heat Pump Only")
|
|
95
|
+
|
|
96
|
+
- **Documentation**: Comprehensive updates across protocol and API documentation
|
|
97
|
+
|
|
98
|
+
- ``docs/guides/time_of_use.rst``: Clarified TOU override status behavior (1=OFF/override active, 2=ON/normal operation)
|
|
99
|
+
- ``docs/protocol/data_conversions.rst``: Updated TOU field descriptions with correct enum values
|
|
100
|
+
- ``docs/protocol/device_features.rst``: Added capability flag pattern explanation (2=supported, 1=not supported)
|
|
101
|
+
- ``docs/protocol/mqtt_protocol.rst``: Updated command code references to use new enum names
|
|
102
|
+
- ``docs/python_api/models.rst``: Updated model field type annotations
|
|
103
|
+
|
|
104
|
+
- **Examples**: Updated to use new enums for type-safe device control
|
|
105
|
+
|
|
106
|
+
- ``examples/anti_legionella_example.py``: Uses ``CommandCode`` enum
|
|
107
|
+
- ``examples/device_feature_callback.py``: Uses capability enums
|
|
108
|
+
- ``examples/event_emitter_demo.py``: Uses status enums
|
|
109
|
+
- ``examples/mqtt_diagnostics_example.py``: Uses command enums
|
|
110
|
+
|
|
111
|
+
- **CLI Code Cleanup**: Refactored JSON formatting to use shared utility function
|
|
112
|
+
|
|
113
|
+
- Extracted repeated `json.dumps()` calls to `format_json_output()` helper
|
|
114
|
+
- Cleaner code with consistent formatting across all commands
|
|
115
|
+
|
|
116
|
+
Fixed
|
|
117
|
+
-----
|
|
118
|
+
|
|
119
|
+
- **Temperature Conversion Test**: Corrected ``test_device_status_div10`` to use ``HalfCelsiusToF`` conversion (100 → 122°F, not 50.0)
|
|
120
|
+
- **Documentation**: Fixed references to non-existent ``OperationMode`` enum - replaced with correct ``DhwOperationSetting`` and ``CurrentOperationMode`` enums
|
|
121
|
+
|
|
5
122
|
Version 6.1.1 (2025-12-08)
|
|
6
123
|
==========================
|
|
7
124
|
|
|
@@ -238,7 +355,7 @@ Quick Example
|
|
|
238
355
|
|
|
239
356
|
# OLD boolean and enum handling
|
|
240
357
|
is_heating = converted["currentHeatUse"] == 2
|
|
241
|
-
mode =
|
|
358
|
+
mode = OperationMode(converted["operationMode"]) if converted["operationMode"] in (0,32,64,96) else OperationMode.STANDBY
|
|
242
359
|
|
|
243
360
|
# NEW simplified
|
|
244
361
|
is_heating = status.current_heat_use
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nwp500-python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0.1
|
|
4
4
|
Summary: A library for controlling Navien NWP500 Water Heaters via NaviLink
|
|
5
5
|
Home-page: https://github.com/eman/nwp500-python
|
|
6
6
|
Author: Emmanuel Levijarvi
|
|
@@ -13,17 +13,13 @@ Platform: any
|
|
|
13
13
|
Classifier: Development Status :: 4 - Beta
|
|
14
14
|
Classifier: Programming Language :: Python
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
20
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
21
17
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.13
|
|
23
19
|
Description-Content-Type: text/x-rst; charset=UTF-8
|
|
24
20
|
License-File: LICENSE.txt
|
|
25
21
|
Requires-Dist: aiohttp>=3.8.0
|
|
26
|
-
Requires-Dist: awsiotsdk>=1.
|
|
22
|
+
Requires-Dist: awsiotsdk>=1.27.0
|
|
27
23
|
Requires-Dist: pydantic>=2.0.0
|
|
28
24
|
Provides-Extra: testing
|
|
29
25
|
Requires-Dist: setuptools; extra == "testing"
|
|
@@ -215,12 +211,10 @@ The library includes type-safe data models with automatic unit conversions:
|
|
|
215
211
|
Requirements
|
|
216
212
|
============
|
|
217
213
|
|
|
218
|
-
* Python 3.
|
|
214
|
+
* Python 3.13+
|
|
219
215
|
* aiohttp >= 3.8.0
|
|
220
|
-
* websockets >= 10.0
|
|
221
|
-
* cryptography >= 3.4.0
|
|
222
216
|
* pydantic >= 2.0.0
|
|
223
|
-
* awsiotsdk >= 1.
|
|
217
|
+
* awsiotsdk >= 1.27.0
|
|
224
218
|
|
|
225
219
|
License
|
|
226
220
|
=======
|
|
@@ -175,12 +175,10 @@ The library includes type-safe data models with automatic unit conversions:
|
|
|
175
175
|
Requirements
|
|
176
176
|
============
|
|
177
177
|
|
|
178
|
-
* Python 3.
|
|
178
|
+
* Python 3.13+
|
|
179
179
|
* aiohttp >= 3.8.0
|
|
180
|
-
* websockets >= 10.0
|
|
181
|
-
* cryptography >= 3.4.0
|
|
182
180
|
* pydantic >= 2.0.0
|
|
183
|
-
* awsiotsdk >= 1.
|
|
181
|
+
* awsiotsdk >= 1.27.0
|
|
184
182
|
|
|
185
183
|
License
|
|
186
184
|
=======
|
|
@@ -18,7 +18,7 @@ providing:
|
|
|
18
18
|
- Automatic reconnection with exponential backoff
|
|
19
19
|
- Command queuing for reliable communication
|
|
20
20
|
- Historical energy usage data (EMS API)
|
|
21
|
-
- Modern Python 3.
|
|
21
|
+
- Modern Python 3.13+ codebase with native type hints
|
|
22
22
|
|
|
23
23
|
Current Status
|
|
24
24
|
--------------
|
|
@@ -38,7 +38,7 @@ The library is feature-complete with:
|
|
|
38
38
|
- Comprehensive documentation
|
|
39
39
|
- Working examples for all features
|
|
40
40
|
- Unit tests with good coverage
|
|
41
|
-
- Python 3.
|
|
41
|
+
- Python 3.13+ with modern type hints
|
|
42
42
|
|
|
43
43
|
Implementation Milestones
|
|
44
44
|
-------------------------
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
Enumerations Reference
|
|
2
|
+
======================
|
|
3
|
+
|
|
4
|
+
This document provides a comprehensive reference for all enumerations used in
|
|
5
|
+
the Navien NWP500 protocol.
|
|
6
|
+
|
|
7
|
+
Device Control Commands
|
|
8
|
+
-----------------------
|
|
9
|
+
|
|
10
|
+
.. autoclass:: nwp500.enums.CommandCode
|
|
11
|
+
:members:
|
|
12
|
+
:undoc-members:
|
|
13
|
+
|
|
14
|
+
These command IDs are used in MQTT control messages to change device settings
|
|
15
|
+
and trigger actions. The most commonly used commands include:
|
|
16
|
+
|
|
17
|
+
- **Power Control**: ``POWER_ON``, ``POWER_OFF``
|
|
18
|
+
- **Temperature**: ``DHW_TEMPERATURE``
|
|
19
|
+
- **Operation Mode**: ``DHW_MODE``
|
|
20
|
+
- **TOU**: ``TOU_ON``, ``TOU_OFF``
|
|
21
|
+
- **Maintenance**: ``AIR_FILTER_RESET``, ``ANTI_LEGIONELLA_ON``
|
|
22
|
+
|
|
23
|
+
Example usage::
|
|
24
|
+
|
|
25
|
+
from nwp500 import CommandCode
|
|
26
|
+
|
|
27
|
+
# Send temperature command
|
|
28
|
+
command = CommandCode.DHW_TEMPERATURE
|
|
29
|
+
params = [120] # 60°C in half-degree units
|
|
30
|
+
|
|
31
|
+
Status Value Enumerations
|
|
32
|
+
--------------------------
|
|
33
|
+
|
|
34
|
+
OnOffFlag
|
|
35
|
+
~~~~~~~~~
|
|
36
|
+
|
|
37
|
+
.. autoclass:: nwp500.enums.OnOffFlag
|
|
38
|
+
:members:
|
|
39
|
+
:undoc-members:
|
|
40
|
+
|
|
41
|
+
Generic on/off flag used throughout status fields for power status, TOU status,
|
|
42
|
+
recirculation status, vacation mode, anti-legionella, and other boolean settings.
|
|
43
|
+
|
|
44
|
+
**Note**: Device uses ``1=OFF, 2=ON`` (not standard 0/1 boolean).
|
|
45
|
+
|
|
46
|
+
Operation
|
|
47
|
+
~~~~~~~~~
|
|
48
|
+
|
|
49
|
+
.. autoclass:: nwp500.enums.Operation
|
|
50
|
+
:members:
|
|
51
|
+
:undoc-members:
|
|
52
|
+
|
|
53
|
+
Device operation state indicating overall device activity.
|
|
54
|
+
|
|
55
|
+
DhwOperationSetting
|
|
56
|
+
~~~~~~~~~~~~~~~~~~~
|
|
57
|
+
|
|
58
|
+
.. autoclass:: nwp500.enums.DhwOperationSetting
|
|
59
|
+
:members:
|
|
60
|
+
:undoc-members:
|
|
61
|
+
|
|
62
|
+
User-configured DHW heating mode preference. This determines which heat source(s)
|
|
63
|
+
the device will use when heating is needed:
|
|
64
|
+
|
|
65
|
+
- **HEAT_PUMP**: Most efficient but slower heating
|
|
66
|
+
- **ELECTRIC**: Fastest but uses most energy
|
|
67
|
+
- **ENERGY_SAVER**: Hybrid mode - balanced efficiency
|
|
68
|
+
- **HIGH_DEMAND**: Hybrid mode - maximum heating capacity
|
|
69
|
+
- **VACATION**: Energy-saving mode for extended absences
|
|
70
|
+
- **POWER_OFF**: Device powered off
|
|
71
|
+
|
|
72
|
+
Example::
|
|
73
|
+
|
|
74
|
+
from nwp500 import DhwOperationSetting
|
|
75
|
+
from nwp500.enums import DHW_OPERATION_SETTING_TEXT
|
|
76
|
+
|
|
77
|
+
mode = DhwOperationSetting.ENERGY_SAVER
|
|
78
|
+
print(f"Current mode: {DHW_OPERATION_SETTING_TEXT[mode]}") # "Hybrid: Efficiency"
|
|
79
|
+
|
|
80
|
+
CurrentOperationMode
|
|
81
|
+
~~~~~~~~~~~~~~~~~~~~
|
|
82
|
+
|
|
83
|
+
.. autoclass:: nwp500.enums.CurrentOperationMode
|
|
84
|
+
:members:
|
|
85
|
+
:undoc-members:
|
|
86
|
+
|
|
87
|
+
Real-time operational state (read-only). This reflects what the device is actually
|
|
88
|
+
doing right now, which may differ from the configured mode setting:
|
|
89
|
+
|
|
90
|
+
- **STANDBY**: Device idle, not actively heating
|
|
91
|
+
- **HEAT_PUMP_MODE**: Heat pump actively running
|
|
92
|
+
- **HYBRID_EFFICIENCY_MODE**: Actively heating in Energy Saver mode
|
|
93
|
+
- **HYBRID_BOOST_MODE**: Actively heating in High Demand mode
|
|
94
|
+
|
|
95
|
+
Example::
|
|
96
|
+
|
|
97
|
+
from nwp500 import CurrentOperationMode
|
|
98
|
+
from nwp500.enums import CURRENT_OPERATION_MODE_TEXT
|
|
99
|
+
|
|
100
|
+
mode = CurrentOperationMode.HEAT_PUMP_MODE
|
|
101
|
+
print(f"Device state: {CURRENT_OPERATION_MODE_TEXT[mode]}") # "Heat Pump"
|
|
102
|
+
|
|
103
|
+
HeatSource
|
|
104
|
+
~~~~~~~~~~
|
|
105
|
+
|
|
106
|
+
.. autoclass:: nwp500.enums.HeatSource
|
|
107
|
+
:members:
|
|
108
|
+
:undoc-members:
|
|
109
|
+
|
|
110
|
+
Currently active heat source (read-only status). This reflects what the device
|
|
111
|
+
is *currently* using, not what mode it's set to. In Hybrid mode, this field
|
|
112
|
+
shows which heat source(s) are active at any moment.
|
|
113
|
+
|
|
114
|
+
DREvent
|
|
115
|
+
~~~~~~~
|
|
116
|
+
|
|
117
|
+
.. autoclass:: nwp500.enums.DREvent
|
|
118
|
+
:members:
|
|
119
|
+
:undoc-members:
|
|
120
|
+
|
|
121
|
+
Demand Response event status. Allows utilities to manage grid load by signaling
|
|
122
|
+
water heaters to reduce consumption (shed) or pre-heat (load up) before peak periods.
|
|
123
|
+
|
|
124
|
+
WaterLevel
|
|
125
|
+
~~~~~~~~~~
|
|
126
|
+
|
|
127
|
+
.. autoclass:: nwp500.enums.WaterLevel
|
|
128
|
+
:members:
|
|
129
|
+
:undoc-members:
|
|
130
|
+
|
|
131
|
+
Hot water level indicator displayed as gauge in app. IDs are non-sequential,
|
|
132
|
+
likely represent bit positions for multi-level displays.
|
|
133
|
+
|
|
134
|
+
FilterChange
|
|
135
|
+
~~~~~~~~~~~~
|
|
136
|
+
|
|
137
|
+
.. autoclass:: nwp500.enums.FilterChange
|
|
138
|
+
:members:
|
|
139
|
+
:undoc-members:
|
|
140
|
+
|
|
141
|
+
Air filter status for heat pump models. Indicates when air filter maintenance
|
|
142
|
+
is needed.
|
|
143
|
+
|
|
144
|
+
RecirculationMode
|
|
145
|
+
~~~~~~~~~~~~~~~~~
|
|
146
|
+
|
|
147
|
+
.. autoclass:: nwp500.enums.RecirculationMode
|
|
148
|
+
:members:
|
|
149
|
+
:undoc-members:
|
|
150
|
+
|
|
151
|
+
Recirculation pump operation mode:
|
|
152
|
+
|
|
153
|
+
- **ALWAYS**: Pump continuously runs
|
|
154
|
+
- **BUTTON**: Manual activation only (hot button)
|
|
155
|
+
- **SCHEDULE**: Runs on configured schedule
|
|
156
|
+
- **TEMPERATURE**: Activates when pipe temp drops below setpoint
|
|
157
|
+
|
|
158
|
+
Time of Use (TOU) Enumerations
|
|
159
|
+
-------------------------------
|
|
160
|
+
|
|
161
|
+
TouWeekType
|
|
162
|
+
~~~~~~~~~~~
|
|
163
|
+
|
|
164
|
+
.. autoclass:: nwp500.enums.TouWeekType
|
|
165
|
+
:members:
|
|
166
|
+
:undoc-members:
|
|
167
|
+
|
|
168
|
+
Day grouping for TOU schedules. Allows separate schedules for weekdays and
|
|
169
|
+
weekends to account for different electricity rates and usage patterns.
|
|
170
|
+
|
|
171
|
+
TouRateType
|
|
172
|
+
~~~~~~~~~~~
|
|
173
|
+
|
|
174
|
+
.. autoclass:: nwp500.enums.TouRateType
|
|
175
|
+
:members:
|
|
176
|
+
:undoc-members:
|
|
177
|
+
|
|
178
|
+
Electricity rate period type. Device behavior can be configured for each period:
|
|
179
|
+
|
|
180
|
+
- **OFF_PEAK**: Lowest rates - device heats aggressively
|
|
181
|
+
- **MID_PEAK**: Medium rates - device heats normally
|
|
182
|
+
- **ON_PEAK**: Highest rates - device minimizes heating
|
|
183
|
+
|
|
184
|
+
Temperature and Unit Enumerations
|
|
185
|
+
----------------------------------
|
|
186
|
+
|
|
187
|
+
TemperatureType
|
|
188
|
+
~~~~~~~~~~~~~~~
|
|
189
|
+
|
|
190
|
+
.. autoclass:: nwp500.enums.TemperatureType
|
|
191
|
+
:members:
|
|
192
|
+
:undoc-members:
|
|
193
|
+
|
|
194
|
+
Temperature display unit preference (Celsius or Fahrenheit).
|
|
195
|
+
|
|
196
|
+
**Alias**: ``TemperatureUnit`` in models.py for backward compatibility.
|
|
197
|
+
|
|
198
|
+
TempFormulaType
|
|
199
|
+
~~~~~~~~~~~~~~~
|
|
200
|
+
|
|
201
|
+
.. autoclass:: nwp500.enums.TempFormulaType
|
|
202
|
+
:members:
|
|
203
|
+
:undoc-members:
|
|
204
|
+
|
|
205
|
+
Temperature conversion formula type. Different device models use slightly different
|
|
206
|
+
rounding algorithms when converting internal Celsius values to Fahrenheit:
|
|
207
|
+
|
|
208
|
+
- **ASYMMETRIC** (Type 0): Special rounding based on raw value remainder
|
|
209
|
+
- **STANDARD** (Type 1): Simple round to nearest integer
|
|
210
|
+
|
|
211
|
+
This ensures the mobile app matches the device's built-in display exactly.
|
|
212
|
+
|
|
213
|
+
Device Type Enumerations
|
|
214
|
+
-------------------------
|
|
215
|
+
|
|
216
|
+
UnitType
|
|
217
|
+
~~~~~~~~
|
|
218
|
+
|
|
219
|
+
.. autoclass:: nwp500.enums.UnitType
|
|
220
|
+
:members:
|
|
221
|
+
:undoc-members:
|
|
222
|
+
|
|
223
|
+
Navien device/unit model types. Common values:
|
|
224
|
+
|
|
225
|
+
- **NPF** (513): Heat pump water heater (primary model for this library)
|
|
226
|
+
- **NPE**: Tankless water heater
|
|
227
|
+
- **NCB**: Condensing boiler
|
|
228
|
+
- **NPN**: Condensing water heater
|
|
229
|
+
|
|
230
|
+
Values with ``CAS_`` prefix indicate cascading systems where multiple units
|
|
231
|
+
work together.
|
|
232
|
+
|
|
233
|
+
DeviceType
|
|
234
|
+
~~~~~~~~~~
|
|
235
|
+
|
|
236
|
+
.. autoclass:: nwp500.enums.DeviceType
|
|
237
|
+
:members:
|
|
238
|
+
:undoc-members:
|
|
239
|
+
|
|
240
|
+
Communication device type (WiFi module model).
|
|
241
|
+
|
|
242
|
+
FirmwareType
|
|
243
|
+
~~~~~~~~~~~~
|
|
244
|
+
|
|
245
|
+
.. autoclass:: nwp500.enums.FirmwareType
|
|
246
|
+
:members:
|
|
247
|
+
:undoc-members:
|
|
248
|
+
|
|
249
|
+
Firmware component types. Devices may have multiple firmware components that
|
|
250
|
+
can be updated independently.
|
|
251
|
+
|
|
252
|
+
Display Text Helpers
|
|
253
|
+
--------------------
|
|
254
|
+
|
|
255
|
+
The enums module also provides dictionaries for converting enum values to
|
|
256
|
+
user-friendly display text:
|
|
257
|
+
|
|
258
|
+
.. code-block:: python
|
|
259
|
+
|
|
260
|
+
from nwp500.enums import (
|
|
261
|
+
DHW_OPERATION_SETTING_TEXT,
|
|
262
|
+
CURRENT_OPERATION_MODE_TEXT,
|
|
263
|
+
HEAT_SOURCE_TEXT,
|
|
264
|
+
DR_EVENT_TEXT,
|
|
265
|
+
RECIRC_MODE_TEXT,
|
|
266
|
+
TOU_RATE_TEXT,
|
|
267
|
+
FILTER_STATUS_TEXT,
|
|
268
|
+
ERROR_CODE_TEXT,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
# Usage examples
|
|
272
|
+
from nwp500 import DhwOperationSetting, CurrentOperationMode, ErrorCode
|
|
273
|
+
|
|
274
|
+
# User-configured mode
|
|
275
|
+
mode = DhwOperationSetting.ENERGY_SAVER
|
|
276
|
+
print(DHW_OPERATION_SETTING_TEXT[mode]) # "Hybrid: Efficiency"
|
|
277
|
+
|
|
278
|
+
# Current operational state
|
|
279
|
+
state = CurrentOperationMode.HEAT_PUMP_MODE
|
|
280
|
+
print(CURRENT_OPERATION_MODE_TEXT[state]) # "Heat Pump"
|
|
281
|
+
|
|
282
|
+
# Error codes
|
|
283
|
+
error = ErrorCode.E407_DHW_TEMP_SENSOR
|
|
284
|
+
print(ERROR_CODE_TEXT[error]) # "Abnormal DHW Temperature Sensor"
|
|
285
|
+
|
|
286
|
+
Related Documentation
|
|
287
|
+
---------------------
|
|
288
|
+
|
|
289
|
+
For detailed protocol documentation, see:
|
|
290
|
+
|
|
291
|
+
- :doc:`protocol/device_status` - Status field definitions
|
|
292
|
+
- :doc:`guides/time_of_use` - TOU scheduling and rate types
|
|
293
|
+
- :doc:`protocol/control_commands` - Control command usage
|
|
@@ -914,11 +914,11 @@ The device status includes TOU-related fields:
|
|
|
914
914
|
|
|
915
915
|
{
|
|
916
916
|
"touStatus": 1,
|
|
917
|
-
"touOverrideStatus":
|
|
917
|
+
"touOverrideStatus": 2
|
|
918
918
|
}
|
|
919
919
|
|
|
920
|
-
* ``touStatus``: ``1`` if TOU scheduling is active, ``0`` if inactive
|
|
921
|
-
* ``touOverrideStatus``: ``1``
|
|
920
|
+
* ``touStatus``: ``1`` if TOU scheduling is enabled/active, ``0`` if disabled/inactive
|
|
921
|
+
* ``touOverrideStatus``: ``2`` (ON) = TOU schedule is operating normally, ``1`` (OFF) = user has overridden TOU to force immediate heating
|
|
922
922
|
|
|
923
923
|
See :doc:`../protocol/device_status` for more details.
|
|
924
924
|
|
|
@@ -5,7 +5,7 @@ Installation
|
|
|
5
5
|
Requirements
|
|
6
6
|
============
|
|
7
7
|
|
|
8
|
-
* Python 3.
|
|
8
|
+
* Python 3.13 or higher
|
|
9
9
|
* pip (Python package installer)
|
|
10
10
|
* Navien Smart Control account
|
|
11
11
|
|
|
@@ -51,7 +51,7 @@ Core Dependencies
|
|
|
51
51
|
The library requires:
|
|
52
52
|
|
|
53
53
|
* ``aiohttp>=3.8.0`` - Async HTTP client for REST API
|
|
54
|
-
* ``awsiotsdk>=1.
|
|
54
|
+
* ``awsiotsdk>=1.27.0`` - AWS IoT SDK for MQTT
|
|
55
55
|
* ``pydantic>=2.0.0`` - Data validation and models
|
|
56
56
|
|
|
57
57
|
Optional Dependencies
|
|
@@ -128,7 +128,7 @@ The MQTT client requires the AWS IoT SDK:
|
|
|
128
128
|
|
|
129
129
|
.. code-block:: bash
|
|
130
130
|
|
|
131
|
-
pip install awsiotsdk>=1.
|
|
131
|
+
pip install awsiotsdk>=1.27.0
|
|
132
132
|
|
|
133
133
|
Upgrading
|
|
134
134
|
=========
|
|
@@ -487,7 +487,7 @@ Vacation and Scheduling Fields
|
|
|
487
487
|
* - ``touStatus``
|
|
488
488
|
- None (direct value)
|
|
489
489
|
- See values below
|
|
490
|
-
- **Time-of-Use (TOU) schedule status**. 0=inactive, 1=active. Controls heating based on electricity rate periods.
|
|
490
|
+
- **Time-of-Use (TOU) schedule status**. 0 = inactive/disabled, 1 = active/enabled. Controls heating based on electricity rate periods.
|
|
491
491
|
* - ``drEventStatus``
|
|
492
492
|
- None (direct value)
|
|
493
493
|
- Bitfield
|
|
@@ -499,7 +499,7 @@ Vacation and Scheduling Fields
|
|
|
499
499
|
* - ``touOverrideStatus``
|
|
500
500
|
- None (direct value)
|
|
501
501
|
- See explanation
|
|
502
|
-
- **
|
|
502
|
+
- **TOU schedule operation status**. 1 (OFF) = user has overridden TOU to force immediate heating (override lasts up to 72 hours), 2 (ON) = TOU schedule is operating normally.
|
|
503
503
|
|
|
504
504
|
Network and Diagnostic Fields
|
|
505
505
|
-----------------------------
|