Python library for interacting with Pentair Thermal WiFi API to control thermostats
Project description
pypentairthermalwifi
A Python library for interacting with the Pentair Thermal WiFi API to control thermostats.
Features
- 🔄 Both sync and async client support
- 🔐 Automatic session management
- 🔁 Retry logic with exponential backoff
- 📝 Full type hints
- 🎯 Simple, intuitive API
- ✅ Comprehensive test coverage
Vibe Coded with Claude Code...
Installation
pip install pypentairthermalwifi
Or using uv:
uv add pypentairthermalwifi
Quick Start
Synchronous Client
from pypentairthermalwifi import PentairThermalWifi
# Create client
client = PentairThermalWifi(
email="your-email@example.com",
password="your-password"
)
# Get all thermostats
response = client.get_thermostats()
for group in response.groups:
for thermostat in group.thermostats:
print(f"{thermostat.room}: {thermostat.temperature_celsius}°C")
# Get specific thermostat
thermostat = client.get_thermostat("1036918")
print(f"Current temperature: {thermostat.temperature_celsius}°C")
# Set manual temperature
client.set_manual_temperature("1036918", 21.5)
# Close the client when done
client.close()
Asynchronous Client
import asyncio
from pypentairthermalwifi import AsyncPentairThermalWifi
async def main():
# Create async client
async with AsyncPentairThermalWifi(
email="your-email@example.com",
password="your-password"
) as client:
# Get all thermostats
response = await client.get_thermostats()
for group in response.groups:
for thermostat in group.thermostats:
print(f"{thermostat.room}: {thermostat.temperature_celsius}°C")
# Get specific thermostat
thermostat = await client.get_thermostat("1036918")
print(f"Current temperature: {thermostat.temperature_celsius}°C")
# Set manual temperature
await client.set_manual_temperature("1036918", 21.5)
asyncio.run(main())
Logging
The library includes comprehensive logging at different levels to help you understand what's happening:
- DEBUG: Detailed request/response information, parameter values
- INFO: High-level operations (authentication, fetching thermostats, updates)
- WARNING: Retries, session expiry, non-critical issues
- ERROR: Authentication failures, request failures
Enable Logging
import logging
# Configure logging (do this before creating the client)
logging.basicConfig(
level=logging.INFO, # or DEBUG for more detail
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
from pypentairthermalwifi import PentairThermalWifi
client = PentairThermalWifi(email="user@example.com", password="pass")
# You'll now see log messages as operations occur
Demo Applications with Logging
The demo applications support logging via the LOG_LEVEL environment variable. When set to INFO or DEBUG, httpx logging is also enabled to show HTTP requests and responses:
# Run with INFO level logging (shows library operations + HTTP requests)
export LOG_LEVEL=INFO
uv run python demo.py
# Run with DEBUG level logging (maximum detail including connection events)
export LOG_LEVEL=DEBUG
uv run python demo.py
Example output with LOG_LEVEL=INFO:
16:30:45 - pypentairthermalwifi.sync_client - INFO - Authenticating as user@example.com
16:30:45 - httpx - DEBUG - HTTP Request: GET https://www.pentairthermalwifi.com/api/authenticate
16:30:46 - pypentairthermalwifi.sync_client - INFO - Authentication successful, session ID: rm3w7zLJ...
Demo Applications
Two interactive demo applications are included to test the library:
Synchronous Demo
# Run with environment variables
export PENTAIR_EMAIL="your-email@example.com"
export PENTAIR_PASSWORD="your-password"
uv run python demo.py
# Or enter credentials interactively
uv run python demo.py
Asynchronous Demo
# Run with environment variables
export PENTAIR_EMAIL="your-email@example.com"
export PENTAIR_PASSWORD="your-password"
uv run python demo_async.py
# Or enter credentials interactively
uv run python demo_async.py
Both demos provide an interactive menu to:
- 📋 List all thermostats with status
- 🔍 View detailed information for a specific thermostat
- 🌡️ Set temperature with confirmation
- ✨ See real-time heating status and online state
Usage
Temperature Conversion
The API uses temperatures in 1/100 degrees Celsius (e.g., 2100 = 21.0°C). Helper functions are provided:
from pypentairthermalwifi import temp_to_celsius, celsius_to_temp
# Convert from API format to Celsius
celsius = temp_to_celsius(2100) # 21.0
# Convert from Celsius to API format
raw = celsius_to_temp(21.0) # 2100
All thermostat models have convenient properties for temperature access:
thermostat = client.get_thermostat("1036918")
# Access temperatures in Celsius
print(thermostat.temperature_celsius)
print(thermostat.manual_temperature_celsius)
print(thermostat.comfort_temperature_celsius)
print(thermostat.min_temp_celsius)
print(thermostat.max_temp_celsius)
Advanced Usage
Custom Thermostat Update
# Get the current thermostat state
thermostat = client.get_thermostat("1036918")
# Modify settings
thermostat.regulation_mode = 5 # Auto mode
thermostat.selected_schedule = 2 # Use program 3
# Update the thermostat
response = client.update_thermostat("1036918", thermostat)
print(f"Update successful: {response.success}")
Error Handling
from pypentairthermalwifi import (
PentairThermalWifi,
AuthenticationError,
ThermostatNotFoundError,
SessionExpiredError,
APIError
)
try:
client = PentairThermalWifi(email="user@example.com", password="wrong")
client.authenticate()
except AuthenticationError as e:
print(f"Authentication failed: {e}")
try:
thermostat = client.get_thermostat("invalid-serial")
except ThermostatNotFoundError as e:
print(f"Thermostat not found: {e}")
try:
response = client.get_thermostats()
except SessionExpiredError as e:
print(f"Session expired: {e}")
# Client will automatically re-authenticate on next request
except APIError as e:
print(f"API error: {e}")
Using Context Managers
# Sync client
with PentairThermalWifi(email="user@example.com", password="pass") as client:
thermostats = client.get_thermostats()
# Client automatically closes when exiting the context
# Async client
async with AsyncPentairThermalWifi(email="user@example.com", password="pass") as client:
thermostats = await client.get_thermostats()
# Client automatically closes when exiting the context
API Reference
PentairThermalWifi / AsyncPentairThermalWifi
Both clients support the same methods (async versions return coroutines).
Constructor
client = PentairThermalWifi(
email: str,
password: str,
max_retries: int = 3,
timeout: float = 30.0
)
Methods
authenticate() -> AuthResponse: Manually authenticate and get session IDget_thermostats() -> ThermostatsResponse: Get all thermostats grouped by groupsget_thermostat(serial_number: str) -> Thermostat: Get a specific thermostat by serial numberupdate_thermostat(serial_number: str, thermostat: Thermostat) -> UpdateThermostatResponse: Update thermostat settingsset_manual_temperature(serial_number: str, temperature_celsius: float) -> UpdateThermostatResponse: Set manual temperature for a thermostatclose(): Close the HTTP client (async:await client.close())
Models
Thermostat: Complete thermostat data with temperature propertiesGroup: Thermostat group containing multiple thermostatsThermostatsResponse: Response containing all groupsSchedule: Thermostat program/scheduleAuthResponse: Authentication response
Exceptions
PentairThermalWifiError: Base exception for all library errorsAuthenticationError: Raised when authentication failsSessionExpiredError: Raised when session expires (auto-recovery enabled)ThermostatNotFoundError: Raised when thermostat is not foundAPIError: Raised on API errors
Development Setup
This project uses uv for dependency management and packaging.
Installation
# Install dependencies
uv sync --all-extras
Running Tests
# Run tests with coverage
uv run pytest
# Run tests with verbose output
uv run pytest -v
# Run tests with coverage report
uv run pytest --cov-report=html
Code Quality
# Run linting
uv run ruff check .
# Run linting with auto-fix
uv run ruff check --fix .
# Format code
uv run ruff format .
# Type checking
uv run mypy src/
All Checks
Run all quality checks before committing:
uv run ruff check . && uv run ruff format --check . && uv run mypy src/ && uv run pytest
Building
# Build package
uv build
Project Structure
pypentairthermalwifi/
├── src/
│ └── pypentairthermalwifi/
│ ├── __init__.py
│ └── py.typed
├── tests/
│ ├── __init__.py
│ └── test_pypentairthermalwifi.py
├── pyproject.toml
└── README.md
License
Add your license here.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pypentairthermalwifi-0.1.1.tar.gz.
File metadata
- Download URL: pypentairthermalwifi-0.1.1.tar.gz
- Upload date:
- Size: 15.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6210260ac8b3627aff7f47b335c2ce2f960d34ebfe8fc29822b0b28e1d3fce9d
|
|
| MD5 |
dd39bae2a69a236017afeb2e230134a5
|
|
| BLAKE2b-256 |
34078da80971d9058fa8309c28883eba250c391566dc77791cb0ac5d1caebc5e
|
File details
Details for the file pypentairthermalwifi-0.1.1-py3-none-any.whl.
File metadata
- Download URL: pypentairthermalwifi-0.1.1-py3-none-any.whl
- Upload date:
- Size: 18.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a79301fdcc55966b07f9717e2bdc3e7cb5c7a844f21c7847570a962e0ed2a1c
|
|
| MD5 |
f98c84a93a22303409c3ac618fcd186d
|
|
| BLAKE2b-256 |
89b6b67ec737503a90b8967a0298f3762bff619c75a49cdeacd5fcde8fab4d54
|