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
23 changes: 18 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ The library includes a command line interface for quick monitoring and device in
# Get device feature/capability information
python -m nwp500.cli --device-feature

# Turn device on
python -m nwp500.cli --power-on

# Turn device off
python -m nwp500.cli --power-off

# Turn device on and see updated status
python -m nwp500.cli --power-on --status

# Set operation mode and see response
python -m nwp500.cli --set-mode energy-saver

Expand All @@ -105,6 +114,8 @@ The library includes a command line interface for quick monitoring and device in
* ``--status``: Print current device status as JSON. Can be combined with control commands to see updated status.
* ``--device-info``: Print comprehensive device information (firmware, model, capabilities) via MQTT as JSON and exit
* ``--device-feature``: Print device capabilities and feature settings via MQTT as JSON and exit
* ``--power-on``: Turn the device on and display response
* ``--power-off``: Turn the device off and display response
* ``--set-mode MODE``: Set operation mode and display response. Valid modes: heat-pump, energy-saver, high-demand, electric, vacation, standby
* ``--set-dhw-temp TEMP``: Set DHW (Domestic Hot Water) target temperature in Fahrenheit (115-150°F) and display response
* ``--monitor``: Continuously monitor status every 30 seconds and log to CSV (default)
Expand Down Expand Up @@ -156,19 +167,21 @@ Operation Modes
* - Heat Pump Mode
- 1
- Most energy-efficient mode using only the heat pump. Longest recovery time.
* - Energy Saver Mode
* - Electric Mode
- 2
- Fastest recovery using only electric heaters. Least energy-efficient.
* - Energy Saver Mode
- 3
- Default mode. Balances efficiency and recovery time using both heat pump and electric heater.
* - High Demand Mode
- 3
- Uses electric heater more frequently for faster recovery time.
* - Electric Mode
- 4
- Fastest recovery using only electric heaters. Least energy-efficient.
- Uses electric heater more frequently for faster recovery time.
* - Vacation Mode
- 5
- Suspends heating to save energy during extended absences.

**Important:** When you set a mode, you're configuring the ``dhwOperationSetting`` (what mode to use when heating). The device's current operational state is reported in ``operationMode`` (0=Standby, 32=Heat Pump active, 64=Energy Saver active, 96=High Demand active). See the `Device Status Fields documentation <docs/DEVICE_STATUS_FIELDS.rst>`_ for details on this distinction.

MQTT Protocol
=============

