nwp500-python 6.0.4__tar.gz → 6.0.5__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.0.4 → nwp500_python-6.0.5}/.github/workflows/release.yml +16 -1
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/CHANGELOG.rst +30 -0
- {nwp500_python-6.0.4/src/nwp500_python.egg-info → nwp500_python-6.0.5}/PKG-INFO +1 -1
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/protocol/data_conversions.rst +13 -13
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/protocol/device_status.rst +8 -8
- nwp500_python-6.0.5/scripts/extract_changelog.py +43 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/models.py +13 -15
- {nwp500_python-6.0.4 → nwp500_python-6.0.5/src/nwp500_python.egg-info}/PKG-INFO +1 -1
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500_python.egg-info/SOURCES.txt +1 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/tests/test_models.py +4 -4
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/.agent/workflows/pre-completion-testing.md +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/.coveragerc +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/.github/copilot-instructions.md +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/.github/workflows/ci.yml +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/.gitignore +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/.pre-commit-config.yaml +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/.readthedocs.yml +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/AUTHORS.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/CONTRIBUTING.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/LICENSE.txt +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/Makefile +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/README.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/RELEASE.md +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/Makefile +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/_static/.gitignore +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/api/nwp500.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/authors.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/changelog.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/conf.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/configuration.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/development/contributing.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/development/history.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/guides/advanced_features_explained.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/guides/auto_recovery.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/guides/command_queue.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/guides/energy_monitoring.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/guides/event_system.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/guides/reservations.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/guides/scheduling_features.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/guides/time_of_use.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/index.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/installation.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/license.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/openapi.yaml +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/protocol/device_features.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/protocol/error_codes.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/protocol/firmware_tracking.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/protocol/mqtt_protocol.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/protocol/rest_api.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/python_api/api_client.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/python_api/auth_client.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/python_api/cli.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/python_api/constants.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/python_api/events.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/python_api/exceptions.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/python_api/models.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/python_api/mqtt_client.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/quickstart.rst +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/docs/requirements.txt +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/.ruff.toml +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/README.md +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/anti_legionella_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/api_client_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/auth_constructor_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/authenticate.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/auto_recovery_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/combined_callbacks.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/command_queue_demo.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/device_feature_callback.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/device_status_callback.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/device_status_callback_debug.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/energy_usage_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/event_emitter_demo.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/exception_handling_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/improved_auth_pattern.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/mask.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/mqtt_client_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/periodic_device_info.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/periodic_requests.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/power_control_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/reconnection_demo.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/reservation_schedule_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/set_dhw_temperature_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/set_mode_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/simple_auto_recovery.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/simple_periodic_info.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/simple_periodic_status.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/test_api_client.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/test_mqtt_connection.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/test_mqtt_messaging.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/test_periodic_minimal.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/token_restoration_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/tou_openei_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/examples/tou_schedule_example.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/pyproject.toml +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/scripts/README.md +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/scripts/bump_version.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/scripts/format.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/scripts/lint.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/scripts/setup-dev.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/scripts/validate_version.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/setup.cfg +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/setup.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/__init__.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/api_client.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/auth.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/cli/__init__.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/cli/__main__.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/cli/commands.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/cli/monitoring.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/cli/output_formatters.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/cli/token_storage.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/config.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/constants.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/encoding.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/events.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/exceptions.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/mqtt_client.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/mqtt_command_queue.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/mqtt_connection.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/mqtt_device_control.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/mqtt_periodic.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/mqtt_reconnection.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/mqtt_subscriptions.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/mqtt_utils.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/py.typed +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500/utils.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500_python.egg-info/dependency_links.txt +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500_python.egg-info/entry_points.txt +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500_python.egg-info/not-zip-safe +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500_python.egg-info/requires.txt +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/src/nwp500_python.egg-info/top_level.txt +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/tests/conftest.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/tests/test_api_helpers.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/tests/test_auth.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/tests/test_command_queue.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/tests/test_events.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/tests/test_exceptions.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/tests/test_utils.py +0 -0
- {nwp500_python-6.0.4 → nwp500_python-6.0.5}/tox.ini +0 -0
|
@@ -77,9 +77,24 @@ jobs:
|
|
|
77
77
|
steps:
|
|
78
78
|
- uses: actions/checkout@v4
|
|
79
79
|
|
|
80
|
+
- name: Set up Python
|
|
81
|
+
uses: actions/setup-python@v5
|
|
82
|
+
with:
|
|
83
|
+
python-version: '3.10'
|
|
84
|
+
|
|
85
|
+
- name: Extract changelog for this version
|
|
86
|
+
id: changelog
|
|
87
|
+
run: |
|
|
88
|
+
VERSION=${GITHUB_REF#refs/tags/v}
|
|
89
|
+
NOTES=$(python3 scripts/extract_changelog.py CHANGELOG.rst "$VERSION")
|
|
90
|
+
# Use multiline output format for GitHub Actions
|
|
91
|
+
echo "notes<<EOF" >> $GITHUB_OUTPUT
|
|
92
|
+
echo "$NOTES" >> $GITHUB_OUTPUT
|
|
93
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
94
|
+
|
|
80
95
|
- name: Create Release
|
|
81
96
|
uses: softprops/action-gh-release@v1
|
|
82
97
|
with:
|
|
83
|
-
|
|
98
|
+
body: ${{ steps.changelog.outputs.notes }}
|
|
84
99
|
draft: false
|
|
85
100
|
prerelease: false
|
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
Version 6.0.5 (2025-11-21)
|
|
6
|
+
==========================
|
|
7
|
+
|
|
8
|
+
Fixed
|
|
9
|
+
-----
|
|
10
|
+
|
|
11
|
+
- **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:
|
|
12
|
+
|
|
13
|
+
- ``tank_upper_temperature`` - Water tank upper sensor
|
|
14
|
+
- ``tank_lower_temperature`` - Water tank lower sensor
|
|
15
|
+
- ``discharge_temperature`` - Compressor discharge temperature (refrigerant)
|
|
16
|
+
- ``suction_temperature`` - Compressor suction temperature (refrigerant)
|
|
17
|
+
- ``evaporator_temperature`` - Evaporator coil temperature (refrigerant)
|
|
18
|
+
- ``ambient_temperature`` - Ambient air temperature at heat pump
|
|
19
|
+
- ``target_super_heat`` - Target superheat setpoint
|
|
20
|
+
- ``current_super_heat`` - Measured superheat value
|
|
21
|
+
|
|
22
|
+
**Impact**: These fields now correctly display temperatures in expected ranges:
|
|
23
|
+
|
|
24
|
+
- Tank temperatures: ~120°F (close to DHW temperature, not ~220°F)
|
|
25
|
+
- Discharge temperature: 120-180°F (not 220-280°F)
|
|
26
|
+
- Suction, evaporator, ambient: Now showing physically realistic values
|
|
27
|
+
|
|
28
|
+
**Technical details**: Changed from ``PentaCelsiusToF`` (÷5) back to ``DeciCelsiusToF`` (÷10). The correct formula is ``(raw_value / 10.0) * 9/5 + 32``.
|
|
29
|
+
|
|
30
|
+
Changed
|
|
31
|
+
-------
|
|
32
|
+
|
|
33
|
+
- **Documentation**: Updated ``data_conversions.rst`` and ``device_status.rst`` to reflect correct ``DeciCelsiusToF`` conversion for refrigerant circuit and tank temperature sensors
|
|
34
|
+
|
|
5
35
|
Version 6.0.4 (2025-11-21)
|
|
6
36
|
==========================
|
|
7
37
|
|
|
@@ -24,11 +24,11 @@ The device uses several encoding schemes to minimize transmission overhead:
|
|
|
24
24
|
- Purpose: Converts raw values, which are in half-degrees Celsius, to Fahrenheit.
|
|
25
25
|
- Example: Raw 122 -> (122 / 2) * 9/5 + 32 = 141.8°F
|
|
26
26
|
|
|
27
|
-
2. **
|
|
28
|
-
- Applied to refrigerant and
|
|
29
|
-
- Formula: ``displayed_value = (raw_value /
|
|
30
|
-
- Purpose: Converts raw values, which are
|
|
31
|
-
- Example: Raw
|
|
27
|
+
2. **Decicelsius to Fahrenheit** (DeciCelsiusToF)
|
|
28
|
+
- Applied to refrigerant circuit and tank temperature sensors.
|
|
29
|
+
- Formula: ``displayed_value = (raw_value / 10.0) * 9/5 + 32``
|
|
30
|
+
- Purpose: Converts raw values, which are in tenths of degrees Celsius, to Fahrenheit.
|
|
31
|
+
- Example: Raw 489 -> (489 / 10) * 9/5 + 32 = 120.0°F
|
|
32
32
|
|
|
33
33
|
3. **Tenths Encoding** (div_10)
|
|
34
34
|
- Applied to decimal precision values
|
|
@@ -97,11 +97,11 @@ Tank Temperature Sensors
|
|
|
97
97
|
- Display Unit
|
|
98
98
|
- Description
|
|
99
99
|
* - ``tankUpperTemperature``
|
|
100
|
-
-
|
|
100
|
+
- DeciCelsiusToF
|
|
101
101
|
- °F
|
|
102
102
|
- **Upper tank sensor temperature**. Indicates stratification - hot water at top for quick delivery. Typically hottest point in tank.
|
|
103
103
|
* - ``tankLowerTemperature``
|
|
104
|
-
-
|
|
104
|
+
- DeciCelsiusToF
|
|
105
105
|
- °F
|
|
106
106
|
- **Lower tank sensor temperature**. Indicates bulk tank temperature and heating progress. Typically cooler than upper sensor.
|
|
107
107
|
|
|
@@ -121,27 +121,27 @@ These temperatures monitor the heat pump refrigerant circuit health and performa
|
|
|
121
121
|
- Display Unit
|
|
122
122
|
- Description
|
|
123
123
|
* - ``dischargeTemperature``
|
|
124
|
-
-
|
|
124
|
+
- DeciCelsiusToF
|
|
125
125
|
- °F
|
|
126
126
|
- **Compressor discharge temperature**. Temperature of refrigerant exiting the compressor. Typically 120-180°F. High values indicate high system pressure; low values indicate efficiency issues.
|
|
127
127
|
* - ``suctionTemperature``
|
|
128
|
-
-
|
|
128
|
+
- DeciCelsiusToF
|
|
129
129
|
- °F
|
|
130
130
|
- **Compressor suction temperature**. Temperature of refrigerant entering the compressor. Typically 40-60°F. Affects superheat calculation.
|
|
131
131
|
* - ``evaporatorTemperature``
|
|
132
|
-
-
|
|
132
|
+
- DeciCelsiusToF
|
|
133
133
|
- °F
|
|
134
134
|
- **Evaporator coil temperature**. Where heat is extracted from ambient air. Typically 20-50°F. Lower outdoor air temperature reduces evaporator efficiency.
|
|
135
135
|
* - ``ambientTemperature``
|
|
136
|
-
-
|
|
136
|
+
- DeciCelsiusToF
|
|
137
137
|
- °F
|
|
138
138
|
- **Ambient air temperature** measured at heat pump inlet. Directly affects system performance. At freezing (32°F), heat pump efficiency drops significantly.
|
|
139
139
|
* - ``targetSuperHeat``
|
|
140
|
-
-
|
|
140
|
+
- DeciCelsiusToF
|
|
141
141
|
- °F
|
|
142
142
|
- **Target superheat setpoint**. Desired temperature difference between suction and evaporator ensuring complete refrigerant vaporization. Typically 10-20°F.
|
|
143
143
|
* - ``currentSuperHeat``
|
|
144
|
-
-
|
|
144
|
+
- DeciCelsiusToF
|
|
145
145
|
- °F
|
|
146
146
|
- **Measured superheat value**. Actual temperature difference. Deviation from target indicates EEV (Electronic Expansion Valve) control issues.
|
|
147
147
|
|
|
@@ -122,37 +122,37 @@ This document lists the fields found in the ``status`` object of device status m
|
|
|
122
122
|
- integer
|
|
123
123
|
- °F
|
|
124
124
|
- Temperature of the upper part of the tank.
|
|
125
|
-
-
|
|
125
|
+
- DeciCelsiusToF
|
|
126
126
|
* - ``tankLowerTemperature``
|
|
127
127
|
- integer
|
|
128
128
|
- °F
|
|
129
129
|
- Temperature of the lower part of the tank.
|
|
130
|
-
-
|
|
130
|
+
- DeciCelsiusToF
|
|
131
131
|
* - ``dischargeTemperature``
|
|
132
132
|
- integer
|
|
133
133
|
- °F
|
|
134
134
|
- Compressor discharge temperature - temperature of refrigerant leaving the compressor.
|
|
135
|
-
-
|
|
135
|
+
- DeciCelsiusToF
|
|
136
136
|
* - ``suctionTemperature``
|
|
137
137
|
- integer
|
|
138
138
|
- °F
|
|
139
139
|
- Compressor suction temperature - temperature of refrigerant entering the compressor.
|
|
140
|
-
-
|
|
140
|
+
- DeciCelsiusToF
|
|
141
141
|
* - ``evaporatorTemperature``
|
|
142
142
|
- integer
|
|
143
143
|
- °F
|
|
144
144
|
- Evaporator temperature - temperature where heat is absorbed from ambient air.
|
|
145
|
-
-
|
|
145
|
+
- DeciCelsiusToF
|
|
146
146
|
* - ``ambientTemperature``
|
|
147
147
|
- integer
|
|
148
148
|
- °F
|
|
149
149
|
- Ambient air temperature measured at the heat pump air intake.
|
|
150
|
-
-
|
|
150
|
+
- DeciCelsiusToF
|
|
151
151
|
* - ``targetSuperHeat``
|
|
152
152
|
- integer
|
|
153
153
|
- °F
|
|
154
154
|
- Target superheat value - the desired temperature difference ensuring complete refrigerant vaporization.
|
|
155
|
-
-
|
|
155
|
+
- DeciCelsiusToF
|
|
156
156
|
* - ``compUse``
|
|
157
157
|
- bool
|
|
158
158
|
- None
|
|
@@ -307,7 +307,7 @@ This document lists the fields found in the ``status`` object of device status m
|
|
|
307
307
|
- integer
|
|
308
308
|
- °F
|
|
309
309
|
- Current superheat value - actual temperature difference between suction and evaporator temperatures.
|
|
310
|
-
-
|
|
310
|
+
- DeciCelsiusToF
|
|
311
311
|
* - ``heatUpperUse``
|
|
312
312
|
- bool
|
|
313
313
|
- None
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Extract release notes from CHANGELOG.rst for a specific version."""
|
|
3
|
+
|
|
4
|
+
import re
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def extract_version_notes(changelog_path: str, version: str) -> str:
|
|
9
|
+
"""
|
|
10
|
+
Extract the changelog section for a specific version.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
changelog_path: Path to CHANGELOG.rst
|
|
14
|
+
version: Version string (e.g., "6.0.4")
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
The changelog content for that version
|
|
18
|
+
"""
|
|
19
|
+
with open(changelog_path, "r") as f:
|
|
20
|
+
content = f.read()
|
|
21
|
+
|
|
22
|
+
# Match the version header and capture everything until the next version
|
|
23
|
+
# Pattern: "Version X.Y.Z (DATE)" followed by "===" line
|
|
24
|
+
version_pattern = rf"Version {re.escape(version)} \([^)]+\)\n=+\n(.*?)(?=\nVersion \d+\.\d+\.\d+ \([^)]+\)\n=+|$)"
|
|
25
|
+
|
|
26
|
+
match = re.search(version_pattern, content, re.DOTALL)
|
|
27
|
+
if not match:
|
|
28
|
+
return f"Release {version}"
|
|
29
|
+
|
|
30
|
+
notes = match.group(1).strip()
|
|
31
|
+
return notes
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
if __name__ == "__main__":
|
|
35
|
+
if len(sys.argv) != 3:
|
|
36
|
+
print("Usage: extract_changelog.py <changelog_path> <version>")
|
|
37
|
+
sys.exit(1)
|
|
38
|
+
|
|
39
|
+
changelog_path = sys.argv[1]
|
|
40
|
+
version = sys.argv[2].lstrip("v") # Remove 'v' prefix if present
|
|
41
|
+
|
|
42
|
+
notes = extract_version_notes(changelog_path, version)
|
|
43
|
+
print(notes)
|
|
@@ -41,10 +41,10 @@ def _half_celsius_to_fahrenheit(v: Any) -> float:
|
|
|
41
41
|
return float(v)
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
def
|
|
45
|
-
"""Convert
|
|
44
|
+
def _deci_celsius_to_fahrenheit(v: Any) -> float:
|
|
45
|
+
"""Convert decicelsius (tenths of Celsius) to Fahrenheit."""
|
|
46
46
|
if isinstance(v, (int, float)):
|
|
47
|
-
celsius = float(v) /
|
|
47
|
+
celsius = float(v) / 10.0
|
|
48
48
|
return (celsius * 9 / 5) + 32
|
|
49
49
|
return float(v)
|
|
50
50
|
|
|
@@ -53,9 +53,7 @@ def _penta_celsius_to_fahrenheit(v: Any) -> float:
|
|
|
53
53
|
DeviceBool = Annotated[bool, BeforeValidator(_device_bool_validator)]
|
|
54
54
|
Div10 = Annotated[float, BeforeValidator(_div_10_validator)]
|
|
55
55
|
HalfCelsiusToF = Annotated[float, BeforeValidator(_half_celsius_to_fahrenheit)]
|
|
56
|
-
|
|
57
|
-
float, BeforeValidator(_penta_celsius_to_fahrenheit)
|
|
58
|
-
]
|
|
56
|
+
DeciCelsiusToF = Annotated[float, BeforeValidator(_deci_celsius_to_fahrenheit)]
|
|
59
57
|
|
|
60
58
|
|
|
61
59
|
class NavienBaseModel(BaseModel):
|
|
@@ -289,15 +287,15 @@ class DeviceStatus(NavienBaseModel):
|
|
|
289
287
|
he_lower_off_diff_temp_setting: Div10
|
|
290
288
|
recirc_dhw_flow_rate: Div10
|
|
291
289
|
|
|
292
|
-
# Temperature fields with
|
|
293
|
-
tank_upper_temperature:
|
|
294
|
-
tank_lower_temperature:
|
|
295
|
-
discharge_temperature:
|
|
296
|
-
suction_temperature:
|
|
297
|
-
evaporator_temperature:
|
|
298
|
-
ambient_temperature:
|
|
299
|
-
target_super_heat:
|
|
300
|
-
current_super_heat:
|
|
290
|
+
# Temperature fields with decicelsius (÷10) to Fahrenheit conversion
|
|
291
|
+
tank_upper_temperature: DeciCelsiusToF
|
|
292
|
+
tank_lower_temperature: DeciCelsiusToF
|
|
293
|
+
discharge_temperature: DeciCelsiusToF
|
|
294
|
+
suction_temperature: DeciCelsiusToF
|
|
295
|
+
evaporator_temperature: DeciCelsiusToF
|
|
296
|
+
ambient_temperature: DeciCelsiusToF
|
|
297
|
+
target_super_heat: DeciCelsiusToF
|
|
298
|
+
current_super_heat: DeciCelsiusToF
|
|
301
299
|
|
|
302
300
|
# Enum fields
|
|
303
301
|
operation_mode: CurrentOperationMode = Field(
|
|
@@ -118,11 +118,11 @@ def test_device_status_half_celsius_to_fahrenheit(default_status_data):
|
|
|
118
118
|
assert status.dhw_temperature == pytest.approx(141.8)
|
|
119
119
|
|
|
120
120
|
|
|
121
|
-
def
|
|
122
|
-
"""Test
|
|
123
|
-
default_status_data["tankUpperTemperature"] =
|
|
121
|
+
def test_device_status_deci_celsius_to_fahrenheit(default_status_data):
|
|
122
|
+
"""Test DeciCelsiusToF conversion."""
|
|
123
|
+
default_status_data["tankUpperTemperature"] = 489
|
|
124
124
|
status = DeviceStatus.model_validate(default_status_data)
|
|
125
|
-
assert status.tank_upper_temperature == pytest.approx(
|
|
125
|
+
assert status.tank_upper_temperature == pytest.approx(120.0, abs=0.1)
|
|
126
126
|
|
|
127
127
|
|
|
128
128
|
def test_device_status_div10(default_status_data):
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|