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-2026.6.1.tar.gz (24.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-2026.6.1-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for senzwifi-2026.6.1.tar.gz
Algorithm Hash digest
SHA256 e4d29dadf0fdf6f72a80df2001fbac3c3171f11bf9f3da5bb32cab11809e1ab1
MD5 a49469081127fb85c8fd222c4472e046
BLAKE2b-256 5de85ef0ba4da7092d0369b7d722399f3a12f206d7bd929bd4f96e40a1510f84

See more details on using hashes here.

Provenance

The following attestation bundles were made for senzwifi-2026.6.1.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-2026.6.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for senzwifi-2026.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 eab9f6283cf7925f2b385ef9ed26403b1f2def5c7bf0b0126c7ae133698170a0
MD5 96dfed44cc583a5a915891fe8193e0da
BLAKE2b-256 0d5ec4505907747f9a88d143ff146734032d1fb39d18f11e539c6953a424268d

See more details on using hashes here.

Provenance

The following attestation bundles were made for senzwifi-2026.6.1-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