Skip to main content

pyfenixcontrol

Asynchronous Python client for the FENIX Control cloud, used by FENIX TFT WiFi thermostats. It powers the FENIX integration for Home Assistant, but has no Home Assistant dependency and can be used from any asyncio code.

  • Fully typed (py.typed), asyncio + aiohttp, Python 3.12+
  • Read thermostats, rooms and installations; set target temperature and operating mode
  • Installation-wide holiday schedules
  • Room energy consumption at hourly … yearly aggregation
  • Pluggable authentication: bundled e-mail/password login, or bring your own OAuth2 tokens
  • Automatic token refresh, single retry on HTTP 401, backoff on HTTP 5xx

Installation

pip install pyfenixcontrol

Quick start

import asyncio

import aiohttp

from pyfenixcontrol import FenixControlClient, PasswordAuth, PresetMode


async def main() -> None:
    async with aiohttp.ClientSession() as session:
        auth = PasswordAuth(session, "you@example.com", "password")
        client = FenixControlClient(auth)

        for device in await client.get_devices():
            print(device.name, device.room_temperature, device.target_temperature)

        await client.set_target_temperature(device.id, 21.5)
        await client.set_preset_mode(device.id, PresetMode.PROGRAM)


asyncio.run(main())

Authentication

The client never sees credentials. It asks an AbstractAuth for a bearer token:

from pyfenixcontrol import AbstractAuth


class MyAuth(AbstractAuth):
    async def async_get_access_token(self) -> str:
        return await my_token_store.get_valid_token()

    async def async_invalidate_access_token(self) -> None:
        # Called after an HTTP 401; optional.
        await my_token_store.mark_expired()

PasswordAuth performs the OAuth2 authorization-code + PKCE login used by the FENIX Control app and keeps tokens in memory. await auth.async_login() validates credentials up front (e.g. in a setup wizard).

PasswordAuth needs an aiohttp session with a working cookie jar, because the identity server tracks its login form with cookies. Cookies of the identity host are cleared before each full login.

API overview

Method Description
get_user_id() Account subject id (cached on the client)
get_installations() Installations (homes) with their rooms and device ids
get_devices(installations=None) Device state of every thermostat
get_device_properties(device_id) Raw device twin properties
trigger_installation_update(installation_id) Ask thermostats to report fresh values
set_target_temperature(device_id, celsius) Set target °C (switches to manual)
set_preset_mode(device_id, mode) PresetMode.OFF / PROGRAM / MANUAL / DEFROST / BOOST / HOLIDAYS
set_holiday_schedule(installation_id, start, end, mode) Holiday for the whole installation
cancel_holiday_schedule(installation_id) Remove the holiday schedule
get_room_energy(installation_id, room_id, start, end, period) EnergyMetric buckets in Wh

Errors

Exception Meaning
FenixControlAuthError Credentials or tokens rejected – user action needed
FenixControlConnectionError Network error or timeout – retry later
FenixControlResponseError Unexpected status or body (.status holds the HTTP code)

All inherit from FenixControlError.

Units and conventions

  • Temperatures are °C. The API transports °F × divFactor; decode_temperature() / encode_temperature() convert.
  • Holiday start/end are wall-clock times of the installation (no time zone conversion). Energy queries convert to UTC; naive datetimes are taken as UTC.
  • Every model keeps the original payload in .raw for fields not yet modelled.

Development

uv sync
uv run pytest --cov
uv run ruff check . && uv run ruff format --check . && uv run mypy

Tests run against a local fake of the cloud and identity server; no account is needed.

Releases: bump __version__, update CHANGELOG.md, publish a GitHub release tagged vX.Y.Z. The release workflow publishes to PyPI via trusted publishing.

License

MIT – see LICENSE. Not an official product of FENIX Trading s.r.o. unless stated otherwise in the project metadata.

Metadata

Release files for pyfenixcontrol 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyfenixcontrol 0.1.0
File Size Uploaded
pyfenixcontrol-0.1.0.tar.gz 22.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyfenixcontrol 0.1.0
File Interpreter ABI Platform
pyfenixcontrol-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 39.7 kB

Release files / pyfenixcontrol-0.1.0.tar.gz

Download URL pyfenixcontrol-0.1.0.tar.gz
Size 22.5 kB
Tags Source
SHA-256 checksum
How to use checksums
23814ad2e4367d6d7dee63a15337d3b96e637d4f78161b3382f25b67711bd58a
BLAKE2b-256 checksum
How to use checksums
28a6e0bbd720a74e7100da66dce0de9eb0611dcd7c9a7bfa2c4604765e0fc895
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / pyfenixcontrol-0.1.0-py3-none-any.whl

Download URL pyfenixcontrol-0.1.0-py3-none-any.whl
Size 17.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4c98d5c7573632de65b05968ba8e4b042c3bcbde4276441781e9de1edf3ca4a3
BLAKE2b-256 checksum
How to use checksums
e41882e7aeb1d84e8334b3f59097c27f612c75aa5ee1499feb59840b7202bab3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page