Skip to content

Feature/enumerations module#47

Merged
eman merged 21 commits intomainfrom
feature/enumerations-module
Dec 17, 2025
Merged

Feature/enumerations module#47
eman merged 21 commits intomainfrom
feature/enumerations-module

Conversation

@eman
Copy link
Copy Markdown
Owner

@eman eman commented Dec 17, 2025

Summary

This PR introduces a comprehensive enumerations module (src/nwp500/enums.py) that provides type-safe enums for device control commands, status values, and error codes.

Breaking Changes

  • Command Code Constants: Migrated to DeviceControl enum with consistent naming

    • ANTI_LEGIONELLA_ENABLE → ANTI_LEGIONELLA_ON
    • ANTI_LEGIONELLA_DISABLE → ANTI_LEGIONELLA_OFF
    • TOU_ENABLE → TOU_ON
    • TOU_DISABLE → TOU_OFF
    • TOU_SETTINGS → TOU_RESERVATION
  • Model Types:

    • TemperatureUnit → TemperatureType
    • Capability flags now use CapabilityFlag type

What's Added

  • 12+ Enumerations covering device protocol:

    • Status: OnOffFlag, Operation, DhwOperationSetting, CurrentOperationMode, HeatSource, DREvent, WaterLevel, FilterChange, RecirculationMode
    • TOU: TouWeekType, TouRateType
    • Capabilities: CapabilityFlag, TemperatureType, DeviceType
    • Commands: DeviceControl (complete command enum)
    • Errors: ErrorCode (complete error code mappings)
  • Human-readable text mappings for all enums

  • Documentation: docs/enumerations.rst with complete reference

  • Examples: examples/error_code_demo.py demonstrating enum usage

What's Changed

  • CLI output uses enum-based text mappings
  • Documentation updated across all guides and protocol docs
  • Examples updated to use new type-safe enums
  • All command constants migrated to consistent naming

What's Fixed

  • Temperature conversion test now uses correct HalfCelsiusToF formula

Testing

  • All existing tests pass with updated enum usage
  • New test validates temperature conversion fix

Documentation

  • Comprehensive enum reference in docs/enumerations.rst
  • Updated TOU guide with correct override status explanation
  • Updated protocol docs with new enum references
  • Added capability flag pattern explanation

eman added 2 commits December 17, 2025 08:56
BREAKING CHANGES:
- Migrated command codes to DeviceControl enum
- Renamed TemperatureUnit to TemperatureType
- Updated capability flags to use CapabilityFlag type

Added:
- src/nwp500/enums.py with 12+ enumerations for device protocol
- ErrorCode enum with complete error mappings
- DeviceControl enum for all MQTT commands
- Status enums: OnOffFlag, Operation, DhwOperationSetting, etc.
- Human-readable text mappings for all enums
- docs/enumerations.rst comprehensive reference
- examples/error_code_demo.py showing enum usage

Changed:
- CLI output uses enum-based text mappings
- Documentation updated across guides and protocol docs
- Examples updated to use new enums
- Command constants: ANTI_LEGIONELLA_ENABLE→ON, TOU_ENABLE→ON, etc.

Fixed:
- Temperature conversion test now uses correct HalfCelsiusToF formula
@eman eman requested a review from Copilot December 17, 2025 17:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a comprehensive enumerations module that centralizes all device protocol enums into type-safe IntEnum classes. The key improvement is replacing magic numbers and scattered enum definitions with a unified, well-documented enums module that provides type safety, human-readable text mappings, and consistent naming conventions.

