---
title: "EMS-ESP Gas Boiler (Bosch, Buderus, Junkers, Nefit)"
description: "Set heating circuit mode, room and DHW setpoints and read flow temperature, burner power, pressure and last error code of EMS gas boilers via EMS-ESP."
url: "https://taphome.com/en/compatibility/ems-esp-gas-boiler-http/"
language: en
lastmod: 2026-10-18
generator: hugo
ai:
  topics: ["http","boiler","ems-bus","rest-api","gateway","wifi","ethernet","dhw"]
  questions: ["Is my Buderus, Bosch, Junkers or Nefit gas boiler compatible with TapHome?","How to integrate a gas boiler with TapHome via EMS-ESP?","What does the EMS-ESP gas boiler TapHome template read and control?","How to connect the BBQKees EMS-ESP gateway to the boiler and to TapHome?","Why does the heating circuit mode show an error with my controller?","Why does an EMS-ESP device show \"no value from the gateway\" or error 401 in TapHome?"]
---

# EMS-ESP Gas Boiler (Bosch, Buderus, Junkers, Nefit)

Communication: Packet Parser → HTTP

- [BBQKees Electronics Official Website](https://bbqkees-electronics.nl)
- [BBQKees Gateway E32 V2 KIT Product Page](https://bbqkees-electronics.nl/product/gateway-e32-v2-ethernet-wifi-edition-v2-kit/)

> Network address
> 
> TapHome reaches this device at the address entered on import. Give the device a fixed address — an IP reservation in the router, or its mDNS name if it supports one — otherwise the integration stops working when the router changes the address.
> 
> [Network Preparation](https://taphome.com/en/docs/setup/network-preparation/)

## Integration guide

The EMS-ESP Gas Boiler template connects TapHome to a Bosch, Buderus, Junkers or Nefit gas boiler through an EMS-ESP gateway — a BBQKees Electronics Gateway E32 V2 that runs the open-source EMS-ESP firmware and plugs into the EMS bus of the boiler. TapHome talks to the gateway over its local HTTP REST API (port 80, JSON); no cloud connection is needed. In EMS-ESP the boiler appears as device type `boiler` and its controller as device type `thermostat`.

The template reads whether the boiler is heating or making hot water, the flow temperature and its target, the burner power, the last error code stored by the boiler, the system pressure, the burner starts, the outdoor temperature and the room and hot water temperatures. With an access token it also sets the mode of heating circuit 1 (Off, Manual, Auto), the room setpoint and the hot water setpoint.

> [!WARNING]
> **Community template.** The template was generated in the TapHome portal and written against **EMS-ESP 3.8.6**. Get it from the TapHome portal: [EMS-ESP Gas Boiler — community template](https://portal.taphome.com/portal/community/ems-esp-gas-boiler-http) (download the XML — no sign-in needed — and import it as a new module).

**[EMS-ESP Gas Boiler (Bosch / Buderus / Junkers / Nefit)](https://portal.taphome.com/en/portal/community/ems-esp-gas-boiler-http)** — EMS-ESP, HTTP. EMS-ESP 3.8.6 REST template for Bosch, Buderus, Junkers and Nefit gas boilers on the EMS bus: heating circuit mode, room and DHW setpoints, burner, pressure, temperatures and last error code.

## Compatible boilers and controllers

Two things decide whether a boiler works with this template: EMS-ESP must support the boiler, and the boiler and its controller must report the values the template reads.

Boilers covered by the template:

- Buderus GB125, GB135, GB162, GBx72, GB192, GB192i.2, Logamax Plus GB022, U122
- Bosch / Junkers Cerapur GC2200W, Cerapur Top, Condens 2500, GC9000
- Nefit Topline, Trendline
- Worcester Greenstar Si, 30Ri Compact, 8000

The [EMS-ESP list of supported boilers](https://docs.emsesp.org/Boilers) names further models, for example Logano, Nefit Proline and Smartline, Condens 2300 and 5000i.

The gateway works with the EMS, EMS Plus (EMS+), EMS2 and Heatronic 3 bus variants. Older boilers with the iRT bus, such as the Nefit Ecomline or the Buderus GB112, can use the gateway only after a Bosch EasyControlAdapter is installed. OpenTherm is not among the bus types the gateway supports.

Which values a given boiler reports is not documented per model. The Devices page of the EMS-ESP web interface shows only entities that have a value; an entity that exists in EMS-ESP but has no value is supported by the firmware, not by the connected boiler. The same list is available at `http://<gateway-ip>/api/boiler/entities` and `http://<gateway-ip>/api/thermostat/entities`.

**Heating circuit mode** depends on the controller, because each controller family has its own list of modes:

| Controller | Modes in EMS-ESP | Heating Circuit Mode |
|---|---|---|
| RC300, RC310, RC100, HMC310, Rego 2000 / 3000 | manual, auto | Manual and Auto; selecting Off ends in a write error |
| BC400, UI800, CR120 | off, manual, auto | Off, Manual and Auto |
| RC35, Junkers controllers and other models | other lists (for example RC35: night, day, auto; Junkers: nofrost, eco, heat, auto) | not supported — the device ends in an error, delete it |

Junkers and Nefit boilers are often paired with Junkers or Nefit controllers that have another mode list. The boiler devices of the template do not depend on the controller and keep working.

Some controllers do not accept EMS write commands and appear in EMS-ESP as read-only devices: Buderus Logamatic TC100, Bosch EasyControl CT200, Junkers CT100, Moduline Easy, Junkers FW / FR built before 9/2008 and Tado thermostats. With them the mode and the room setpoint cannot be changed from TapHome.

## Hardware connection

The BBQKees Gateway E32 V2 KIT contains the gateway, a 150 cm EMS service cable, a 100 cm EMS screw terminal cable, an EMS service port adapter plug, a power supply (12 V DC barrel jack or 5 V USB-C, depending on the production batch) and a JST ZH cable for own DS18B20 temperature sensors. The gateway connects to the boiler in one of three ways:

| Connection on the boiler | Cable | Power |
|---|---|---|
| EMS service jack (3.5 mm) | 150 cm EMS service cable | from the service jack |
| EMS service jack (3.5 mm) | 150 cm EMS service cable | external power supply |
| EMS bus screw terminals | 100 cm EMS screw terminal cable | external power supply (12 V DC or 5 V USB-C) |

The service jack is an option only when the boiler has one. Gateways sold from summer 2025 onward accept both types of power supply. The [BBQKees EMS Gateway Wiki](https://bbqkees-electronics.nl/wiki/) shows how to connect the gateway to a specific boiler.

- **Network:** Ethernet (RJ45) or Wi-Fi. EMS-ESP connects only to 2.4 GHz WPA2 Wi-Fi networks, not to 5 GHz.
- **Firmware:** EMS-ESP. The Gateway E32 V2 (sold from January 2024) has PSRAM and uses the `ESP32-16MB+` firmware variant. The firmware is updated in the EMS-ESP web interface under Settings → Version.

## Configuration

### First-time setup of EMS-ESP

1. On the first start EMS-ESP opens a Wi-Fi access point `ems-esp` (WPA password `ems-esp-neo`). A gateway on Ethernet is reachable on the IP address the router assigned to it.
2. Sign in with the default user `admin` / `admin` and change the password.
3. Connect the gateway to the home network in Settings → Network (Wi-Fi or Ethernet).
4. Reserve a fixed IP address for the gateway in the router (DHCP reservation) — the template addresses the gateway by its IP address.

### EMS-ESP settings that matter

- **Temperatures in °C** — keep "Convert temperature values to Fahrenheit" off in Settings → Application. The module checks this every 60 s and shows an error when EMS-ESP reports °F.
- **Language: English** — keep Language in Settings → Application on English. The Heating Circuit Mode device recognises the mode by its option text (`off`, `manual`, `auto`), and EMS-ESP translates these texts into the selected language; with another language the device ends in an error that names the reported text. Writes use the English texts, which EMS-ESP accepts in every language, and the other devices do not depend on the language.
- **Boolean Format and Enum Format** do not matter. The template reads the `index` and `bool` keys and the numeric `value` of the EMS-ESP entity detail, which do not depend on these settings.
- **Firmware 3.8** — the module shows a warning when the gateway reports a version outside the 3.8 series. In 3.7.0 the hot water entities moved from the `ww` prefix to the nested `dhw` object and EMS-ESP got a separate mode list for BC400-type controllers; between 3.8.0 and 3.8.6 the entities used by the template did not change.

### Access token for writes

Reading needs no authentication. Writing — heating circuit mode, room and hot water setpoints — needs the EMS-ESP access token of a user with admin rights:

1. Open the EMS-ESP web interface → Settings → Security → Manage Users.
2. Click the key icon of a user with admin rights and copy the token. The token has no expiry date.
3. Paste the token into the `AccessToken` import parameter when importing the template.

Without a token the integration is read-only and every write ends in error 401. Do not switch on "Bypass Access Token authorization on API calls" in EMS-ESP instead — it makes the API open, and the EMS-ESP documentation does not recommend it.

### Import parameters

| Parameter | Description |
|---|---|
| `IpAddress` | IP address of the EMS-ESP gateway |
| `AccessToken` | EMS-ESP access token of an admin user — needed only for writes; leave it empty for a read-only integration |

## Device capabilities

### Heating circuit 1

- **Heating Circuit Mode** — Off, Manual or Auto for heating circuit 1. The device reads the position in the mode list of the controller, looks up its option text and shows Off, Manual or Auto; it writes the English option text. Which modes work depends on the controller (see the table above).
- **Room Thermostat** — current and selected room temperature of heating circuit 1 as reported by the controller. The setpoint range of the device is 0–30 °C. EMS-ESP keeps the room setpoint in 0.5 °C steps; the template sends the value unchanged.

### Boiler status

- **Heating Active** — Active while the boiler runs for space heating.
- **Tap Water Heating Active** — Active while the boiler heats domestic hot water.

### Temperatures

- **Flow Temperature** — current flow temperature of the boiler, with 0.1 °C resolution.
- **Flow Temperature Target** — the flow temperature the boiler is aiming for (0–90 °C), set by the controller. The device is read-only on purpose: EMS-ESP could write this value, but a written flow temperature would override the room controller.
- **Outdoor Temperature** — outside temperature as reported by the boiler, with 0.1 °C resolution.

### Burner and system pressure

- **Burner Power** — current burner output in percent. The device also reads the last error code stored by the boiler and shows it as the info message "Last error code (stored by the boiler): …", for example `2E(207) 100.75.2000 65:00 (0 min)`. This is the code the boiler stored last, with its date and duration — not necessarily an active fault; the message stays after the fault is gone. When the error code cannot be read, the device shows a warning and the burner power stays available.
- **Burner Starts** — total number of burner starts counted by the boiler.
- **System Pressure** — water pressure of the heating system in bar, with 0.1 bar resolution.

### Domestic hot water

- **Domestic Hot Water** — current and selected hot water temperature of the boiler. The setpoint range of the device is 10–70 °C, the setpoint is sent in whole degrees and the boiler enforces its own limits.

The template writes the hot water setpoint of the boiler (`dhw.seltemp`), not the hot water settings of the controller (`dhw.settemp`, `dhw.mode`). The EMS-ESP documentation notes that boiler settings managed by the controller are overwritten by it, so a controller that manages hot water may overwrite the setpoint set in TapHome.

### How the template talks to EMS-ESP

Each device reads its own values with one HTTP GET per entity on `/api/<device>/[hc1/|dhw/]<entity>` and takes the `value`, `index` or `bool` key of the answer. Most devices poll every 30 s; System Pressure and Outdoor Temperature poll every 60 s and Burner Starts every 5 minutes. The module reads `/api/system/info` every 60 s. Writes are HTTP POST requests with a JSON body and the access token in the `Authorization: Bearer` header.

EMS-ESP 3.8.3 and newer answers `429 Too Many Requests` to a GET that arrives less than 50 ms after the previous API call. The template therefore waits 60 ms before each GET and retries once after 200 ms when it gets 429. Another client polling the EMS-ESP API at the same time (for example a second home automation system) can still cause an occasional retry.

> [!NOTE]
> **Why REST and not Modbus.** EMS-ESP also offers Modbus TCP, but its register offsets moved between the stable releases 3.8.0 and 3.8.6, so a Modbus template would silently read other values after a firmware update of the gateway. The REST API addresses values by name — a renamed entity ends in a visible device error instead.

## Troubleshooting

### Device error "no value from the gateway"

The message "no value from the gateway — this controller or unit does not report it; delete this device" means the connected boiler or controller does not report this entity. Check the Devices page of EMS-ESP or `http://<gateway-ip>/api/boiler/entities` and `http://<gateway-ip>/api/thermostat/entities`, then delete the device after the import — the other devices keep working.

### Device error 404

A `404` with a message such as `no 'xyz' in thermostat` means that EMS-ESP does not know the entity under this path — the controller or boiler does not have it, or the firmware uses another name. `unknown device` means EMS-ESP has not detected a boiler or controller of that type on the EMS bus.

### Heating Circuit Mode reports another text

The error "hc1.mode reports '…'" appears when EMS-ESP reports a mode text other than `off`, `manual` or `auto`. Either the EMS-ESP Language is not English (set it to English in Settings → Application), or the controller uses another mode list (for example RC35 or a Junkers controller) — then delete the Heating Circuit Mode device.

### Selecting Off ends in a write error

Controllers of the RC300 family (RC300, RC310, RC100, HMC310, Rego 2000 / 3000) have no off mode. EMS-ESP refuses a value that is not in the list of the controller, so the device shows a write error (`hc1.mode write: HTTP …`). Use Manual or Auto with these controllers.

### Write fails with error 401

The access token is missing or wrong. Copy it again from Settings → Security → Manage Users → key icon of an admin user and enter it into the `AccessToken` variable of the module. The token is derived from the user name and the super user password in Settings → Security → Security Settings.

### Error 429

Another client polls the EMS-ESP API at the same moment. The template already paces its own requests and retries once; reduce the polling rate of the other client if the error repeats.

### Module error or warning

- "EMS-ESP reports °F" — switch Fahrenheit off in Settings → Application.
- "Template written for EMS-ESP 3.8.6, gateway reports …" — the gateway runs firmware outside the 3.8 series. Update EMS-ESP in Settings → Version.

### Gateway not reachable

1. Check the gateway LED: 1 blue flash during boot = EMS bus not connected yet (check the cable and the EMS Tx Mode setting), 2 red flashes = network still connecting (check Settings → Network; Wi-Fi must be 2.4 GHz WPA2), steady light = EMS data is flowing.
2. Open `http://<gateway-ip>/api/system/info` in a browser — if it answers, the gateway is reachable.
3. If the IP address has changed, open the mDNS name `http://ems-esp.local` to find the gateway, then set a DHCP reservation in the router.
4. Use `http://` — the EMS-ESP API does not support HTTPS with self-signed certificates.

## Available devices 11

These devices appear in TapHome after import.

EMS-ESP Gateway Module

Custom Variables

`AccessToken` (string) EMS-ESP access token of a user with admin rights, sent as Bearer header with every write (heating circuit mode, room and hot water setpoints); reads work without it, so an empty token gives a read-only integration

EMS-ESP web interface → Settings → Security → Manage Users → key icon of a user with admin rights; paste the token into the AccessToken import parameter. The token has no expiry date.

Read (module)

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/system/info");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/system/info");
END
IF r.IsSuccess = false
    ADDERROR("system/info: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
ELSE
    VAR fahrenheit := PARSEJSON(r.Content, "settings.fahrenheit", true);
    IF fahrenheit
        ADDERROR("EMS-ESP reports \u00b0F \u2014 switch Fahrenheit off in EMS-ESP Settings \u2192 Application");
    END
    VAR version := PARSEJSON(r.Content, "system.version", true);
    IF !ISNULL(version)
        IF INDEXOF(TOSTRING(version), "3.8.") != 0
            ADDWARNING("Template written for EMS-ESP 3.8.6, gateway reports " + version);
        END
    END
END
```

Heating Circuit Mode Multi-value Switch Read and write

Operating mode of heating circuit 1 — Off, Manual or Auto; RC300-family controllers offer only Manual and Auto, BC400 / UI800 / CR120 also Off; needs EMS-ESP Language set to English

enum json\_path

Values / States: Off · Manual · Auto

Read switch state

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/thermostat/hc1/mode");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/thermostat/hc1/mode");
END
IF r.IsSuccess = false
    ADDERROR("hc1.mode: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR enumList := PARSEJSON(r.Content, "enum", true);
VAR idx := PARSEJSON(r.Content, "index", true);
IF ISNULL(enumList) OR ISNULL(idx)
    ADDERROR("hc1.mode: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
VAR text := PARSEJSON(r.Content, "$.enum[" + TOSTRING(idx) + "]", true);
IF ISNULL(text)
    ADDERROR("hc1.mode: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
IF text = "off"
    RETURN(0);
ELSEIF text = "manual"
    RETURN(1);
ELSEIF text = "auto"
    RETURN(2);
ELSE
    ADDERROR("hc1.mode reports '" + text + "': this template supports controllers with off / manual / auto and needs EMS-ESP Language = English (Settings \u2192 Application)");
    RETURN(NaN);
END
```

Write switch state

```taphome
VAR modeName := IF(Mu = 0, "off", IF(Mu = 1, "manual", "auto"));
VAR body := "{\"value\":\"" + modeName + "\"}";
VAR r := SENDHTTPREQUEST("/api/thermostat/hc1/mode", "POST", body, "Content-Type: application/json", "Authorization: Bearer " + AccessToken);
IF r.IsSuccess = false
    IF r.StatusCode = 401
        ADDERROR("hc1.mode write: access token missing or wrong (EMS-ESP Settings \u2192 Security \u2192 Manage Users \u2192 key icon of an admin user)");
    ELSE
        ADDERROR("hc1.mode write: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    END
END
```

Room Thermostat Thermostat Read and write

Current and selected room temperature of heating circuit 1 from the controller; setpoint 0–30 °C, kept by EMS-ESP in 0.5 °C steps

numeric Unit: °C

Read temperature

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/thermostat/hc1/currtemp");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/thermostat/hc1/currtemp");
END
IF r.IsSuccess = false
    ADDERROR("hc1.currtemp: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "value", true);
IF ISNULL(v)
    ADDERROR("hc1.currtemp: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Read desired temperature

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/thermostat/hc1/seltemp");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/thermostat/hc1/seltemp");
END
IF r.IsSuccess = false
    ADDERROR("hc1.seltemp: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "value", true);
IF ISNULL(v)
    ADDERROR("hc1.seltemp: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Write desired temperature

```taphome
VAR body := "{\"value\":" + Se + "}";
VAR r := SENDHTTPREQUEST("/api/thermostat/hc1/seltemp", "POST", body, "Content-Type: application/json", "Authorization: Bearer " + AccessToken);
IF r.IsSuccess = false
    IF r.StatusCode = 401
        ADDERROR("hc1.seltemp write: access token missing or wrong (EMS-ESP Settings \u2192 Security \u2192 Manage Users \u2192 key icon of an admin user)");
    ELSE
        ADDERROR("hc1.seltemp write: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    END
END
```

Heating Active Reed Contact Read-only

Active while the boiler runs for space heating

boolean

Read

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/boiler/heatingactive");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/boiler/heatingactive");
END
IF r.IsSuccess = false
    ADDERROR("heatingactive: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "bool", true);
IF ISNULL(v)
    ADDERROR("heatingactive: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Tap Water Heating Active Reed Contact Read-only

Active while the boiler heats domestic hot water

boolean

Read

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/boiler/tapwateractive");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/boiler/tapwateractive");
END
IF r.IsSuccess = false
    ADDERROR("tapwateractive: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "bool", true);
IF ISNULL(v)
    ADDERROR("tapwateractive: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Flow Temperature Temperature Sensor Read-only

numeric Unit: °C

Read temperature

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/boiler/curflowtemp");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/boiler/curflowtemp");
END
IF r.IsSuccess = false
    ADDERROR("curflowtemp: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "value", true);
IF ISNULL(v)
    ADDERROR("curflowtemp: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Flow Temperature Target Variable Read-only

Flow temperature the boiler is aiming for (0–90 °C), set by the controller; read-only, so TapHome never overrides the controller

numeric Unit: °C

Read

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/boiler/selflowtemp");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/boiler/selflowtemp");
END
IF r.IsSuccess = false
    ADDERROR("selflowtemp: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "value", true);
IF ISNULL(v)
    ADDERROR("selflowtemp: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Burner Power Variable Read-only

Current burner output in percent; also shows the last error code stored by the boiler as an info message — not necessarily an active fault

numeric Unit: %

Read

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/boiler/curburnpow");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/boiler/curburnpow");
END
IF r.IsSuccess = false
    ADDERROR("curburnpow: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "value", true);
IF ISNULL(v)
    ADDERROR("curburnpow: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Read (module)

```taphome
SLEEP(60);
VAR rlc := SENDHTTPREQUEST("/api/boiler/lastcode");
IF rlc.StatusCode = 429
    SLEEP(200);
    rlc := SENDHTTPREQUEST("/api/boiler/lastcode");
END
IF rlc.IsSuccess = false
    ADDWARNING(1, "lastcode: HTTP " + rlc.StatusCode + IF(ISNULL(PARSEJSON(rlc.Content, "message", true)), "", ": " + PARSEJSON(rlc.Content, "message", true)));
ELSE
    VAR lc := PARSEJSON(rlc.Content, "value", true);
    IF !ISNULL(lc)
        ADDINFO(1, "Last error code (stored by the boiler): " + lc);
    END
END
```

System Pressure Variable Read-only

Water pressure of the heating system in bar

numeric Unit: bar

Read

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/boiler/syspress");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/boiler/syspress");
END
IF r.IsSuccess = false
    ADDERROR("syspress: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "value", true);
IF ISNULL(v)
    ADDERROR("syspress: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Burner Starts Variable Read-only

Total number of burner starts counted by the boiler

numeric

Read

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/boiler/burnstarts");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/boiler/burnstarts");
END
IF r.IsSuccess = false
    ADDERROR("burnstarts: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "value", true);
IF ISNULL(v)
    ADDERROR("burnstarts: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Domestic Hot Water Thermostat Read and write

Current and selected hot water temperature of the boiler; the setpoint is sent in whole degrees and the boiler applies its own limits

numeric Unit: °C

Read temperature

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/boiler/dhw/curtemp");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/boiler/dhw/curtemp");
END
IF r.IsSuccess = false
    ADDERROR("dhw.curtemp: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "value", true);
IF ISNULL(v)
    ADDERROR("dhw.curtemp: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Read desired temperature

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/boiler/dhw/seltemp");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/boiler/dhw/seltemp");
END
IF r.IsSuccess = false
    ADDERROR("dhw.seltemp: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "value", true);
IF ISNULL(v)
    ADDERROR("dhw.seltemp: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

Write desired temperature

```taphome
VAR body := "{\"value\":" + ROUND(Se) + "}";
VAR r := SENDHTTPREQUEST("/api/boiler/dhw/seltemp", "POST", body, "Content-Type: application/json", "Authorization: Bearer " + AccessToken);
IF r.IsSuccess = false
    IF r.StatusCode = 401
        ADDERROR("dhw.seltemp write: access token missing or wrong (EMS-ESP Settings \u2192 Security \u2192 Manage Users \u2192 key icon of an admin user)");
    ELSE
        ADDERROR("dhw.seltemp write: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    END
END
```

Outdoor Temperature Temperature Sensor Read-only

Outside temperature as reported by the boiler

numeric Unit: °C

Read temperature

```taphome
SLEEP(60);
VAR r := SENDHTTPREQUEST("/api/boiler/outdoortemp");
IF r.StatusCode = 429
    SLEEP(200);
    r := SENDHTTPREQUEST("/api/boiler/outdoortemp");
END
IF r.IsSuccess = false
    ADDERROR("outdoortemp: HTTP " + r.StatusCode + IF(ISNULL(PARSEJSON(r.Content, "message", true)), "", ": " + PARSEJSON(r.Content, "message", true)));
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, "value", true);
IF ISNULL(v)
    ADDERROR("outdoortemp: no value from the gateway \u2014 this controller or unit does not report it; delete this device");
    RETURN(NaN);
END
RETURN(v);
```

**Connection:** Packet Parser → HTTP • Hostname: `ems-esp.local`

Possible improvements (17)

- Writing the selected flow temperature — Writable in EMS-ESP (0–90 °C), deliberately left out: a written flow temperature overrides the room controller; the template only reads it (Flow Temperature Target)
- Heating circuits 2–8 — Same entities as hc1 under the hc2…hc8 path prefix; the template covers heating circuit 1 only — devices for further circuits would be copies with a different path
- Summer / winter switchover — winter / auto / summer, RC100 and RC300
- Further heating circuit settings — Comfort / eco / manual setpoints, summer and frost thresholds, flow temperature limits, heating curve design temperature, offset, room influence, control mode and time program (RC100 / RC300 and others); the docs mark the command table as incomplete and model-dependent
- Controller-side domestic hot water settings — DHW mode (off / on / auto), DHW set temperatures, one-time charge and circulation mode on RC100 / RC300 — the template reads and writes the boiler DHW entities instead
- Boiler-side hot water functions — Hot water enable, one-time charge, circulation pump and mode, flow temperature offset and maximum power for hot water; some of them are overwritten by the thermostat (docs Boilers)
- Boiler comfort mode, heating enable and heating temperature limit — comfort hot / eco / intelligent; heatingactivated and heatingtemp are not changeable on some systems (for example with an MC10 rotary control)
- Burner and pump parameters — Burner hysteresis, minimum burner period, modulation limits and pump settings — installer parameters, the allowed ranges depend on the boiler type
- Maintenance message and error reset — Set or reset the maintenance message; reset error should be used only with an active error (docs Boilers) — candidates for service actions
- EMS-ESP firmware version — Already fetched by the module for the version warning; could be exposed as a module service attribute
- Restart EMS-ESP — GET with access token; candidate for a module service action
- Refresh all device values — Forces EMS-ESP to re-read all values from the EMS bus; no authentication
- Temperature sensors on the gateway (DS18B20) — The kit includes a JST ZH cable for own DS18B20 sensors; their readings are available over the same REST API
- Analog sensors and outputs of the gateway — Readings and setvalue for gateway analog inputs, counters and output pins
- Custom entities — User-defined entities for EMS telegrams EMS-ESP does not decode yet
- Entity discovery lists — Not a device — the live list of entities a given installation reports; the way to check which template devices will work before importing
- Other EMS-ESP interfaces — EMS-ESP also offers Modbus TCP (since 3.7.0) and MQTT / MQTT Discovery; the template uses the REST API by entity name because Modbus register offsets move between firmware releases

## Import parameters

Enter these values when you import the XML.

| Asked in the app                  | Default         |
|-----------------------------------|-----------------|
| Gateway IP Address                | Enter at import |
| EMS-ESP Access Token (admin user) | Enter at import |

## Sources

- EMS-ESP 3.8.6 REST API facts (TapHome digest of the firmware at tag v3.8.6)
  
  [github.com](https://github.com/emsesp/EMS-ESP32/tree/v3.8.6) 2026-10-18
- EMS-ESP documentation — Commands and API Reference
  
  [docs.emsesp.org](https://docs.emsesp.org/Commands) 2026-10-18
- EMS-ESP documentation — Configuring EMS-ESP
  
  [docs.emsesp.org](https://docs.emsesp.org/Configuring) 2026-10-18
- EMS-ESP documentation — Supported Boilers
  
  [docs.emsesp.org](https://docs.emsesp.org/Boilers) 2026-10-18
- EMS-ESP documentation — Supported Thermostats
  
  [docs.emsesp.org](https://docs.emsesp.org/Thermostats) 2026-10-18
- EMS-ESP documentation — Installing
  
  [docs.emsesp.org](https://docs.emsesp.org/Installing) 2026-10-18
- EMS-ESP documentation — Getting Started
  
  [docs.emsesp.org](https://docs.emsesp.org/Getting-Started) 2026-10-18
- EMS-ESP changelog 3.7.0 – 3.8.6
  
  [github.com](https://github.com/emsesp/EMS-ESP32/blob/v3.8.6/CHANGELOG.md) 2026-10-18
- BBQKees Gateway E32 V2 KIT (Ethernet + WiFi Edition V2 KIT) — product page
  
  [bbqkees-electronics.nl](https://bbqkees-electronics.nl/product/gateway-e32-v2-ethernet-wifi-edition-v2-kit/) 2026-10-18

## Related Documentation

- [Packet Parser Integration](https://taphome.com/en/compatibility/packet-parser-guide/)
- [Packet Parser (HTTP, TCP, UDP, FTP, MQTT)](https://taphome.com/en/docs/integration/packet-parser/)
- [Packet parser functions](https://taphome.com/en/docs/script/packet-parser/)
- [Parsing functions](https://taphome.com/en/docs/script/parsing-functions/)

