Add VolumeCode enum and improve DeviceFeature field documentation#53
Add VolumeCode enum and improve DeviceFeature field documentation#53
Conversation
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)
There was a problem hiding this comment.
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
VolumeCodeenum 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) |
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
src/nwp500/enums.py
Outdated
| 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 |
There was a problem hiding this comment.
Corrected spelling of 'liter' to 'liters' in all three volume code comments.
| 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 |
src/nwp500/cli/__main__.py
Outdated
|
|
||
| logging.basicConfig( | ||
| level=logging.WARNING, | ||
| level=logging.WARNING, # Default for other libraries |
There was a problem hiding this comment.
Missing space after '#' in comment. Should be '# Default for other libraries' per PEP 8.
| level=logging.WARNING, # Default for other libraries | |
| level=logging.WARNING, # Default for other libraries |
src/nwp500/cli/__main__.py
Outdated
|
|
||
| cli() | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
There was a problem hiding this comment.
Excessive blank lines (3 consecutive blank lines) reduce code readability. Reduce to 1-2 blank lines maximum.
| cli() | |
| cli() |
src/nwp500/models.py
Outdated
| "(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)" |
There was a problem hiding this comment.
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.
| "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." |
- 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