An open API service indexing awesome lists of open source software.

https://github.com/oleost/ventreg

Home Assistant: kurvestyring av tilluftstemperatur (Flexit) basert på utetemperatur
https://github.com/oleost/ventreg

flexit hacs heating-curve home-assistant homeassistant-integration ventilation

Last synced: 15 days ago
JSON representation

Home Assistant: kurvestyring av tilluftstemperatur (Flexit) basert på utetemperatur

Awesome Lists containing this project

README

          

# VentiReg

[![hacs_badge](https://img.shields.io/badge/HACS-Custom-41BDF5.svg)](https://github.com/hacs/integration)
[![GitHub release](https://img.shields.io/github/v/release/oleost/VentReg?include_prereleases&sort=semver)](https://github.com/oleost/VentReg/releases)
[![License](https://img.shields.io/github/license/oleost/VentReg)](LICENSE)

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

## Contents

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Setup](#setup)
- [Entities](#entities)
- [Graphical curve card](#graphical-curve-card)
- [The `ventireg.set_curve` service](#the-ventiregset_curve-service)
- [How the regulation works](#how-the-regulation-works)
- [Troubleshooting](#troubleshooting)
- [Limitations](#limitations)
- [License](#license)

## Features

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

## Requirements

- Home Assistant with [HACS](https://hacs.xyz/) installed.
- A **climate entity** (`climate.*`) where the **target temperature controls the supply air** —
typically from [Flexit Nordic (BACnet)](https://www.home-assistant.io/integrations/flexit_bacnet/)
or a Modbus/ESPHome solution. Verify that `climate.set_temperature` actually moves the supply
air setpoint on your unit (see [Troubleshooting](#troubleshooting)).
- An **outdoor temperature sensor** (`sensor.*`) with a numeric value in °C.

## Installation

### Via HACS (recommended)

1. HACS → **Integrations** → three dots in the top right → **Custom repositories**.
2. Paste `https://github.com/oleost/VentReg`, choose category **Integration**, and add it.
3. Search for **VentiReg** in HACS and install it.
4. **Restart Home Assistant.**
5. **Settings → Devices & services → Add integration → VentiReg.**

### Updating

HACS → VentiReg → **Update** → restart HA. Do a hard refresh in the browser
(Ctrl/Cmd+Shift+R) so the new card is loaded.

### Manual installation

Copy `custom_components/ventireg/` to `config/custom_components/` in HA, and restart.

## Setup

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.

## Entities

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.

## Graphical curve card

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](#troubleshooting).)

### Add the card to a dashboard

Edit the dashboard → **+ Add card** → search **VentiReg Curve**, or use YAML:

```yaml
type: custom:ventireg-card
entity: sensor.ventireg_calculated_setpoint # use your actual entity id (see note ¹)
title: Outdoor compensation curve
```

### Card options

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

### Usage

- **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's `outdoor° / 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.

## The `ventireg.set_curve` service

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

```yaml
service: ventireg.set_curve
data:
entity_id: sensor.ventireg_calculated_setpoint # your actual entity id
curve: "0:23, 10:18, 20:10"
```

## How the regulation works

Every 15 minutes (configurable), and only when the switch is **on**:

1. Read the outdoor temperature and compute the supply air from the curve (linear interpolation,
clamped outside the end points).
2. Round to 0.5 °C.
3. **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.

## Troubleshooting

**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:

```yaml
# in the dashboard configuration (or lovelace: resources:)
resources:
- url: /ventireg/ventireg-card.js
type: module
```

**The 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](https://github.com/oleost/VentReg/issues).

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

## Limitations

- `_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](CLAUDE.md) for architecture and design choices.

## License

[MIT](LICENSE)