Key Changes:

  • Created comprehensive enums module with 12+ enumerations for device protocol
  • Migrated command constants to consistent naming (e.g., ANTI_LEGIONELLA_ENABLE → ANTI_LEGIONELLA_ON)
  • Fixed temperature conversion test to use correct HalfCelsiusToF formula

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/nwp500/enums.py New comprehensive enumerations module with status values, commands, error codes, and text mappings
src/nwp500/models.py Updated to use enums from new module, added enum serialization to model_dump(), changed TemperatureUnit to TemperatureType
src/nwp500/constants.py Renamed command constants for consistency (ENABLE→ON, DISABLE→OFF, SETTINGS→RESERVATION)
src/nwp500/init.py Exports new enums for public API
src/nwp500/mqtt_device_control.py Updated to use renamed command constants
src/nwp500/cli/output_formatters.py Simplified enum serialization (now handled by model_dump())
src/nwp500/cli/commands.py Refactored to use format_json_output helper
tests/test_models.py Fixed temperature conversion test formula
examples/*.py Updated examples to use new enums
docs/*.rst Updated documentation to reference new enums and clarify TOU override behavior
Comments suppressed due to low confidence (1)

src/nwp500/enums.py:1

  • The class name OperationMode is introduced in enums.py but the PR description and documentation refer to it as DhwOperationSetting. The models.py file imports DhwOperationSetting from enums.py, but enums.py defines OperationMode. Either the import in models.py should use OperationMode, or the class in enums.py should be renamed to DhwOperationSetting for consistency.
"""Enumerations for Navien device protocol.

eman added 7 commits December 17, 2025 09:35
- Replace OperationMode with DhwOperationSetting (user-configured mode)
- Replace OperationMode with CurrentOperationMode (real-time state)
- Update text mapping examples to use correct constants
- Add both enums to enumerations.rst with clear explanations
- Update models.rst type annotations and examples
The use_enum_values=False parameter controls deserialization behavior
(keeps enums as enum objects during validation), not serialization.
Actual serialization to names is handled by the custom model_dump() method.
DhwOperationSetting does not have a HYBRID member. The hybrid modes are:
- ENERGY_SAVER (value 3) - Hybrid: Efficiency mode
- HIGH_DEMAND (value 4) - Hybrid: Boost mode
- Changed 'Hybrid mode' to 'Energy Saver mode' for HYBRID_EFFICIENCY_MODE
- Added missing handler for HYBRID_BOOST_MODE (High Demand mode)
- Ensures mode names match actual enum values and user-facing terminology
Changed two comparisons from checking OnOffFlag.OFF to OnOffFlag.ON:
- smart_diagnostic_use: OFF (1) = not supported, ON (2) = supported
- mixing_value_use: OFF (1) = not supported, ON (2) = supported

The previous logic showed 'Yes' when the flag was OFF, which was incorrect.
Copy link
Copy Markdown
Contributor

Copilot AI commented Dec 17, 2025

@eman I've opened a new pull request, #48, to work on those changes. Once the pull request is ready, I'll request review from you.

eman added 5 commits December 17, 2025 10:00
Reverted magic number 5 back to DhwOperationSetting.VACATION.value.
Added missing import from enums module.
Updated docstring to avoid magic number reference.
Fixed magic number usage in:
- examples/anti_legionella_example.py: 2 -> OnOffFlag.ON
- examples/combined_callbacks.py: 2 -> OnOffFlag.ON
- src/nwp500/mqtt_client.py: Updated docstring

All enum values now use proper enum references for type safety.
Moved CommandCode from constants.py to enums.py for better organization:
- All enumerations now in a single module
- constants.py now only contains firmware metadata
- Backward compatibility maintained via re-export in constants.py
- Updated imports in mqtt_device_control.py to use enums module
- Updated __init__.py to export CommandCode from enums

This consolidates all protocol enumerations in one place.
Per project policy, no backward compatibility needed.
- Removed re-export from constants.py
- Updated constants.py to note new import location
- Added breaking change to CHANGELOG with migration example

Users must update: from nwp500.constants -> from nwp500.enums
Updated import to use nwp500.enums instead of nwp500.constants
@eman eman requested a review from Copilot December 17, 2025 18:24
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 7 comments.

Comments suppressed due to low confidence (1)

src/nwp500/enums.py:1

  • The class name DeviceControl is inconsistent with the PR description and documentation which refer to CommandCode. The CHANGELOG and imports show this enum should be named CommandCode to match the original constant class it replaces. This inconsistency will cause confusion as developers expect to import CommandCode but the enum is actually named DeviceControl.
"""Enumerations for Navien device protocol.

eman added 4 commits December 17, 2025 10:32
The enum is named CommandCode, not DeviceControl.
- Updated docs/enumerations.rst: DeviceControl -> CommandCode
- Updated docs/python_api/models.rst: DeviceControl -> CommandCode
- Updated CHANGELOG.rst: All DeviceControl references -> CommandCode

This matches what developers actually import and use.
Prevents potential infinite recursion on circular references:
- Added 'visited' parameter to track processed objects
- Returns early if a circular reference is detected
- Uses set of object ids to identify already-processed items
- Fixes potential stack overflow with circular data structures

This is defensive programming for safety even though Pydantic models
should not produce circular references in normal use.
Signal handlers run in different execution contexts and can cause
race conditions when modifying shared state. Fixed by:
- Replaced self.running = False with asyncio.Event
- Signal handler schedules shutdown via asyncio.create_task
- Loop conditions check shutdown_event.is_set() instead of self.running
- Eliminates race conditions between signal handler and main loop

This is a safer pattern for async code with signal handlers.
Format strings with IntEnum values should use .value explicitly
rather than relying on implicit conversion. This improves:
- Clarity of intent (explicitly accessing the value)
- Type checking compliance
- Reduces error-prone implicit conversions

Changed E{error_code:03d} to E{error_code.value:03d} in two places.
@eman eman requested a review from Copilot December 17, 2025 18:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 3 comments.

eman added 3 commits December 17, 2025 10:54
Updated two remaining references to self.running attribute that was
removed in favor of asyncio.Event:
- Line 253: while condition now uses 'not self.shutdown_event.is_set()'
- Line 262: cleanup now calls 'self.shutdown_event.set()'

Prevents AttributeError at runtime in the main example loop.
Removed result_val temporary variable and return directly from
type(data)(converted) for cleaner, more concise code without
sacrificing readability.
Changed from incorrect 'CAS\_' with escaped underscore to proper
inline literal syntax using backticks: 'CAS_' renders correctly
in reStructuredText without escape sequences.
@eman eman merged commit 33f37bf into main Dec 17, 2025
10 checks passed
@eman eman deleted the feature/enumerations-module branch December 17, 2025 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants