Skip to main content

Python library for interacting with SenzWifi (Pentair Thermal WiFi) API to control thermostats

Project description

python-senz-wifi-module

Python library for interacting with the SenzWifi (Pentair Thermal WiFi) API to control thermostats.

Features

  • Async-first — built on httpx for efficient async operations
  • Authentication & session management — automatic retry on session expiry
  • Thermostat control — list, read, and update thermostat settings
  • Convenience methods — set temperature, turn off, boost mode
  • Real-time notifications — long-polling for thermostat state changes
  • CLI tool — built-in command-line interface for quick operations
  • Fully typed — type hints throughout with py.typed marker

Installation

pip install senzwifi

Or install from source:

git clone https://github.com/sockless-coding/python-senz-wifi-module.git
cd python-senz-wifi-module
pip install -e .

Quick Start

Using the Library

import asyncio
from senzwifi import AsyncSenzWifi, RegulationMode

async def main():
    # Create client with credentials
    async with AsyncSenzWifi("your@email.com", "your-password") as client:
        # Authenticate
        await client.authenticate()

        # List all thermostats
        response = await client.get_thermostats()
        for group in response.groups:
            print(f"Group: {group.group_name}")
            for t in group.thermostats:
                print(f"  {t.room}: {t.temperature_celsius:.1f}°C (mode: {RegulationMode(t.regulation_mode).name})")

        # Set a thermostat to 21°C manually
        await client.set_manual_temperature("SN123456789", 21.0)

        # Turn off a thermostat
        await client.turn_off("SN123456789")

        # Start boost mode (3 hours by default)
        await client.start_boost("SN123456789")

asyncio.run(main())

Using the CLI

# List all thermostats
senzwifi --username "your@email.com" --password "your-password" list

# Get a specific thermostat
senzwifi --username "your@email.com" --password "your-password" get SN123456789

# Set temperature to 21°C
senzwifi --username "your@email.com" --password "your-password" set SN123456789 21.0

# Turn off a thermostat
senzwifi --username "your@email.com" --password "your-password" off SN123456789

# Start boost mode
senzwifi --username "your@email.com" --password "your-password" boost SN123456789

API Reference

AsyncSenzWifi

The main client class. Supports use as an async context manager.

async with AsyncSenzWifi(email, password) as client:
    await client.authenticate()
    # ... use the client

Constructor

Parameter Type Default Description
email str Account email address
password str Account password
max_retries int 3 Maximum retry attempts for failed requests
timeout float 30.0 Request timeout in seconds

Methods

authenticate() -> AuthResponse

Authenticate and obtain a session ID.

auth = await client.authenticate()
if auth.is_success:
    print(f"Logged in as {auth.email}")
get_thermostats() -> ThermostatsResponse

Fetch all thermostats grouped by their group.

response = await client.get_thermostats()
for group in response.groups:
    print(f"{group.group_name}: {len(group.thermostats)} devices")

# Get all thermostats flat
all_thermostats = response.get_all_thermostats()

# Find a specific thermostat
t = response.get_thermostat("SN123456789")
get_thermostat(serial_number: str) -> Thermostat

Get a specific thermostat by serial number.

t = await client.get_thermostat("SN123456789")
print(f"{t.room}: {t.temperature_celsius:.1f}°C")
set_manual_temperature(serial_number: str, temperature_celsius: float) -> UpdateThermostatResponse

Set a thermostat to a specific temperature in manual mode.

result = await client.set_manual_temperature("SN123456789", 21.5)
print(f"Success: {result.success}")
turn_off(serial_number: str) -> UpdateThermostatResponse

Turn off a thermostat.

result = await client.turn_off("SN123456789")
start_boost(serial_number: str, end_time: datetime | None = None) -> UpdateThermostatResponse

Start boost (comfort) mode. Defaults to 3 hours from now if no end time is specified.

from datetime import datetime, timedelta, timezone

# Boost for 3 hours (default)
await client.start_boost("SN123456789")

# Boost until a specific time
end = datetime.now(timezone.utc) + timedelta(hours=1)
await client.start_boost("SN123456789", end_time=end)
update_thermostat(serial_number: str, thermostat: Thermostat) -> UpdateThermostatResponse