Expand Down
225 changes: 208 additions & 17 deletions docs/DEVICE_STATUS_FIELDS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ This document lists the fields found in the ``status`` object of device status m
- Sub error code providing additional error details. See ERROR_CODES.rst for details.
- None
* - ``operationMode``
- integer
- OperationMode
- None
- The current operation mode of the device. See Operation Modes section below.
- The current **actual operational state** of the device (what it's doing RIGHT NOW). Reports status values: 0=Standby, 32=Heat Pump active, 64=Energy Saver active, 96=High Demand active. See Operation Modes section below for the critical distinction between this and ``dhwOperationSetting``.
- None
* - ``operationBusy``
- integer
Expand Down Expand Up @@ -229,9 +229,9 @@ This document lists the fields found in the ``status`` object of device status m
- Type of program reservation.
- None
* - ``dhwOperationSetting``
- integer
- OperationMode
- None
- DHW operation setting.
- User's configured DHW operation mode preference. This field uses the same ``OperationMode`` enum as ``operationMode`` but contains command mode values (1=HEAT_PUMP, 2=ELECTRIC, 3=ENERGY_SAVER, 4=HIGH_DEMAND, 5=VACATION, 6=POWER_OFF). When the device is powered off via the power-off command, this field will show 6 (POWER_OFF). This is how to distinguish between "powered off" vs "on but in standby". See the Operation Modes section below for details.
- None
* - ``temperatureType``
- integer
Expand Down Expand Up @@ -469,31 +469,31 @@ The ``operationMode`` field is an integer that maps to the following modes. Thes
- High
- Most energy-efficient mode, using only the heat pump. Recovery time varies with ambient temperature and humidity. Higher ambient temperature and humidity improve efficiency and reduce recovery time.
* - 2
- Electric
- Fast
- Very Low
- Uses only upper and lower electric heaters (not simultaneously). Least energy-efficient with shortest recovery time. Can operate continuously for up to 72 hours before automatically reverting to previous mode.
* - 3
- Energy Saver (Hybrid: Efficiency)
- Fast
- Very High
- Default mode. Combines the heat pump and electric heater for balanced efficiency and recovery time. Heat pump is primarily used with electric heater for backup. Applied during initial shipment and factory reset.
* - 3
* - 4
- High Demand (Hybrid: Boost)
- Very Fast
- Low
- Combines heat pump and electric heater with more frequent use of electric heater for faster recovery. Suitable when higher hot water supply is needed.
* - 4
- Electric
- Fast
- Very Low
- Uses only upper and lower electric heaters (not simultaneously). Least energy-efficient with shortest recovery time. Can operate continuously for up to 72 hours before automatically reverting to previous mode.
* - 5
- Vacation
- None
- Very High
- Suspends heating to save energy during absences (0-99 days). Only minimal operations like freeze protection and anti-seize are performed. Heating resumes 9 hours before the vacation period ends.


Observed Operation Modes (from network traffic analysis)
Operation Modes
--------------------------------------------------------

The following ``operationMode`` values have been observed in status messages from the device. These values appear to correspond to the commanded modes as follows:
The following ``operationMode`` values in status messages from the device. These values appear to correspond to the commanded modes as follows:

.. list-table::
:header-rows: 1
Expand All @@ -509,13 +509,204 @@ The following ``operationMode`` values have been observed in status messages fro
- Heat Pump
- Corresponds to commanded mode ``HEAT_PUMP`` (1).
* - 64
- Energy Saver
- Corresponds to commanded mode ``ENERGY_SAVER`` (2).
- Energy Saver (Hybrid: Efficiency)
- Corresponds to commanded mode ``ENERGY_SAVER`` (3).
* - 96
- High Demand
- Corresponds to commanded mode ``HIGH_DEMAND`` (3).
- High Demand (Hybrid: Boost)
- Corresponds to commanded mode ``HIGH_DEMAND`` (4).

The commanded mode ``ELECTRIC`` (2) has been observed to result in ``operationMode`` values of both 64 and 96 at different times.

Understanding operationMode vs dhwOperationSetting
---------------------------------------------------

These two fields serve different purposes and it's critical to understand their relationship:

Field Definitions
^^^^^^^^^^^^^^^^^

**dhwOperationSetting** (OperationMode enum with command values 1-5)
The user's **configured mode preference** - what heating mode the device should use when it needs to heat water. This is set via the ``dhw-mode`` command and persists until changed by the user or device.

* Type: ``OperationMode`` enum
* Values:

* 1 = ``HEAT_PUMP`` (Heat Pump Only)
* 2 = ``ELECTRIC`` (Electric Only)
* 3 = ``ENERGY_SAVER`` (Hybrid: Efficiency)
* 4 = ``HIGH_DEMAND`` (Hybrid: Boost)
* 5 = ``VACATION`` (Vacation mode)
* 6 = ``POWER_OFF`` (Device is powered off)

* Set by: User via app, CLI, or MQTT command
* Changes: Only when user explicitly changes the mode or powers device off/on
* Meaning: "When heating is needed, use this mode" OR "I'm powered off" (if value is 6)
* **Critical**: Value 6 (``POWER_OFF``) indicates the device was powered off via the power-off command. This is how to distinguish between "powered off" and "on but idle".

**operationMode** (OperationMode enum with status values 0, 32, 64, 96)
The device's **current actual operational state** - what the device is doing RIGHT NOW. This reflects real-time operation and changes automatically based on whether the device is idle or actively heating.

* Type: ``OperationMode`` enum
* Values:

* 0 = ``STANDBY`` (Idle, not heating)
* 32 = ``HEAT_PUMP_MODE`` (Heat Pump actively running)
* 64 = ``HYBRID_EFFICIENCY_MODE`` (Energy Saver actively heating)
* 96 = ``HYBRID_BOOST_MODE`` (High Demand actively heating)

* Set by: Device automatically based on heating demand
* Changes: Dynamically as device starts/stops heating
* Meaning: "This is what I'm doing right now"
* **Note**: This field shows ``STANDBY`` (0) both when device is powered off AND when it's on but not heating. Check ``dhwOperationSetting`` to determine if device is actually powered off (value 6).

Key Relationship
^^^^^^^^^^^^^^^^

The relationship between these fields can be summarized as:

* ``dhwOperationSetting`` = "What mode to use when heating"
* ``operationMode`` = "Am I heating right now, and if so, how?"

A device can be **idle** (``operationMode = STANDBY``) while still being **configured** for a specific heating mode (``dhwOperationSetting = ENERGY_SAVER``). When the tank temperature drops and heating begins, ``operationMode`` will change to reflect active heating (e.g., ``HYBRID_EFFICIENCY_MODE``), but ``dhwOperationSetting`` remains unchanged.

Real-World Examples
^^^^^^^^^^^^^^^^^^^

**Example 1: Energy Saver Mode, Tank is Hot**
::

dhwOperationSetting = 3 (ENERGY_SAVER) # Configured mode
operationMode = 0 (STANDBY) # Currently idle
dhwChargePer = 100 # Tank is fully charged

*Interpretation:* Device is configured for Energy Saver mode, but water is already at temperature so no heating is occurring.

**Example 2: Energy Saver Mode, Actively Heating**
::

dhwOperationSetting = 3 (ENERGY_SAVER) # Configured mode
operationMode = 64 (HYBRID_EFFICIENCY_MODE) # Actively heating
operationBusy = true # Heating in progress
dhwChargePer = 75 # Tank at 75%

*Interpretation:* Device is using Energy Saver mode to heat the tank, currently at 75% charge.

**Example 3: High Demand Mode, Heat Pump Running**
::

dhwOperationSetting = 4 (HIGH_DEMAND) # Configured mode
operationMode = 32 (HEAT_PUMP_MODE) # Heat pump active
compUse = true # Compressor running

*Interpretation:* Device is configured for High Demand but is currently running just the heat pump component (hybrid heating will engage electric elements as needed).

**Example 4: Device Powered Off**
::

dhwOperationSetting = 6 (POWER_OFF) # Device powered off
operationMode = 0 (STANDBY) # Currently idle
operationBusy = false # No heating

*Interpretation:* Device was powered off using the power-off command. Although ``operationMode`` shows ``STANDBY`` (same as an idle device), the ``dhwOperationSetting`` value of 6 indicates it's actually powered off, not just idle.

Displaying Status in a User Interface
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For user-facing applications, follow these guidelines:

**Primary Mode Display**
Use ``dhwOperationSetting`` to show the user's configured mode preference. This is what users expect to see as "the current mode" because it represents their selection.

**Important**: Check for value 6 (``POWER_OFF``) first to show "Off" or "Powered Off" status.

Example display::

Mode: Energy Saver [when dhwOperationSetting = 1-5]
Mode: Off [when dhwOperationSetting = 6]

**Status Indicator**
Use ``operationMode`` to show real-time operational status:

* ``STANDBY`` (0): Show "Idle" or "Standby" indicator (but check ``dhwOperationSetting`` for power-off state)
* ``HEAT_PUMP_MODE`` (32): Show "Heating (Heat Pump)" or heating indicator
* ``HYBRID_EFFICIENCY_MODE`` (64): Show "Heating (Energy Saver)" or heating indicator
* ``HYBRID_BOOST_MODE`` (96): Show "Heating (High Demand)" or heating indicator

**Combined Display Examples**
::

# Device on and idle
Mode: Energy Saver
Status: Idle ○
Tank: 100%

# Device on and heating
Mode: Energy Saver
Status: Heating ●
Tank: 75%

# Device powered off
Mode: Off
Status: Powered Off
Tank: 100%

**Code Example**
.. code-block:: python

def format_mode_display(status: DeviceStatus) -> dict:
"""Format mode and status for UI display."""

# Check if device is powered off first
if status.dhwOperationSetting == OperationMode.POWER_OFF:
return {
'configured_mode': 'Off',
'operational_state': 'Powered Off',
'is_heating': False,
'is_powered_on': False,
'tank_charge': status.dhwChargePer,
}

# User's configured mode (what they selected)
configured_mode = status.dhwOperationSetting.name.replace('_', ' ').title()

# Current operational state
if status.operationMode == OperationMode.STANDBY:
operational_state = "Idle"
is_heating = False
elif status.operationMode == OperationMode.HEAT_PUMP_MODE:
operational_state = "Heating (Heat Pump)"
is_heating = True
elif status.operationMode == OperationMode.HYBRID_EFFICIENCY_MODE:
operational_state = "Heating (Energy Saver)"
is_heating = True
elif status.operationMode == OperationMode.HYBRID_BOOST_MODE:
operational_state = "Heating (High Demand)"
is_heating = True
else:
operational_state = "Unknown"
is_heating = False

return {
'configured_mode': configured_mode, # "Energy Saver"
'operational_state': operational_state, # "Idle" or "Heating..."
'is_heating': is_heating, # True/False
'is_powered_on': True, # Device is on
'tank_charge': status.dhwChargePer, # 0-100
}

**Display Notes**

1. **Never display operationMode as "the mode"** - users don't care that the device is in "HYBRID_EFFICIENCY_MODE", they want to know it's set to "Energy Saver"

2. **Do use operationMode for heating indicators** - it tells you whether the device is actively heating right now

3. **Mode changes affect dhwOperationSetting** - when a user changes the mode, you're setting ``dhwOperationSetting``

4. **operationMode changes automatically** - you cannot directly set this; it changes based on device operation

5. **Both fields use OperationMode enum** - but different value ranges (1-6 for dhwOperationSetting, 0/32/64/96 for operationMode)

The commanded mode ``ELECTRIC`` (4) has been observed to result in ``operationMode`` values of both 64 and 96 at different times.
6. **Power off detection** - Check if ``dhwOperationSetting == 6`` (``POWER_OFF``) to determine if device is powered off vs just idle

Technical Notes
---------------
Expand Down
19 changes: 14 additions & 5 deletions docs/MQTT_CLIENT.rst
Original file line number Diff line number Diff line change
Expand Up @@ -442,15 +442,21 @@ set_dhw_mode()

await mqtt_client.set_dhw_mode(device: Device, mode_id: int) -> int

Set DHW (Domestic Hot Water) operation mode.
Set DHW (Domestic Hot Water) operation mode. This sets the ``dhwOperationSetting`` field, which determines what heating mode the device will use when it needs to heat water.

**Command:** ``33554433``

**Mode:** ``dhw-mode``

**Mode IDs:** - ``1``: Heat Pump (most efficient, longest recovery) -
``2``: Electric (least efficient, fastest recovery) - ``3``: Energy
Saver (default, balanced) - ``4``: High Demand (faster recovery)
**Mode IDs (command values):**

* ``1``: Heat Pump Only (most efficient, longest recovery)
* ``2``: Electric Only (least efficient, fastest recovery)
* ``3``: Energy Saver (default, balanced - Hybrid: Efficiency)
* ``4``: High Demand (faster recovery - Hybrid: Boost)
* ``5``: Vacation (suspend heating for 0-99 days)

**Important:** Setting the mode updates ``dhwOperationSetting`` but does not immediately change ``operationMode``. The ``operationMode`` field reflects the device's current operational state and changes automatically when the device starts/stops heating. See :doc:`DEVICE_STATUS_FIELDS` for details on the relationship between these fields.

set_dhw_temperature()
'''''''''''''''''''''
Expand Down Expand Up @@ -749,13 +755,16 @@ Response Message
"dhwTemperature": 120,
"tankUpperTemperature": 115,
"tankLowerTemperature": 110,
"operationMode": 3,
"operationMode": 64,
"dhwOperationSetting": 3,
"dhwUse": true,
"compUse": false
}
}
}

Note: ``operationMode`` shows the current operational state (64 = Energy Saver actively heating), while ``dhwOperationSetting`` shows the configured mode preference (3 = Energy Saver). See :doc:`DEVICE_STATUS_FIELDS` for the distinction between these fields.

Error Handling
--------------

Expand Down
2 changes: 1 addition & 1 deletion docs/MQTT_MESSAGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ The device sends a response to a control message on the ``responseTopic`` specif

The ``sessionID`` in the response corresponds to the ``sessionID`` of the request.

The ``response`` object contains a ``status`` object that reflects the new state. For example, after a ``dhw-mode`` command with ``param`` ``[3]``\ , the ``dhwOperationSetting`` in the ``status`` object of the response will be ``3``.
The ``response`` object contains a ``status`` object that reflects the new state. For example, after a ``dhw-mode`` command with ``param`` ``[3]`` (Energy Saver), the ``dhwOperationSetting`` field in the ``status`` object will be ``3``. Note that ``operationMode`` may still show ``0`` (STANDBY) if the device is not currently heating. See :doc:`DEVICE_STATUS_FIELDS` for the important distinction between ``dhwOperationSetting`` (configured mode) and ``operationMode`` (current operational state).

Device Status Messages
----------------------
Expand Down
Loading