Skip to content

Add VolumeCode enum and improve DeviceFeature field documentation#53

Merged
eman merged 16 commits intomainfrom
feature/device-feature-enhancements
Dec 24, 2025
Merged

Add VolumeCode enum and improve DeviceFeature field documentation#53
eman merged 16 commits intomainfrom
feature/device-feature-enhancements

Conversation

@eman
Copy link
Copy Markdown
Owner

@eman eman commented Dec 23, 2025

  • Add VolumeCode enum mapping tank capacity codes to gallons (50/65/80)
  • Add _volume_code_validator for robust enum conversion
  • Export VolumeCode from main package
  • Update DeviceFeature.volume_code to use VolumeCodeField with enum validation
  • Clarify documentation for country_code, model_type_code, control_type_code, and recirc_model_type_code fields
  • Fix device country code documentation (actual value is 3, not 1 as previously noted)

- Add VolumeCode enum mapping tank capacity codes to gallons (50/65/80)
- Add _volume_code_validator for robust enum conversion
- Export VolumeCode from main package
- Update DeviceFeature.volume_code to use VolumeCodeField with enum validation
- Clarify documentation for country_code, model_type_code, control_type_code, and recirc_model_type_code fields
- Fix device country code documentation (actual value is 3, not 1 as previously noted)
@eman eman requested a review from Copilot December 23, 2025 20:08
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 enhances the device features API by introducing a strongly-typed VolumeCode enum for tank capacity codes and improving field documentation with more precise, accurate descriptions based on real device observations.

Key Changes:

  • Adds VolumeCode enum mapping tank capacity codes (1/2/3) to nominal gallons (50/65/80)
  • Corrects country code documentation from code 1 to code 3 based on actual USA device data
  • Clarifies that several device code fields are device-specific identifiers without public specifications

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/nwp500/enums.py Adds VolumeCode enum with three capacity variants (50/65/80 gallons)
src/nwp500/models.py Implements VolumeCodeField with validation, updates field documentation with accurate descriptions, corrects country code value
src/nwp500/__init__.py Exports VolumeCode enum for external use
docs/protocol/device_features.rst Updates country code documentation to reflect actual device value (3 instead of 1)

eman added 12 commits December 23, 2025 14:18
Address review comment: Make documentation consistent between device_features.rst
and models.py regarding country_code field. Updated to clarify that USA devices
report code 3 and that code 1 was previously documented.

- Country/region code description now consistent across documentation
- Added note about previous documentation referencing code 1
- Improved clarity on device-specific code nature
Add display text mapping for VolumeCode enum values to match the pattern
used by other enums in the Display Text Helpers section.

- Maps VolumeCode.VOLUME_50/65/80 to '50 gallons', '65 gallons', '80 gallons'
- Consistent with existing display text helpers for other enums
- Add pyright>=1.1.0 to dev dependencies in setup.cfg
- Configure pyright in pyproject.toml with strict mode for src/nwp500
- Add pyright to tox lint and default environments
- Update CI workflow to use Python 3.13 consistently
- Integrate pyright into lint script (scripts/lint.py)
- Fix type errors in src code:
  - Add public property to MqttDeviceControl.device_info_cache
  - Add setter method for _ensure_device_info_callback
  - Fix datetime imports to use UTC from datetime module
  - Fix type annotations in rich_output.py for optional dependencies
  - Fix encoding.py type narrowing issue
  - Remove unused import from mqtt_connection.py
  - Fix events.py unused variable assignment
  - Remove unnecessary connection check in mqtt_connection.py
- Update MqttConnection callback signature to use AwsCrtError

Type checking now runs automatically:
- Locally: make ci-lint or python3 scripts/lint.py
- In CI: lint and test jobs both run pyright
- All 209 tests passing with 0 errors from src code
Consolidate 9 separate MQTT modules into a cohesive mqtt package:
- Create src/nwp500/mqtt/ package with organized submodules
- Combine reconnection logic into connection.py
- Update all imports across codebase (mqtt package, examples, tests, CLI)
- Create mqtt/__init__.py with clean public API exports
- Fix type checking errors in connection.py and client.py
- Remove old mqtt_*.py files from src/nwp500/

Benefits:
- Clearer package organization and structure
- Reduced cognitive load for users learning the system
- Better clarity on public vs internal APIs
- Easier maintenance and navigation

All 209 tests pass with zero type checking errors in mqtt package.
- Rename DeviceCapabilityChecker to MqttDeviceCapabilityChecker for consistency
- Rename DeviceInfoCache to MqttDeviceInfoCache to indicate MQTT domain
- Update all imports and usages across codebase
- Update public API exports in __init__.py
- Add comprehensive Naming Conventions section to CONTRIBUTING.rst with:
  - Class naming patterns (Client, Manager, Utility)
  - Method naming patterns (getters, setters, actions, requesters)
  - Enum documentation requirements
  - Exception hierarchy patterns
