Skip to content

Commit e61f7f2

Browse files
authored
Merge pull request #50 from eman/improvement/diagnostics-and-docs
feat: enhance diagnostics, docs, and CLI tests
2 parents 40ad3d4 + be8e8ea commit e61f7f2

36 files changed

Lines changed: 643 additions & 199 deletions

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
runs-on: ubuntu-latest
3434
strategy:
3535
matrix:
36-
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
36+
python-version: ['3.13', '3.14']
3737

3838
steps:
3939
- uses: actions/checkout@v4

CHANGELOG.rst

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,31 @@
22
Changelog
33
=========
44

5-
Version 6.2.0 (2025-12-17)
5+
Version 7.0.0 (2025-12-17)
66
==========================
77

8-
**BREAKING CHANGES**: Enumerations refactored for type safety and consistency
8+
**BREAKING CHANGES**:
9+
- Minimum Python version raised to 3.13
10+
- Enumerations refactored for type safety and consistency
11+
12+
Removed
13+
-------
14+
- **Python 3.9-3.12 Support**: Minimum Python version is now 3.13
15+
16+
Home Assistant has deprecated Python 3.12 support, making Python 3.13 the de facto minimum for this ecosystem.
17+
18+
Python 3.13 features and improvements:
19+
20+
- **Experimental free-threaded mode** (PEP 703): Optional GIL removal for true parallelism
21+
- **JIT compiler** (PEP 744): Just-in-time compilation for performance improvements
22+
- **Better error messages**: Enhanced suggestions for NameError, AttributeError, and import errors
23+
- **Type system enhancements**: TypeVars with defaults (PEP 696), @deprecated decorator (PEP 702), ReadOnly TypedDict (PEP 705)
24+
- **Performance**: ~5-10% faster overall, optimized dictionary/set operations, better function calls
25+
- PEP 695: New type parameter syntax for generics
26+
- PEP 701: f-string improvements
27+
- Built-in ``datetime.UTC`` constant
28+
29+
If you need Python 3.12 support, use version 6.1.x of this library.
930

1031
- **CommandCode moved**: Import from ``nwp500.enums`` instead of ``nwp500.constants``
1132

@@ -22,6 +43,13 @@ Version 6.2.0 (2025-12-17)
2243
Added
2344
-----
2445

46+
- **Python 3.12+ Optimizations**: Leverage latest Python features
47+
48+
- PEP 695: New type parameter syntax (``def func[T](...)`` instead of ``TypeVar``)
49+
- Use ``datetime.UTC`` constant instead of ``datetime.timezone.utc``
50+
- Native union syntax (``X | Y`` instead of ``Union[X, Y]``)
51+
- Cleaner generic type annotations throughout codebase
52+
2553
- **Enumerations Module (``src/nwp500/enums.py``)**: Comprehensive type-safe enums for device control and status
2654

2755
- Status value enums: ``OnOffFlag``, ``Operation``, ``DhwOperationSetting``, ``CurrentOperationMode``, ``HeatSource``, ``DREvent``, ``WaterLevel``, ``FilterChange``, ``RecirculationMode``

README.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,10 @@ The library includes type-safe data models with automatic unit conversions:
175175
Requirements
176176
============
177177

178-
* Python 3.9+
178+
* Python 3.13+
179179
* aiohttp >= 3.8.0
180-
* websockets >= 10.0
181-
* cryptography >= 3.4.0
182180
* pydantic >= 2.0.0
183-
* awsiotsdk >= 1.21.0
181+
* awsiotsdk >= 1.27.0
184182

185183
License
186184
=======

docs/development/history.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ providing:
1818
- Automatic reconnection with exponential backoff
1919
- Command queuing for reliable communication
2020
- Historical energy usage data (EMS API)
21-
- Modern Python 3.9+ codebase with native type hints
21+
- Modern Python 3.13+ codebase with native type hints
2222

2323
Current Status
2424
--------------
@@ -38,7 +38,7 @@ The library is feature-complete with:
3838
- Comprehensive documentation
3939
- Working examples for all features
4040
- Unit tests with good coverage
41-
- Python 3.9+ with modern type hints
41+
- Python 3.13+ with modern type hints
4242

4343
Implementation Milestones
4444
-------------------------

docs/installation.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Installation
55
Requirements
66
============
77

8-
* Python 3.9 or higher
8+
* Python 3.13 or higher
99
* pip (Python package installer)
1010
* Navien Smart Control account
1111

@@ -51,7 +51,7 @@ Core Dependencies
5151
The library requires:
5252

5353
* ``aiohttp>=3.8.0`` - Async HTTP client for REST API
54-
* ``awsiotsdk>=1.20.0`` - AWS IoT SDK for MQTT
54+
* ``awsiotsdk>=1.27.0`` - AWS IoT SDK for MQTT
5555
* ``pydantic>=2.0.0`` - Data validation and models
5656

