Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@
Changelog
=========

Version 7.3.4 (2026-01-27)
==========================

Fixed
-----
- **Temperature Delta Conversions**: Fixed incorrect Fahrenheit conversion for differential temperature settings (heat pump and heater element on/off thresholds)

- Created new ``DeciCelsiusDelta`` class for temperature deltas that apply scale factor (9/5) but NOT the +32 offset
- Heat pump and heater element differential settings now use ``DeciCelsiusDelta`` instead of ``DeciCelsius``
- ``hp_upper_on_diff_temp_setting``, ``hp_lower_on_diff_temp_setting``, ``he_upper_on_diff_temp_setting``, ``he_lower_on_diff_temp_setting``, and related off settings now convert correctly to Fahrenheit
- Example: A device value of 5 (representing 0.5°C delta) now correctly converts to 0.9°F delta instead of 32.9°F

- **CLI Output**: Added display of heat pump and heater element differential temperature settings in device status output

Changed
-------
- **Internal API**: Added ``div_10_celsius_delta_to_preferred`` converter for temperature delta values in device models


Version 7.3.3 (2026-01-27)
==========================

Expand Down
8 changes: 8 additions & 0 deletions docs/api/nwp500.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ nwp500.topic\_builder module
:show-inheritance:
:undoc-members:

nwp500.unit\_system module
--------------------------

.. automodule:: nwp500.unit_system
:members:
:show-inheritance:
:undoc-members:

nwp500.utils module
-------------------

Expand Down
63 changes: 32 additions & 31 deletions docs/guides/reservations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ Here's a simple example that sets up a weekday morning reservation:
device = await api.get_first_device()

# Build reservation entry
weekday_morning = NavienAPIClient.build_reservation_entry(
weekday_morning = build_reservation_entry(
enabled=True,
days=["Monday", "Tuesday", "Wednesday", "Thursday",
"Friday"],
hour=6,
minute=30,
mode_id=4, # High Demand
temperature_f=140.0 # Temperature in Fahrenheit
temperature=140.0 # Temperature in user's preferred unit
)

# Send to device
Expand Down Expand Up @@ -149,8 +149,8 @@ Field Descriptions
(e.g., ``98`` for 120°F) for consistency.

**Note:** When using ``build_reservation_entry()``, you don't need to
calculate the param value manually - just pass ``temperature_f`` in
Fahrenheit and the conversion is handled automatically.
calculate the param value manually - just pass ``temperature`` in
your user's preferred unit and the conversion is handled automatically.

Helper Functions
================
Expand All @@ -161,33 +161,33 @@ Building Reservation Entries
-----------------------------

Use ``build_reservation_entry()`` to create properly formatted entries.
The function accepts temperature in Fahrenheit and handles the conversion
The function accepts temperature in your user's preferred unit and handles the conversion
to the device's internal format automatically:

.. code-block:: python

from nwp500 import build_reservation_entry

# Weekday morning - High Demand mode at 140°F
# Weekday morning - High Demand mode at 140 (°F or °C based on unit preference)
entry = build_reservation_entry(
enabled=True,
days=["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
hour=6,
minute=30,
mode_id=4, # High Demand
temperature_f=140.0 # Temperature in Fahrenheit
temperature=140.0 # Temperature in user's preferred unit
)
# Returns: {'enable': 1, 'week': 62, 'hour': 6, 'min': 30,
# 'mode': 4, 'param': 120}

# Weekend - Energy Saver mode at 120°F
# Weekend - Energy Saver mode at 120 (°F or °C)
entry2 = build_reservation_entry(
enabled=True,
days=["Saturday", "Sunday"],
hour=8,
minute=0,
mode_id=3, # Energy Saver
temperature_f=120.0
temperature=120.0
)

# You can also use day indices (0=Sunday, 6=Saturday)
Expand All @@ -197,7 +197,7 @@ to the device's internal format automatically:
hour=18,
minute=0,
mode_id=1, # Heat Pump Only
temperature_f=130.0
temperature=130.0
)

Temperature Conversion Utility
Expand Down Expand Up @@ -269,34 +269,34 @@ Send a new reservation schedule to the device:

# Build multiple reservation entries
reservations = [
# Weekday morning: High Demand at 140°F
# Weekday morning: High Demand at 140 (user's preferred unit)
build_reservation_entry(
enabled=True,
days=["Monday", "Tuesday", "Wednesday", "Thursday",
"Friday"],
hour=6,
minute=30,
mode_id=4,
temperature_f=140.0
temperature=140.0
),
# Weekday evening: Energy Saver at 130°F
# Weekday evening: Energy Saver at 130 (user's preferred unit)
build_reservation_entry(
enabled=True,
days=["Monday", "Tuesday", "Wednesday", "Thursday",
"Friday"],
hour=18,
minute=0,
mode_id=3,
temperature_f=130.0
temperature=130.0
),
# Weekend: Heat Pump Only at 120°F
# Weekend: Heat Pump Only at 120 (user's preferred unit)
build_reservation_entry(
enabled=True,
days=["Saturday", "Sunday"],
hour=8,
minute=0,
mode_id=1,
temperature_f=120.0
temperature=120.0
),
]

Expand Down Expand Up @@ -439,7 +439,7 @@ Different settings for work days and weekends:
hour=5,
minute=30,
mode_id=4, # High Demand
temperature_f=140.0
temperature=140.0
),
# Weekend morning: later start, energy saver
build_reservation_entry(
Expand All @@ -448,7 +448,7 @@ Different settings for work days and weekends:
hour=8,
minute=0,
mode_id=3, # Energy Saver
temperature_f=130.0
temperature=130.0
),
]

