Skip to main content

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,
    hot_refresh_timeout=300,
    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,
        hot_refresh_timeout=300,
        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

Each refresh_devices() call always starts with a bulk read from GET /ally/devices.

After successful write operations (set_mode(...) and send_command(...)), the target device is tracked as pending hot refresh. While pending, refresh_devices() also calls GET /ally/devices/{device_id}/status for that device.

Hot refresh for a pending device stops when either of these conditions is met:

  • the latest bulk snapshot differs from the baseline state captured when the write succeeded
  • the hot refresh timeout is reached (default: 300 seconds / 5 minutes)

The refresh tuning knobs are configurable through DanfossAlly(...):

  • refresh_device_concurrency controls how many status hot refresh calls may run at once
  • refresh_device_min_interval controls the minimum delay in seconds between starting two status hot refresh calls
  • hot_refresh_timeout controls how long a device stays in pending hot refresh mode

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>.

Writable temperature helpers

The client includes explicit helpers for several writable temperature-like settings:

  • set_upper_temp(device_id, temp)
  • set_lower_temp(device_id, temp)
  • set_at_home_setting(device_id, temp)
  • set_leaving_home_setting(device_id, temp)
  • set_holiday_setting(device_id, temp)
  • set_pause_setting(device_id, temp)

These helpers validate values before writing them:

  • minimum 5.0
  • maximum 35.0
  • only 0.5 degree steps

Example:

devices = await ally.get_devices()
device = devices["device-1"]

await ally.set_upper_temp("device-1", 28.0)
await ally.set_lower_temp("device-1", 7.0)
await ally.set_at_home_setting("device-1", 21.5)
await ally.set_leaving_home_setting("device-1", 17.0)
await ally.set_holiday_setting("device-1", 15.0)
await ally.set_pause_setting("device-1", 8.0)

await ally.refresh_device("device-1")
device = ally.devices["device-1"]

print(device["upper_temp"])
print(device["lower_temp"])
print(device["at_home_setting"])
print(device["leaving_home_setting"])
print(device["holiday_setting"])
print(device["pause_setting"])

Read access for these values is exposed through the parsed device state returned by get_devices(), get_device(), refresh_device(), and refresh_devices(). The library does not currently include dedicated getter methods for these fields because they are already part of the normal device model.

Local verification

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

Metadata

Release files for pydanfossally 1.3.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 pydanfossally 1.3.0
File Size Uploaded Provenance
pydanfossally-1.3.0.tar.gz 26.7 kB With provenance Details

Built distribution (wheel)

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

Total release size: 54.2 kB

Release files / pydanfossally-1.3.0.tar.gz

Download URL pydanfossally-1.3.0.tar.gz
Size 26.7 kB
Tags Source
SHA-256 checksum
How to use checksums
aec8a409ca6c352d22a612a9b26e502a0d6fc18c3a82db2a8447299ca28a6cb3
BLAKE2b-256 checksum
How to use checksums
83be243253b16f8b08793281862f7b709bc88da9264f78da73843eeef6337536
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Apr 1, 2026.

Transparency log

Release files / pydanfossally-1.3.0-py3-none-any.whl

Download URL pydanfossally-1.3.0-py3-none-any.whl
Size 27.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c4505f851e062ad60b58e9f5a8e896703ced61d0f2ab694a54bcc15c7d68db88
BLAKE2b-256 checksum
How to use checksums
188126d335fcdd8efdf96a598aafb04ad378f18041f7fdc06b66c310e33dbdfc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Apr 1, 2026.

Transparency log

Security for pydanfossally 1.3.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pydanfossally-1.3.0.tar.gz

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 Apr 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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