Skip to content

Commit 33f37bf

Browse files
authored
Merge pull request #47 from eman/feature/enumerations-module
Feature/enumerations module
2 parents 1040607 + 571c408 commit 33f37bf

23 files changed

Lines changed: 1846 additions & 422 deletions

CHANGELOG.rst

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,88 @@
22
Changelog
33
=========
44

5+
Version 6.2.0 (2025-12-17)
6+
==========================
7+
8+
**BREAKING CHANGES**: Enumerations refactored for type safety and consistency
9+
10+
- **CommandCode moved**: Import from ``nwp500.enums`` instead of ``nwp500.constants``
11+
12+
.. code-block:: python
13+
14+
# OLD (removed)
15+
from nwp500.constants import CommandCode
16+
17+
# NEW
18+
from nwp500.enums import CommandCode
19+
# OR
20+
from nwp500 import CommandCode # Still works
21+
22+
Added
23+
-----
24+
25+
- **Enumerations Module (``src/nwp500/enums.py``)**: Comprehensive type-safe enums for device control and status
26+
27+
- Status value enums: ``OnOffFlag``, ``Operation``, ``DhwOperationSetting``, ``CurrentOperationMode``, ``HeatSource``, ``DREvent``, ``WaterLevel``, ``FilterChange``, ``RecirculationMode``
28+
- Time of Use enums: ``TouWeekType``, ``TouRateType``
29+
- Device capability enums: ``CapabilityFlag``, ``TemperatureType``, ``DeviceType``
30+
- Device control command enum: ``CommandCode`` (all MQTT command codes)
31+
- Error code enum: ``ErrorCode`` with complete error code mappings
32+
- Human-readable text mappings for all enums (e.g., ``DHW_OPERATION_SETTING_TEXT``, ``ERROR_CODE_TEXT``)
33+
- Exported from main package: ``from nwp500 import OnOffFlag, ErrorCode, CommandCode``
34+
- Comprehensive documentation in ``docs/enumerations.rst``
35+
- Example usage in ``examples/error_code_demo.py``
36+
37+
Changed
38+
-------
39+
40+
- **Command Code Constants**: Migrated from ``constants.py`` to ``CommandCode`` enum in ``enums.py``
41+
42+
- ``ANTI_LEGIONELLA_ENABLE`` → ``CommandCode.ANTI_LEGIONELLA_ON``
43+
- ``ANTI_LEGIONELLA_DISABLE`` → ``CommandCode.ANTI_LEGIONELLA_OFF``
44+
- ``TOU_ENABLE`` → ``CommandCode.TOU_ON``
45+
- ``TOU_DISABLE`` → ``CommandCode.TOU_OFF``
46+
- ``TOU_SETTINGS`` → ``CommandCode.TOU_RESERVATION``
47+
- All command constants now use consistent naming in ``CommandCode`` enum
48+
49+
- **Model Enumerations**: Updated type annotations for clarity and type safety
50+
51+
- ``TemperatureUnit`` → ``TemperatureType`` (matches device protocol field names)
52+
- All capability flags (e.g., ``power_use``, ``dhw_use``) now use ``CapabilityFlag`` type
53+
- ``MqttRequest.device_type`` now accepts ``Union[DeviceType, int]`` for flexibility
54+
55+
- **Model Serialization**: Enums automatically serialize to human-readable names
56+
57+
- `model_dump()` converts enums to names (e.g., `DhwOperationSetting.HEAT_PUMP` → `"HEAT_PUMP"`)
58+
- CLI and other consumers benefit from automatic enum name serialization
59+
- Text mappings available for custom formatting (e.g., `DHW_OPERATION_TEXT[enum]` → "Heat Pump Only")
60+
61+
- **Documentation**: Comprehensive updates across protocol and API documentation
62+
63+
- ``docs/guides/time_of_use.rst``: Clarified TOU override status behavior (1=OFF/override active, 2=ON/normal operation)
64+
- ``docs/protocol/data_conversions.rst``: Updated TOU field descriptions with correct enum values
65+
- ``docs/protocol/device_features.rst``: Added capability flag pattern explanation (2=supported, 1=not supported)
66+
- ``docs/protocol/mqtt_protocol.rst``: Updated command code references to use new enum names
67+
- ``docs/python_api/models.rst``: Updated model field type annotations
68+
69+
- **Examples**: Updated to use new enums for type-safe device control
70+
71+
- ``examples/anti_legionella_example.py``: Uses ``CommandCode`` enum
72+
- ``examples/device_feature_callback.py``: Uses capability enums
73+
- ``examples/event_emitter_demo.py``: Uses status enums
74+
- ``examples/mqtt_diagnostics_example.py``: Uses command enums
75+
76+
- **CLI Code Cleanup**: Refactored JSON formatting to use shared utility function
77+
78+
- Extracted repeated `json.dumps()` calls to `format_json_output()` helper
79+
- Cleaner code with consistent formatting across all commands
80+
81+
Fixed
82+
-----
83+
84+
- **Temperature Conversion Test**: Corrected ``test_device_status_div10`` to use ``HalfCelsiusToF`` conversion (100 → 122°F, not 50.0)
85+
- **Documentation**: Fixed references to non-existent ``OperationMode`` enum - replaced with correct ``DhwOperationSetting`` and ``CurrentOperationMode`` enums
86+
587
Version 6.1.1 (2025-12-08)
688
==========================
789

@@ -238,7 +320,7 @@ Quick Example
238320
239321
# OLD boolean and enum handling
240322
is_heating = converted["currentHeatUse"] == 2
241-
mode = CurrentOperationMode(converted["operationMode"]) if converted["operationMode"] in (0,32,64,96) else CurrentOperationMode.STANDBY
323+
mode = OperationMode(converted["operationMode"]) if converted["operationMode"] in (0,32,64,96) else OperationMode.STANDBY
242324
243325
# NEW simplified
244326
is_heating = status.current_heat_use

docs/enumerations.rst

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

0 commit comments

Comments
 (0)