5757
Optional Dependencies
@@ -128,7 +128,7 @@ The MQTT client requires the AWS IoT SDK:
128128

129129
.. code-block:: bash
130130
131-
pip install awsiotsdk>=1.20.0
131+
pip install awsiotsdk>=1.27.0
132132
133133
Upgrading
134134
=========

docs/python_api/models.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ Complete real-time device status with 100+ fields.
292292
# Water usage detection
293293
if status.dhw_use:
294294
print("Water usage detected (short-term)")
295-
if status.dhw_useSustained:
295+
if status.dhw_use_sustained:
296296
print("Water usage detected (sustained)")
297297
298298
# Errors

docs/python_api/mqtt_client.rst

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ subscribe_device_status()
207207
print(f"Target: {status.dhw_temperature_setting}°F")
208208
print(f"Mode: {status.dhw_operation_setting.name}")
209209
print(f"Power: {status.current_inst_power}W")
210-
print(f"Energy: {status.available_energy_capacity}%")
210+
print(f"Energy: {status.dhw_charge_per}%")
211211
212212
# Check if actively heating
213213
if status.operation_busy:
@@ -566,11 +566,15 @@ subscribe_energy_usage()
566566
print(f"Electric: {energy.total.heat_element_percentage:.1f}%")
567567
568568
print("\nDaily Breakdown:")
569-
for day_data in energy.data:
570-
print(f" Date: Day {len(energy.data)}")
571-
print(f" Total: {day_data.total_usage} Wh")
572-
print(f" HP: {day_data.hpUsage} Wh ({day_data.hpTime}h)")
573-
print(f" HE: {day_data.heUsage} Wh ({day_data.heTime}h)")
569+
for monthly_data in energy.usage:
570+
print(f" Month: {monthly_data.year}-{monthly_data.month}")
571+
for day_data in monthly_data.data:
572+
# Skip empty days (all zeros)
573+
if day_data.total_usage > 0:
574+
print(f" Day {monthly_data.data.index(day_data) + 1}:")
575+
print(f" Total: {day_data.total_usage} Wh")
576+
print(f" HP: {day_data.heat_pump_usage} Wh ({day_data.heat_pump_time}h)")
577+
print(f" HE: {day_data.heat_element_usage} Wh ({day_data.heat_element_time}h)")
574578
575579
await mqtt.subscribe_energy_usage(device, on_energy)
576580
await mqtt.request_energy_usage(device, year=2024, months=[10])

docs/quickstart.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ in just a few minutes.
88
Prerequisites
99
=============
1010

11-
* Python 3.9 or higher
11+
* Python 3.13 or higher
1212
* Navien Smart Control account (via Navilink mobile app)
1313
* At least one Navien NWP500 device registered to your account
1414
* Valid email and password for your Navien account

examples/mask.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
from __future__ import annotations
88

99
import re
10-
from typing import Optional
1110

1211

13-
def mask_mac(mac: Optional[str]) -> str:
12+
def mask_mac(mac: str | None) -> str:
1413
"""Always return fully redacted MAC address label, never expose partial values."""
1514
return "[REDACTED_MAC]"
1615

1716

18-
def mask_mac_in_topic(topic: str, mac_addr: Optional[str] = None) -> str:
17+
def mask_mac_in_topic(topic: str, mac_addr: str | None = None) -> str:
1918
"""Return topic with any MAC-like substrings replaced.
2019
2120
Also ensures a direct literal match of mac_addr is redacted.
@@ -33,7 +32,7 @@ def mask_mac_in_topic(topic: str, mac_addr: Optional[str] = None) -> str:
3332
__all__ = ["mask_mac", "mask_mac_in_topic"]
3433

3534

36-
def mask_any(value: Optional[str]) -> str:
35+
def mask_any(value: str | None) -> str:
3736
"""Generic redaction for strings considered sensitive in examples.
3837
3938
Always returns a short redaction tag; keep implementation simple so examples
@@ -51,7 +50,7 @@ def mask_any(value: Optional[str]) -> str:
5150
return "[REDACTED]"
5251

5352

54-
def mask_location(city: Optional[str], state: Optional[str]) -> str:
53+
def mask_location(city: str | None, state: str | None) -> str:
5554
"""Redact location fields for examples.
5655
5756
Returns a single redaction tag if either city or state are present.

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ version_scheme = "no-guess-dev"
1111
[tool.ruff]
1212
# Ruff configuration for code formatting and linting
1313
line-length = 80
14-
target-version = "py39"
14+
target-version = "py313"
1515

1616
# Exclude directories
1717
exclude = [
@@ -99,7 +99,7 @@ line-ending = "auto"
9999
strict = true
100100

101101
# Python version target
102-
python_version = "3.9"
102+
python_version = "3.13"
103103

104104
# Module discovery
105105
files = ["src/nwp500", "tests"]

0 commit comments

Comments
 (0)