Danfoss Ally API library
Project description
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/tokenGET /ally/devicesGET /ally/devices/{device_id}GET /ally/devices/{device_id}/sub-devicesGET /ally/devices/{device_id}/statusPOST /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
codevalues are supported for all device types. - The
POST /commandsresponse 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_concurrencycontrols how many per-device refreshes may run at oncerefresh_device_min_intervalcontrols the minimum delay in seconds between starting two per-device refreshesdevice_discovery_intervalcontrols how often the bulk/ally/devicesendpoint is used to discover newly added devices and refresh low-priority onesdegraded_refresh_cooldowncontrols 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
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac12c8cf3164003a5a0c6f3bcb37252b3a06d99baa3ad7c17e5c9b16a1483beb
|
|
| MD5 |
5030cc9263d304dccbfab1b4a23a2120
|
|
| BLAKE2b-256 |
055dde581dd60e1b080fed513816f12647f205b7784f657cc8aa8d6f9d84ca5c
|
Provenance
The following attestation bundles were made for pydanfossally-1.1.0.tar.gz:
Publisher:
pythonpublish.yml on MTrab/pydanfossally
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydanfossally-1.1.0.tar.gz -
Subject digest:
ac12c8cf3164003a5a0c6f3bcb37252b3a06d99baa3ad7c17e5c9b16a1483beb - Sigstore transparency entry: 1155299094
- Sigstore integration time:
-
Permalink:
MTrab/pydanfossally@82c8033cadf474494fb23c092870d246ff4c637f -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/MTrab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pythonpublish.yml@82c8033cadf474494fb23c092870d246ff4c637f -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a9f7b8aed0b926f6fcd60a7bfc88aa8cffcef24385366a9efd075f4fd2f3ba7
|
|
| MD5 |
654cbffd60f886bf5848deb1a8858131
|
|
| BLAKE2b-256 |
0b5b342b9db22670e66a91344b1753279926b2d00a58ca4db339121fbc697261
|
Provenance
The following attestation bundles were made for pydanfossally-1.1.0-py3-none-any.whl:
Publisher:
pythonpublish.yml on MTrab/pydanfossally
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydanfossally-1.1.0-py3-none-any.whl -
Subject digest:
4a9f7b8aed0b926f6fcd60a7bfc88aa8cffcef24385366a9efd075f4fd2f3ba7 - Sigstore transparency entry: 1155299095
- Sigstore integration time:
-
Permalink:
MTrab/pydanfossally@82c8033cadf474494fb23c092870d246ff4c637f -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/MTrab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pythonpublish.yml@82c8033cadf474494fb23c092870d246ff4c637f -
Trigger Event:
release
-
Statement type: