Skip to main content

Danfoss Ally API library

Project description

Buy Me A Coffee

Danfoss Ally API

Async-first Python client for the Danfoss Ally OpenAPI.

Installation

pip install pydanfossally

Local development

For local development with Poetry and VS Code debugging, this repository is configured to use an in-project virtual environment at .venv.

poetry install
poetry run python example.py

If you already created a Poetry environment before this setting was added, recreate it once so Poetry installs dependencies into .venv for this repository.

Async usage

Long-lived client

This is the recommended pattern for smart-home systems and other integrations that keep one client alive and reuse it across many calls.

from pydanfossally import DanfossAlly

ally = DanfossAlly(
    timeout=30,
    refresh_device_concurrency=5,
    refresh_device_min_interval=0.10,
    device_discovery_interval=600,
    degraded_refresh_cooldown=600,
    user_agent_prefix="HomeAssistant-DanfossAlly/2026.3.0",
)

authorized = await ally.initialize(key, secret)
if not authorized:
    raise RuntimeError("Authorization failed")

devices = await ally.get_devices()
print(devices)

await ally.aclose()

Context-managed client

This is a good fit for small scripts, one-off tools, and examples where you want automatic resource cleanup.

import asyncio
import os

from pydanfossally import DanfossAlly


async def main() -> None:
    async with DanfossAlly(
        timeout=30,
        refresh_device_concurrency=5,
        refresh_device_min_interval=0.10,
        device_discovery_interval=600,
        degraded_refresh_cooldown=600,
        user_agent_prefix="HomeAssistant-DanfossAlly/2026.3.0",
    ) as ally:
        authorized = await ally.initialize(os.environ["KEY"], os.environ["SECRET"])
        if not authorized:
            raise RuntimeError("Authorization failed")

        devices = await ally.get_devices()
        print(devices)


asyncio.run(main())

Supported OpenAPI endpoints

  • POST /oauth2/token
  • GET /ally/devices
  • GET /ally/devices/{device_id}
  • GET /ally/devices/{device_id}/sub-devices
  • GET /ally/devices/{device_id}/status
  • POST /ally/devices/{device_id}/commands

Notes about the data model

The transport layer follows the OpenAPI file in docs/openapi-spec.

The parsed devices mapping is a best-effort convenience model built from observed status codes. The OpenAPI file documents generic {code, value} pairs, but it does not define all device-specific status or command codes. That means:

  • request/response transport compatibility is covered by the library
  • friendly parsed fields are based on current observed API behavior
  • some status fields may vary between device types

Known gaps

  • The OpenAPI file does not fully document which command code values are supported for all device types.
  • The POST /commands response shape is inconsistent between schema and examples; this client accepts both {"result": true, "t": ...} and {"t": ...}.
  • Live verification should be performed against read-only endpoints before enabling write flows in production integrations.

Refresh behavior

The library uses a hybrid refresh strategy. Bulk reads from GET /ally/devices populate the cache, refresh low-priority devices such as gateways, and run again every 10 minutes to keep discovery current. High-priority devices such as thermostats and room sensors prefer the lighter GET /ally/devices/{device_id}/status endpoint, and the returned statuses are merged with cached metadata before parsing.

If the API responds with HTTP 429 during per-device refreshes, the client enters a temporary bulk-only cooldown. Once the cooldown expires, per-device refreshes resume gradually instead of all at once.

Both knobs are configurable through DanfossAlly(...):

  • refresh_device_concurrency controls how many per-device refreshes may run at once
  • refresh_device_min_interval controls the minimum delay in seconds between starting two per-device refreshes
  • device_discovery_interval controls how often the bulk /ally/devices endpoint is used to discover newly added devices and refresh low-priority ones
  • degraded_refresh_cooldown controls how long the client stays in bulk-only mode after a per-device refresh is rate limited

User-Agent

By default, the client sends a User-Agent header in the form pydanfossally/<version>. Integrations can prepend their own identifier through user_agent_prefix, resulting in a final header such as HomeAssistant-DanfossAlly/2026.3.0 pydanfossally/<version>.

Local verification

The repository includes example.py as a small async read-only example that uses credentials from the environment.

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

pydanfossally-1.1.0.tar.gz (26.3 kB view details)

Uploaded Source

Built Distribution

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

pydanfossally-1.1.0-py3-none-any.whl (27.4 kB view details)

Uploaded Python 3

File details

Details for the file pydanfossally-1.1.0.tar.gz.

File metadata

  • Download URL: pydanfossally-1.1.0.tar.gz
  • Upload date:
  • Size: 26.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pydanfossally-1.1.0.tar.gz
Algorithm Hash digest
SHA256 ac12c8cf3164003a5a0c6f3bcb37252b3a06d99baa3ad7c17e5c9b16a1483beb
MD5 5030cc9263d304dccbfab1b4a23a2120
BLAKE2b-256 055dde581dd60e1b080fed513816f12647f205b7784f657cc8aa8d6f9d84ca5c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydanfossally-1.1.0.tar.gz:

Publisher: pythonpublish.yml on MTrab/pydanfossally

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

File details

Details for the file pydanfossally-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: pydanfossally-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 27.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pydanfossally-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4a9f7b8aed0b926f6fcd60a7bfc88aa8cffcef24385366a9efd075f4fd2f3ba7
MD5 654cbffd60f886bf5848deb1a8858131
BLAKE2b-256 0b5b342b9db22670e66a91344b1753279926b2d00a58ca4db339121fbc697261

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydanfossally-1.1.0-py3-none-any.whl:

Publisher: pythonpublish.yml on MTrab/pydanfossally

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