Build a proper HACS custom component for Home Assistant called fritz_smart_offset. The goal is to automatically calibrate AVM Fritz!Box DECT radiator thermostats (FRITZ!Smart Thermo 301/302) using any HA-compatible external temperature sensor, replicating what the expensive FRITZ!DECT 440 Taster does natively.
Fritz!Box DECT thermostats have a valve-mounted temperature sensor that reads high due to proximity to the hot radiator pipe. Fritz!Box corrects this via a configurable offset (Temperaturabweichung). When a DECT 440 is paired, Fritz!Box automatically updates this offset using the 440's room temperature reading — confirmed via the Fritz!Box UI label "Automatische Offset-Anpassung". The valve always uses its own sensor + offset for local on/off control; the offset is the only correction mechanism.
The offset is not exposed via:
- The official AHA HTTP Interface (
/webservices/homeautoswitch.lua) — readable only - The new Fritz!Box Smart Home REST API (FritzOS 8.20, v0.9.5) — not present at all
The only way to write the offset is via the Fritz!Box internal web UI backend. This has been verified working on FritzOS 8.20 via browser DevTools:
Authentication: POST to /login_sid.lua?version=2 using PBKDF2-HMAC-SHA256 challenge-response.
Write offset: POST to /data.lua with these parameters (all required, verified by testing minimal payloads):
xhr=1
sid={session_id}
device={device_ain} # e.g. "13979 0387192"
Offset={value} # float, 0.5°C increments e.g. "-1.5"
WindowOpenTimer={int} # 1-120, required by backend validation
WindowOpenTrigger={int} # required
ule_device_name={name} # required, causes SetName error if missing
apply=
page=home_auto_hkr_edit
lang=de
Response on success: {"data":{"redirect":{...},"apply":"ok"}}
The Fritz!Box SPA (#/ routing) still uses this same backend endpoint — the frontend changed but the API did not.
- Calculate offset:
external_sensor_temp - valve_sensor_temp, rounded to nearest 0.5°C - Filter to comfort mode only: Only sample/apply when the Fritz!Box comfort mode sensor equals
"comfort"(HA entity:sensor.{device}_aktuelle_geplante_voreinstellung) - Rolling average: Use a configurable time window (default 48h) of comfort-mode-only samples to smooth out the spike when the valve is fully open. Samples return
unavailableoutside comfort mode, which the statistics sensor skips. - Apply offset: Write to Fritz!Box via the endpoint above
- Expose sensors: Current calculated offset, 48h average offset, last applied offset
custom_components/fritz_smart_offset/
__init__.py
manifest.json
config_flow.py # UI setup: Fritz!Box host/user/pass, device AIN(s), external sensor, window timer/trigger values
const.py
coordinator.py # Handles auth, offset calculation, Fritz!Box write
sensor.py # Exposes offset sensors
services.yaml # fritz_smart_offset.apply_offset service
strings.json
translations/
en.json
de.json
- Fritz!Box hostname (default:
fritz.box) - Fritz!Box username + password
- One or more thermostat devices: each needs AIN, display name,
WindowOpenTimer,WindowOpenTrigger, and the associated valve temperature sensor entity - External room temperature sensor entity (the one mounted away from the radiator)
- Comfort mode sensor entity (e.g.
sensor.heizung_wohnzimmer_aktuelle_geplante_voreinstellung) - Rolling average window in hours (default: 48)
- Update interval in minutes (default: 60)
- Use
aiohttp(available in HA) for all HTTP requests - Auth should be re-done on each update cycle (SIDs expire after ~20 min inactivity)
- The offset calculation sensor should return
unavailablewhen not in comfort mode so the statistics average only includes relevant samples - Should support multiple thermostats per config entry (e.g. two radiators in one room sharing the same external sensor)
- Include a
fritz_smart_offset.apply_offsetservice that applies immediately on demand, plus automatic updates on the configured interval - Store credentials in HA's encrypted config entry storage, not plaintext YAML
- This integration is inherently fragile (undocumented endpoint) — include a clear warning in the README and a persistent notification if the Fritz!Box write fails after a firmware update
- Fritz!Box 5530 Fiber, FritzOS 8.20
- External sensor: IKEA TIMMERFLOTTE (Matter over Thread, temperature + humidity)
- Thermostats: FRITZ!Smart Thermo 301 (Heizkörper Fenster, AIN
13979 0387192) and FRITZ!Smart Thermo 301 (Heizkörper Wintergarten) - HA at 192.168.178.34, Fritz!Box at fritz.box