- Fix all type errors:
  - Remove unused type: ignore comments
  - Add cast() for optional rich library objects
  - Fix protected member access in auth.py
  - Add type annotation for optional console field
- Update all tests to use new class names
- All linting, type checking, and tests passing
…ters

- Create temperature.py: Typed classes for HalfCelsius and DeciCelsius
  * Base Temperature ABC with to_celsius() and to_fahrenheit() methods
  * HalfCelsius: 0.5°C precision (value / 2.0)
  * DeciCelsius: 0.1°C precision (value / 10.0)
  * from_fahrenheit() class methods for reverse conversions
  * Validator functions for Pydantic integration

- Create converters.py: Protocol-specific converters
  * device_bool_to_python(): Convert device boolean (1=False, 2=True)
  * device_bool_from_python(): Reverse conversion
  * tou_status_to_python(): Time of Use status conversion
  * tou_override_to_python(): TOU override status conversion
  * div_10(): Divide by 10.0 utility
  * enum_validator(): Generic enum factory
  * Comprehensive documentation explaining device protocol quirks

- Refactor models.py: Use new converter modules
  * Replace 53 lines of scattered validators with imports
  * Update frankfurter_to_half_celsius() to use HalfCelsius class
  * Preserve all Pydantic type annotations
  * Update imports and remove duplicate logic

Benefits:
- Type-safe temperature handling with clear precision
- Easier to use the correct temperature converter
- Protocol logic documented and centralized
- Better testability and maintainability
- No breaking changes to public API

Tests: All 209 tests pass
Linting: All checks pass (ruff, pyright)
Type checking: No new type errors
…ctory function

- Create factory.py: create_navien_clients() for simplified multi-client init
  * Handles authentication and session setup automatically
  * Returns (auth, api, mqtt) clients ready to use
  * Reduces boilerplate for common use case
  * Documented with clear usage examples

- Add docs/guides/authentication.rst: Comprehensive authentication guide
  * Explains session lifecycle and context manager semantics
  * Documents implicit vs explicit sign-in behavior
  * Shows how to share sessions between API and MQTT clients
  * Includes token management and restoration patterns
  * Covers security best practices
  * Troubleshooting guide for common issues

- Enhance auth.py docstring: Clarify context manager behavior
  * Explain exactly what happens on __aenter__ and __aexit__
  * Document session creation and cleanup
  * Show proper pattern for multi-client usage
  * Add example of creating API and MQTT clients

- Update README.rst: Add MQTT real-time monitoring section
  * Quick example of setting up MQTT client
  * Link to comprehensive authentication guide
  * Show complete flow with both API and MQTT

- Add examples/authentication_patterns.py: Concrete working examples
  * Basic authentication pattern
  * Multi-client setup (API + MQTT)
  * Explicit initialization steps for clarity
  * All examples ready to run with credentials

Benefits:
- Clear initialization order and dependencies
- Explicit documentation of when sign_in() happens
- Session management is no longer scattered or confusing
- Easier for users to share auth across clients
- Context manager semantics fully documented
- Factory function available for convenience

Tests: All 209 tests pass
Linting: All checks pass
- Migrate CLI to Click framework for better command organization
  * Implemented async_command decorator for automatic loop and connection management
  * Added support for command groups (reservations, tou)
  * Improved argument and option parsing with built-in validation
  * Enhanced help text and version reporting

- Centralize command registry in src/nwp500/cli/commands.py
  * Created CliCommand dataclass for structured command metadata
  * Defined CLI_COMMANDS registry for easier discovery

- Reorganize CLI handlers into src/nwp500/cli/handlers.py
  * Moved implementation logic from commands.py to handlers.py
  * Improved separation of concerns between CLI framework and business logic

- Infrastructure and Tests
  * Added click>=8.0.0 dependency to setup.cfg
  * Updated tests/test_cli_commands.py to use new handler locations
  * All CLI tests pass with new implementation

Benefits:
- Better discoverability of available commands
- Cleaner command organization and parameter validation
- Reduced boilerplate for adding new async CLI commands
- Industry-standard CLI framework (Click)
- Reorganize examples into beginner, intermediate, advanced, and testing categories
  * Created structured hierarchy in examples/ directory
  * Renamed and moved 35+ example scripts for better discoverability
  * Updated examples/README.md with a 'Getting Started' guide and categorized index
  * Patched sys.path and imports in all examples to work with new structure
  * Added 01-04 beginner series for smooth onboarding

