Home Assistant custom integration for curve control of supply air temperature on ventilation units (primarily Flexit), based on outdoor temperature — the way a heating curve / weather compensation works.
Cold outside → warmer supply air, warm outside → cooler supply air, with a linear transition between configurable breakpoints.
Supply air
22°C │●─────╮
│ ╲
10°C │ ╰──────●
└──┬────────────┬────► Outdoor temperature
5°C 20°C
- Features
- Requirements
- Installation
- Setup
- Entities
- Graphical curve card
- The
ventireg.set_curveservice - How the regulation works
- Troubleshooting
- Limitations
- License
- Multi-point curve (at least 2 points), linear interpolation, flat (clamp) outside the end points.
- Everything configurable in the UI — outdoor sensor, climate entity, curve points, interval, tolerance, rounding step.
- Graphical card with drag-the-points editing (auto-registered, no build step).
- Auto-pause: if anything other than VentiReg changes the setpoint, regulation stops automatically (a manual change is never overwritten).
- Notification: persistent notification in Home Assistant 24 hours after auto-pause occurred.
- Switch for on/off, status sensor (
On/Off/Auto paused) and a sensor for the calculated setpoint. - Rounds the setpoint to 0.5 °C (Flexit step).
- Home Assistant with HACS installed.
- A climate entity (
climate.*) where the target temperature controls the supply air — typically from Flexit Nordic (BACnet) or a Modbus/ESPHome solution. Verify thatclimate.set_temperatureactually moves the supply air setpoint on your unit (see Troubleshooting). - An outdoor temperature sensor (
sensor.*) with a numeric value in °C.
- HACS → Integrations → three dots in the top right → Custom repositories.
- Paste
https://github.com/oleost/VentReg, choose category Integration, and add it. - Search for VentiReg in HACS and install it.
- Restart Home Assistant.
- Settings → Devices & services → Add integration → VentiReg.
HACS → VentiReg → Update → restart HA. Do a hard refresh in the browser (Ctrl/Cmd+Shift+R) so the new card is loaded.
Copy custom_components/ventireg/ to config/custom_components/ in HA, and restart.
When you "Add integration" (and later via Configure) you set:
| Field | Description | Default |
|---|---|---|
| Outdoor temperature sensor | sensor.* measuring outdoors |
– |
| Ventilation (climate) | climate.* where target = supply air temperature |
– |
| Curve points | outdoor:supply, separated by comma/newline, e.g. 5:22, 20:10 |
-5:23, 5:20, 10:18, 20:10 |
| Update interval | Minutes between each computation | 15 |
| Tolerance | °C deviation regarded as an external change | 0.5 |
| Rounding step | Step the setpoint is rounded to | 0.5 |
Curve points format: each point is outdoor_temperature:supply_air_temperature. Decimals use
a period. Points are separated by comma, semicolon or newline. Examples:
-5:23, 5:20, 10:18, 20:10 # four points (default)
5:22, 20:10 # simplest, two points
-20:23, -10:23, 0:22, 10:21, 20:15, 25:15 # multi-point
Settings can be changed at any time via Configure on the integration — without reinstalling anything.
The integration creates one device with the following entities (the actual entity_id may vary
with the HA language — check under Devices & services):
| Entity (typical id) | Type | Description |
|---|---|---|
switch.ventireg_regulation |
switch | On = active regulation. Off = stopped (manually or auto-paused). |
sensor.ventireg_status |
sensor (enum) | On / Off / Auto paused. |
sensor.ventireg_calculated_setpoint¹ |
sensor (°C) | The setpoint the curve gives right now. Has the attributes curve_points, outdoor_temp and status (used by the card). |
¹ The entity id follows your HA language. In English it is
sensor.ventireg_calculated_setpoint, in Norwegian sensor.ventireg_beregnet_settpunkt.
Check the actual id under Settings → Devices & services → VentiReg, and use it in the
card/service configuration below.
The integration registers the card automatically as a Lovelace resource (the way HACS does) — you do not need to add a dashboard resource manually. It happens right after Home Assistant has started. (Requires an HA restart the first time; if you use YAML dashboards, see Troubleshooting.)
Edit the dashboard → + Add card → search VentiReg Curve, or use YAML:
type: custom:ventireg-card
entity: sensor.ventireg_calculated_setpoint # use your actual entity id (see note ¹)
title: Outdoor compensation curve| Field | Required | Description |
|---|---|---|
type |
yes | Must be custom:ventireg-card. |
entity |
yes | The calculated-setpoint sensor (the one with the curve_points attribute). |
title |
no | Card heading. Default "Outdoor compensation curve". |
min_outdoor |
no | Fixed left edge of the X axis (°C). Default about -25. |
max_outdoor |
no | Fixed right edge of the X axis (°C). Default about 30. |
x_step |
no | Outdoor-temperature snapping while dragging (degrees). Default 1. |
- Drag each point freely — left/right changes outdoor temperature, up/down changes supply air.
- A point cannot cross its neighbours (the curve stays in increasing order). Y snaps to
0.5 °C, X to
x_step(default 1°). While dragging, the point'soutdoor° / supply°is shown. - The change is saved when you release, via
ventireg.set_curve. - The dashed line shows the current outdoor temperature, and the dot shows the current setpoint ("ACT SP").
The card is just a nicer way to edit the curve — it can also be changed via Configure (text field) or the service below. All three paths write to the same setting.
Overwrite the curve points from an automation, a script or Developer Tools.
| Parameter | Required | Description |
|---|---|---|
entity_id |
no | Any VentiReg entity of the instance. Can be omitted if you only have one instance. |
curve |
yes | String ("5:22, 20:10") or a list of [outdoor, supply] pairs. |
service: ventireg.set_curve
data:
entity_id: sensor.ventireg_calculated_setpoint # your actual entity id
curve: "0:23, 10:18, 20:10"Every 15 minutes (configurable), and only when the switch is on:
- Read the outdoor temperature and compute the supply air from the curve (linear interpolation, clamped outside the end points).
- Round to 0.5 °C.
- Check first: does the climate setpoint deviate from what VentiReg last set (≥ tolerance)?
- Yes → someone else changed it → auto-pause (switch off, status "Auto paused"), write nothing. After 24 h paused, a persistent notification is sent.
- No → write the curve value to the climate entity and remember it.
Resume: turn the switch back on. VentiReg then resets the reference and writes the curve value immediately (doesn't wait 15 min), so it doesn't pause itself again.
Manual off (you turn the switch off yourself) produces no notification — the notification only applies to auto-pause.
The card doesn't show up / "Custom element doesn't exist: ventireg-card".
Restart HA after installing/updating. The card is registered as a Lovelace resource right after
startup; check Settings → Dashboards → Resources — /ventireg/ventireg-card.js should be
listed. Then do a hard refresh (Ctrl/Cmd+Shift+R). If you use a YAML dashboard (mode: yaml),
resources are managed in YAML — add the resource yourself:
# in the dashboard configuration (or lovelace: resources:)
resources:
- url: /ventireg/ventireg-card.js
type: moduleThe setpoint on the unit doesn't move.
Confirm that climate.set_temperature on your Flexit actually controls the supply air. Test in
Developer Tools → Services: call climate.set_temperature on the entity and see if the supply air
changes. If your unit controls supply air via a number.* entity instead,
open an issue.
It goes to "Auto paused" unexpectedly. Then something else (an app, another automation, a manual change on the panel) changed the setpoint by ≥ tolerance. Increase the tolerance if needed, or turn the switch back on to resume.
Nothing happens / status doesn't change.
Check that the outdoor sensor has a valid numeric value (not unavailable/unknown), and that
the switch is on. Look for "VentiReg" messages in the log.
_last_set(the reference for pause detection) is kept in memory and saved to disk, but an external change made while HA was down is not detected until the next normal cycle.- The card lets you drag the points freely (outdoor + supply), but cannot add/remove points in the graph yet — use the text field under Configure to change the number of points.
- The interpolation is linear and clamps outside the end points (no extrapolation).
See CLAUDE.md for architecture and design choices.