Expand All @@ -467,7 +467,7 @@ Minimize energy use during peak hours:
hour=6,
minute=0,
mode_id=4,
temperature_f=140.0
temperature=140.0
),
# Day: 9:00 AM - Switch to Energy Saver
build_reservation_entry(
Expand All @@ -476,7 +476,7 @@ Minimize energy use during peak hours:
hour=9,
minute=0,
mode_id=3,
temperature_f=120.0
temperature=120.0
),
# Evening: 5:00 PM - Heat Pump Only (before peak pricing)
build_reservation_entry(
Expand All @@ -485,7 +485,7 @@ Minimize energy use during peak hours:
hour=17,
minute=0,
mode_id=1,
temperature_f=130.0
temperature=130.0
),
# Night: 10:00 PM - Back to Energy Saver
build_reservation_entry(
Expand All @@ -494,7 +494,7 @@ Minimize energy use during peak hours:
hour=22,
minute=0,
mode_id=3,
temperature_f=120.0
temperature=120.0
),
]

Expand All @@ -512,7 +512,7 @@ Automatically enable vacation mode during a trip:
hour=20,
minute=0,
mode_id=5, # Vacation Mode
temperature_f=120.0 # Temperature doesn't matter for vacation mode
temperature=120.0 # Temperature doesn't matter for vacation mode
)

# Return to normal operation when you get back
Expand All @@ -522,7 +522,7 @@ Automatically enable vacation mode during a trip:
hour=14,
minute=0,
mode_id=3, # Energy Saver
temperature_f=130.0
temperature=130.0
)

reservations = [start_vacation, end_vacation]
Expand All @@ -533,11 +533,12 @@ Important Notes
Temperature Conversion
-----------------------

When using ``build_reservation_entry()``, pass temperatures in Fahrenheit
using the ``temperature_f`` parameter. The function automatically converts
to the device's internal format (half-degrees Celsius).
When using ``build_reservation_entry()``, pass temperatures in your user's
preferred unit (Celsius or Fahrenheit) using the ``temperature`` parameter.
The function automatically converts to the device's internal format
(half-degrees Celsius).

The valid temperature range is 95°F to 150°F.
The valid temperature range is 35°C to 65.5°C (95°F to 150°F).

For reading reservation responses from the device, the ``param`` field
contains the raw half-degrees Celsius value. Convert to Fahrenheit with:
Expand Down Expand Up @@ -619,7 +620,7 @@ Full working example with error handling and response monitoring:
hour=6,
minute=30,
mode_id=4, # High Demand
temperature_f=140.0
temperature=140.0
),
# Weekday day
build_reservation_entry(
Expand All @@ -629,7 +630,7 @@ Full working example with error handling and response monitoring:
hour=9,
minute=0,
mode_id=3, # Energy Saver
temperature_f=120.0
temperature=120.0
),
# Weekend morning
build_reservation_entry(
Expand All @@ -638,7 +639,7 @@ Full working example with error handling and response monitoring:
hour=8,
minute=0,
mode_id=3, # Energy Saver
temperature_f=130.0
temperature=130.0
),
]

Expand Down
42 changes: 25 additions & 17 deletions docs/protocol/data_conversions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,17 @@ The device uses several encoding schemes to minimize transmission overhead:
- Applied to decimal precision values
- Formula: ``displayed_value = raw_value / 10.0``
- Purpose: Preserve decimal precision in integer storage
- Common for flow rates and differential temperatures
- Common for flow rates
- Example: Raw 125 → 12.5 GPM