- Implement MQTT event system and feature monitoring
  * Added nwp500/mqtt_events.py for structured MQTT event handling
  * Updated nwp500/mqtt/client.py to support event emission
  * Enhanced device capability monitoring in nwp500/mqtt/control.py
  * Added unit tests for model and temperature converters
- Create docs/PROTOCOL_REFERENCE.md: Developer cheat sheet for protocol quirks
  * Documents non-standard boolean logic (1=False, 2=True)
  * Lists key Enum values (OperationMode, DhwSetting)
  * Summarizes MQTT topic structure and command codes
  * Acts as a quick lookup to prevent 'magic number' bugs

- Update source code documentation
  * src/nwp500/converters.py: Link to reference in docstring
  * src/nwp500/enums.py: Link to reference in docstring
- Convert docs/PROTOCOL_REFERENCE.md to docs/protocol/quick_reference.rst
  * Use proper ReStructuredText syntax for consistency
  * Add to docs/index.rst under Advanced: Protocol Reference
  * Remove standalone Markdown file from docs/ directory

- Update source code references
  * src/nwp500/converters.py: Point to new .rst location
  * src/nwp500/enums.py: Point to new .rst location
@eman eman requested a review from Copilot December 24, 2025 03:01
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 75 out of 93 changed files in this pull request and generated 4 comments.

Comment on lines +226 to +228
VOLUME_50 = 1 # NWP500-50: 50-gallon (189.2 liter) tank capacity
VOLUME_65 = 2 # NWP500-65: 65-gallon (246.0 liter) tank capacity
VOLUME_80 = 3 # NWP500-80: 80-gallon (302.8 liter) tank capacity
Copy link

Copilot AI Dec 24, 2025

Choose a reason for hiding this comment

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

Corrected spelling of 'liter' to 'liters' in all three volume code comments.

Suggested change
VOLUME_50 = 1 # NWP500-50: 50-gallon (189.2 liter) tank capacity
VOLUME_65 = 2 # NWP500-65: 65-gallon (246.0 liter) tank capacity
VOLUME_80 = 3 # NWP500-80: 80-gallon (302.8 liter) tank capacity
VOLUME_50 = 1 # NWP500-50: 50-gallon (189.2 liters) tank capacity
VOLUME_65 = 2 # NWP500-65: 65-gallon (246.0 liters) tank capacity
VOLUME_80 = 3 # NWP500-80: 80-gallon (302.8 liters) tank capacity

Copilot uses AI. Check for mistakes.

logging.basicConfig(
level=logging.WARNING,
level=logging.WARNING, # Default for other libraries
Copy link

Copilot AI Dec 24, 2025

Choose a reason for hiding this comment

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

Missing space after '#' in comment. Should be '# Default for other libraries' per PEP 8.

Suggested change
level=logging.WARNING, # Default for other libraries
level=logging.WARNING, # Default for other libraries

Copilot uses AI. Check for mistakes.
Comment on lines +347 to +353

cli()





Copy link

Copilot AI Dec 24, 2025

Choose a reason for hiding this comment

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

Excessive blank lines (3 consecutive blank lines) reduce code readability. Reduce to 1-2 blank lines maximum.

Suggested change
cli()
cli()

Copilot uses AI. Check for mistakes.
"(1=USA, complies with FCC Part 15 Class B)"
"Country/region code where device is certified for operation. "
"Device-specific code without public specification. "
"Example: USA devices report code 3 (previously documented as 1)"
Copy link

Copilot AI Dec 24, 2025

Choose a reason for hiding this comment

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

Consider adding a note about whether code 1 was incorrect in previous versions or if the device firmware changed. This helps users understand the historical context.

Suggested change
"Example: USA devices report code 3 (previously documented as 1)"
"Example: USA devices report code 3. Earlier project "
"documentation incorrectly listed code 1 for USA; field "
"observations of production devices confirm that code 3 is "
"the correct value."

Copilot uses AI. Check for mistakes.
eman added 3 commits December 23, 2025 19:49
- Configure Pyright to downgrade untyped decorator/base class warnings
  from third-party libraries (Click, Pydantic) to warnings instead of errors
- Remove dead code and verbose development comments from CLI module
- Add type ignore annotations for untyped Click decorators
- Fix null-safety checks in tou_get function
- Fix type safety in cli() function call
- Remove unused imports and fix code formatting
- All 377 tests pass, CI linting checks pass
@eman eman merged commit 4392847 into main Dec 24, 2025
7 checks passed
@eman eman deleted the feature/device-feature-enhancements branch December 24, 2025 06:32
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.

2 participants