Gilles HPK-RA: A Pellet Boiler in Home Assistant
Published on 10 October 2026 · Home Assistant · Modbus TCP
A boiler produces some interesting data: temperatures, oxygen readings, combustion phases and fan states. Much of it is already visible on the controller’s display. I wanted these values in Home Assistant too, so I could follow what the boiler does over longer periods. That became gilles-hpk-ra-modbus: open documentation of the Modbus interface, along with tools and a Home Assistant configuration.
Gilles is a heating equipment manufacturer from Gmunden in Upper Austria. HPK-RA is a range of automatically fed biomass boilers. The manufacturer’s documentation covers both pellet and wood-chip versions in various output sizes. The installation used to develop this project is a pellet boiler. See the Gilles pellet boiler brochure (PDF) and wood-chip boiler brochure (PDF).
In this type of boiler, fuel moves automatically from storage to the burner. Pellets are fed in controlled quantities and ignited; the resulting heat passes through the heat exchanger into the heating water. An induced-draught fan maintains the necessary negative pressure inside the boiler. A lambda sensor measures residual oxygen in the flue gas, providing an important input for combustion control. This boiler range also features automatic heat-exchanger cleaning and ash removal, as described in the manufacturer’s brochure (PDF).
The process involves several operating phases. Before the boiler begins heating, it goes through stages such as ventilation, fuel feed and ignition. The controller then regulates combustion and reduces output as heat demand allows. Further states follow the heating phase, including a fan run-on period. Looking only at the current boiler temperature therefore reveals a small part of what is happening. The Gilles Touch manual (PDF) describes these sequences in considerable detail.
The installation is operated through Gilles Touch. The controller examined in this project is based on the Sigmatek HZS platform and uses LASAL II. This is industrial control technology. The touchscreen displays the measurements and settings used by that controller. For this project, the question was which of them could also be read over the network.
That is where Modbus TCP comes in. Put simply, a program uses the network to query numbered locations in the controller, known as registers. The response consists of numbers. What a number means, which unit it uses and whether it needs to be converted are normally explained in a register map.
That documentation was missing for the Gilles controller under investigation. The interface responded, but I did not have a suitable public register map. The manufacturer’s mention of Modbus in its documentation (PDF) helps identify the protocol. It takes considerably more work to establish what the individual values mean.
Looking at Hargassner did not provide a ready-made solution either. Hargassner announced its acquisition of Gilles in September 2020. However, the Hargassner register map compared during this project did not match the existing Gilles controller. The company’s history alone does not explain the technical interface of an older installation. The acquisition is documented in Hargassner’s announcement.
The interface examined here exposes 40 logical values. Technically, each consists of two 16-bit registers combined into a 32-bit value. That distinction matters when experimenting with Modbus yourself: these 40 values occupy 80 register words.
The mappings emerged through comparisons. A parameter export from the controller provided named settings. The touchscreen showed current temperatures and operating states. Alongside those, I recorded the values read over Modbus. When a display reading and a register agree repeatedly and change together, an initial guess gradually becomes a mapping supported by evidence.
This works reasonably well for temperatures. Numbers representing an operating state or a control output are harder to interpret. A value might rise when the burner starts because it describes fuel feed. It might also rise because a fan is accelerating at the same time. Timing alone does not settle the question.
Register 62 is a good example. Initially, it looked like a door signal because its value changed significantly when the door opened. Further observations no longer fitted that explanation: the value also took intermediate levels and tracked the induced-draught fan. Opening the door caused the fan to respond, and that response was what appeared in the register. The functional mapping was corrected accordingly. The precise scaling of the fan values nevertheless remains a separate, unresolved question.
These steps are documented in the methodology. The tools are covered there too: a Python logger that records changes and can save them as CSV, plus a snapshot tool for capturing a single set of readings. These make it possible to compare observations later without copying everything from the display.
The first Git commit, dated 20 May 2026, already contained the register map, tools and a Home Assistant integration. The early development steps are also recorded in the changelog. Calculated sensors and a more extensive statistics view followed shortly afterwards.
At first, the analysis went too far. There were estimates for pellet consumption, efficiency and modulation. It is easy to calculate another number from the numbers already available. Whether the result represents a useful measurement depends on the assumptions behind it. For pellet consumption, for example, there was no reliably calibrated fuel-feed rate.
Those estimates were removed on 7 September. The available signals did not support what the calculations claimed to show. That step is as much a part of the project’s development as adding new sensors. An efficiency percentage looks good on a dashboard, but it needs a defensible basis.
September also brought work on connection reliability. A very short TCP idle limit was observed on the reference controller: the connection could be closed after roughly three seconds without a request. The configuration therefore reads one selected state value every two seconds. This is an adjustment to the observed behaviour of that controller; other firmware versions need to be checked separately.
Handling missing data was equally important. When Home Assistant loses its connection, the boiler’s state is initially unknown. The display must then show “unavailable”. A missing measurement must not produce an apparently normal boiler temperature, and a missing state report must not accidentally become “standby”. Availability checks were added and the dependent sensors were revised to address this.
Longer observation led to further corrections. On 24 September, the earlier interpretation of register 78 as an ash-removal motor signal was withdrawn. Its behaviour over a longer period did not support that mapping. A possible consumption counter also proved not to be monotonic: its value could fall again. That made the original explanation as a running cumulative counter untenable.
Other values remain candidates for particular functions. There is evidence that register 56 could represent an oxygen setpoint, for example. A plausible match is not yet enough to give it a definitive label. A comparison in which both the display and the register happen to show zero proves particularly little. A useful check needs meaningful values during normal operation.
The latest Git revision examined, dated 25 September 2026, also accounts for newly observed state numbers. Some of their meanings remain unresolved, so they are labelled accordingly. The current register findings record what was observed and which explanation currently fits the evidence.
Home Assistant can now display boiler, flue-gas and return temperatures, residual oxygen and known operating phases, among other values. There are also statistics for observed starts and cycle durations. The history makes it possible to see how temperature and operating state relate to each other, and how a heating cycle develops.
Those statistics have limits too. A start can only be counted if the corresponding transition was actually observed. Events may be missed during gaps in the data. A recorded cycle duration can include ventilation before and after combustion, so it does not directly establish how long a flame was present. The rolling start statistic for the previous 24 hours also has a documented limitation and should currently not be treated as a reliable counter.
The integration is strictly read-only. It does not change boiler parameters. The Gilles controller retains control of the heating process; Home Assistant displays and analyses the accessible data.
The project still has open questions. For example, the register map examined here does not yet contain reliable mappings for all buffer-tank and domestic-hot-water temperatures, or for actual pellet consumption. Unknown states and the scaling of individual control outputs also need further comparisons. The results obtained so far come from one specific reference installation and do not guarantee that every Gilles controller exposes the same values.
The code and documentation are available on GitHub under the MIT licence, with German and English descriptions. Anyone with a similar installation can find the register map and the Home Assistant instructions there. Reproducible comparisons between touchscreen readings and register values are especially useful. They can make the next mapping more precise—or show that an existing explanation needs to be crossed off the list.