3.5. **Temperature Delta (Decicelsius)** (div_10_celsius_delta)
- Applied to differential temperature settings (heat pump and element hysteresis)
- Formula: ``displayed_value_celsius = raw_value / 10.0``, ``displayed_value_fahrenheit = (raw_value / 10.0) * 9/5`` (NO +32 offset)
- Purpose: Represents temperature DIFFERENCES/DELTAS, not absolute temperatures
- Key difference from absolute temperature conversion: No +32 offset applied when converting to Fahrenheit
- Example: Raw 5 → 0.5°C delta → 0.9°F delta (NOT 32.9°F)
- Used for: Heat pump on/off differential, heating element on/off differential

4. **Boolean Encoding** (device_bool)
- Applied to all status flags
- Formula: ``displayed_value = (raw_value == 2)``
Expand Down Expand Up @@ -181,21 +189,21 @@ Electric heating elements are controlled via thermostat ranges. Two sensors (upp
- °F
- **Lower element OFF threshold**. Lower tank temp rises above this to deactivate lower element.
* - ``heUpperOnDiffTempSetting``
- div_10
- div_10_celsius_delta
- °F
- **Upper element differential** (ON-OFF difference). Hysteresis width to prevent rapid cycling. Typically 2-5°F.
- **Upper element differential** (ON-OFF hysteresis width). Temperature delta to prevent rapid cycling. Typically 2-5°F. This is a DELTA value, not an absolute temperature (0 delta = 0°F difference).
* - ``heUpperOffDiffTempSetting``
- div_10
- div_10_celsius_delta
- °F
- **Upper element differential** variation (advanced tuning). May vary based on mode.
- **Upper element OFF differential** (advanced tuning). May vary based on mode. DELTA value.
* - ``heLowerOnDiffTempSetting``
- div_10
- div_10_celsius_delta
- °F
- **Lower element differential** (ON-OFF difference).
- **Lower element differential** (ON-OFF hysteresis width). DELTA value.
* - ``heLowerOffDiffTempSetting``
- div_10
- div_10_celsius_delta
- °F
- **Lower element differential** variation.
- **Lower element OFF differential** variation. DELTA value.
* - ``heatMinOpTemperature``
- HalfCelsiusToF
- °F
Expand Down Expand Up @@ -231,21 +239,21 @@ Heat pump stages are similarly controlled via thermostat ranges:
- °F
- **Lower heat pump OFF**. Lower tank rises above this to stop lower tank heat pump operation.
* - ``hpUpperOnDiffTempSetting``
- div_10
- div_10_celsius_delta
- °F
- **Heat pump upper differential** (ON-OFF hysteresis). Prevents rapid cycling.
- **Heat pump upper differential** (ON-OFF hysteresis). Temperature delta to prevent rapid cycling. DELTA value.
* - ``hpUpperOffDiffTempSetting``
- div_10
- div_10_celsius_delta
- °F
- **Heat pump upper differential** variation.
- **Heat pump upper OFF differential** variation. DELTA value.
* - ``hpLowerOnDiffTempSetting``
- div_10
- div_10_celsius_delta
- °F
- **Heat pump lower differential**.
- **Heat pump lower ON differential**. DELTA value.
* - ``hpLowerOffDiffTempSetting``
- div_10
- div_10_celsius_delta
- °F
- **Heat pump lower differential** variation.
- **Heat pump lower OFF differential** variation. DELTA value.

Freeze Protection Temperatures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
15 changes: 8 additions & 7 deletions docs/python_api/device_control.rst
Original file line number Diff line number Diff line change
Expand Up @@ -220,32 +220,33 @@ Temperature Control
set_dhw_temperature()
^^^^^^^^^^^^^^^^^^^^^

.. py:method:: set_dhw_temperature(device, temperature_f)
.. py:method:: set_dhw_temperature(device, temperature)

Set DHW target temperature.

**Capability Required:** ``dhw_temperature_setting_use`` - DHW temperature control enabled

:param device: Device object
:type device: Device
:param temperature_f: Target temperature in Fahrenheit (95-150°F)
:type temperature_f: float
:param temperature: Target temperature in user's preferred unit (Celsius or Fahrenheit)
:type temperature: float
:return: Publish packet ID
:rtype: int
:raises RangeValidationError: If temperature is outside 95-150°F range
:raises RangeValidationError: If temperature is outside valid range
:raises DeviceCapabilityError: If device doesn't support temperature control

The temperature is automatically converted to the device's internal format
(half-degrees Celsius).
(half-degrees Celsius). The valid range depends on the device's
temperature preference and configuration.

**Example:**

.. code-block:: python

# Set temperature to 140°F
# Set temperature (interpreted in device's preferred unit)
await mqtt.control.set_dhw_temperature(device, 140.0)

# Common temperatures
# Common temperatures (device-dependent units)
await mqtt.control.set_dhw_temperature(device, 120.0) # Standard
await mqtt.control.set_dhw_temperature(device, 130.0) # Medium
await mqtt.control.set_dhw_temperature(device, 140.0) # Hot
Expand Down
Loading