OpTh library as base for a thermostate replacement

Having only the modern equivalent of the basic on/off thermostate, I wanted a flexible programmable one with a clock for a week and preferably some online presence. The clock option is something you can buy, but open and expandable is not cheap. The thermostate and boiler use OpenTherm, a protocol that may not be completely open, but at least documented and public.

My luck, there is already something as OpTh, a library for the Arduino which can interpret and visualise the messages between the thermostate and boiler. The web site of the creator of OpTh also has an interface, which converts the voltage and current modulation to a bitstream. This interface is based on an old Elektor design.

Photo prototype board

Also on this web site is a link to an OpenTherm thermostate implemented with a PIC microcontroller. Alas the firmware is free, but the source code is not. From this project I plan to borrow the voltage modulating circuit and add it to the OpTh/Elektor design, making it usable as both a listener and a thermostate replacement.

Diagram prototype diagram CW side

Diagram prototype diagram Arduino side plus voltage modulator

The interface diagram is more or less reverted to the original Elektor design, with some changes; a diode (BAT85) is added to protect the opamp from voltages larger than Vcc and the optocouplers are replaced by type PC817 and rearranged to get an implicit OR function. While debugging I found the current modulating signal leaks a bit into the voltage modulating detection, but in the ORred signal this is not a problem.

Logic analyser two channels

Adaptations to the OpTh OT_master_LCD code

Initially the example did not produce useful data, only an occasional "M:0:0" message. This was fixed by adding the line OT_StateMachine.transitionTo(GetPeriod).update(); to the loop.

There was no LCD present when I first got the interface working, so I expanded the debug interface somewhat. By adding the msg_type data to each message, it appeared some messages send by the thermostate are not supported by the boiler. So these can be ignored in further studies (in this setup).

Study of the messages used

The thermostate is an AGPO Agpotherm Plus, the boiler an APGP-Ferrolli Megadens.

This are the messages send by the thermostate:

Id dir description value response
0 R Master and slave status flags
1 W Control setpoint: CH water temperature setpoint
9 R Remote override room setpoint (unknown ID)
14 W Maximum relative modulation level setting (%) (0 or 2560)
15 R Maximum boiler capacity (kW) / minimum boiler modulation level(%) (0)
16 W Room setpoint (°C)
17 R Relative modulation level (%) (0-25600)
24 W Room temperature (°C)
25 R Boiler flow water temperature (°C)
27 R Outside temperature (°C) (unknown ID)
29 R Solar storage temperature (°C) (unknown ID)
57 RW Max CH water setpoint (°C) (unknown ID)

(°C) are send as f8.8 format, divide by 256 for the proper temperature.

M:0 / S:0 flags

Only bits 0-7 are specified in the v.2. protocol specfication
                bit         master                     // slave
                        0   CH enabled / disabled      // no fault / fault
                       1    DWH enabled / disabled     // CH not active / active
                      2     cooling disabled / enabled // DHW not active 
                     3      OCT not active / active    // flame active
                   4 |      CH2 disabled / enabled     // cooling disabled / enabled
                  5  |      res                        // CH2 active
                 6   |      res                        // no diag / diag event
                7    |      res                        // res
M:0:768  - 0011 0000 0000 
S:0:778  - 0111 0111 1010 
S:0 780  - 0111 0000 1100 (hot water tap)
S:0:768  - 0111 0000 0000 (after water tap 1)
S:0:770  - 0111 0000 0010 (after water tap 2)
M:0:512  - 0010 0000 0000 
S:0:522  - 0010 0000 1010 
             9
             "comfort" setting. 0 switches the DHW boiler off, 1 switches it on.

88243 Master messages in 24 hours, about each second one. The order is typically 25, 1, 0 and one of the remainer; 9, 14, 15, 16, 17, 14, 27, 29 and 57. The reply to 9, 27, 29, 57 is a "Unknown DataID", so are not supported by the boiler.

The ratio of the send messages is:

Almost all messages get a reply, only the "S:0:0" are missing. It seems the boiler only replies to "M:0:0" if it has something other than 0 to report.

the prototype

Concluding remarks for the message analysis

Based on the message flow this is the expected working of the system:


Local links:

Other links:


Last updated: 2014-03-08

Email: fjkraan@xs4all.nl