Update a thermostat with custom settings.

t = await client.get_thermostat("SN123456789")
t.regulation_mode = RegulationMode.SCHEDULE
t.manual_temperature = 2000  # 20.0°C in raw format
result = await client.update_thermostat("SN123456789", t)
wait_for_notification(timeout: float = 300.0) -> Notification | None

Long-poll for thermostat state change notifications.

notification = await client.wait_for_notification(timeout=60.0)
if notification:
    print(f"Change detected: {notification.action} on {notification.thermostat.room}")

Models

RegulationMode

RegulationMode.SCHEDULE   # 1 — Use the configured schedule
RegulationMode.BOOST      # 2 — Boost / comfort temp mode
RegulationMode.MANUAL     # 3 — Constant temp mode
RegulationMode.OFF        # 5 — Off

Thermostat

Key properties (all temperatures available in both raw and Celsius):

Property Type Description
serial_number str Device serial number
room str Room name
group_name str Group name
temperature_celsius float Current temperature
regulation_mode int Current regulation mode
online bool Whether the device is online
heating bool Whether heating is active
manual_temperature_celsius float Manual setpoint temperature
comfort_temperature_celsius float Comfort/boost temperature
min_temp_celsius float Minimum temperature
max_temp_celsius float Maximum temperature
schedules list[Schedule] Available schedules

Temperature Conversion Utilities

from senzwifi import temp_to_celsius, celsius_to_temp

# Raw API value (1/100 °C) → Celsius
temp_to_celsius(2100)  # 21.0

# Celsius → raw API value
celsius_to_temp(21.0)  # 2100

Exceptions

Exception Description
SenzWifiError Base exception for all errors
AuthenticationError Authentication failed
SessionExpiredError Session has expired
DeviceNotFoundError Thermostat not found
APIError API request failed

Example: Monitoring Thermostats

See examples/monitor.py for a complete example that monitors thermostat changes in real time.

import asyncio
from senzwifi import AsyncSenzWifi, RegulationMode

async def monitor():
    async with AsyncSenzWifi("your@email.com", "your-password") as client:
        await client.authenticate()

        # Show initial state
        response = await client.get_thermostats()
        for t in response.get_all_thermostats():
            mode = RegulationMode(t.regulation_mode).name
            print(f"[INIT] {t.room}: {t.temperature_celsius:.1f}°C ({mode})")

        # Watch for changes
        while True:
            notification = await client.wait_for_notification()
            if notification:
                t = notification.thermostat
                mode = RegulationMode(t.regulation_mode).name
                print(f"[CHANGE] {t.room}: {t.temperature_celsius:.1f}°C ({mode})")

asyncio.run(monitor())

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run linter
ruff check .

# Run type checker
mypy senzwifi

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

senzwifi-0.1.0.tar.gz (20.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

senzwifi-0.1.0-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file senzwifi-0.1.0.tar.gz.

File metadata

  • Download URL: senzwifi-0.1.0.tar.gz
  • Upload date:
  • Size: 20.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for senzwifi-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2ee84548767fb2a87a580e7ee0205a6711c730973d3f52b4923c87a2f249ec0e
MD5 9363295c58de39a46fdc894ea76f1491
BLAKE2b-256 77793305efd894fe26101affcefc61f2e19fafc8488f84804942513840db4919

See more details on using hashes here.

Provenance

The following attestation bundles were made for senzwifi-0.1.0.tar.gz:

Publisher: publish.yml on sockless-coding/python-senz-wifi-module

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file senzwifi-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: senzwifi-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for senzwifi-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 407d0184608ad7a969021a96bd21b573ad424a79cf8a44282c325400530c64d7
MD5 3881ab4321f9800c3031abd235dbc73a
BLAKE2b-256 18183846df7e3608d3093385c842eea1a060669c98d18e21d0f3930f81cd5379

See more details on using hashes here.

Provenance

The following attestation bundles were made for senzwifi-0.1.0-py3-none-any.whl:

Publisher: publish.yml on sockless-coding/python-senz-wifi-module

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page