Today I configured my OpenTherm Gateway to publish data to MQTT where the messages are received, processes and persisted in influx. This way I can see what my current conditions are for my central heating system and analyse the historic data through Grafana.
I do not use the OTGW to control my central heating system. It is there for monitoring. A regular Honeywell Evohome does OpenTherm Modulation and has control over zone valves etc.
This solution is based on OpenTherm Gateway with Raspberry Pi Zero W directly connected through an USB-TTL cable. This solution does NOT use a NodeMCU / Network shield on OTGW
This solution does NOT use the OpenHAB OpenTherm Gateway Binding. It instead uses the standard MQTT Binding in OpenHAB to integrate the OpenTherm Gateway.
Enjoy and let me know if you like the solution.
Kind regards, Bas
A) Get an OpenTherm Gateway
Buy it or compose it yourself (https://www.nodo-shop.nl/nl/opentherm-gateway/188-opentherm-gateway.html) incl. the power supply and soldered it according to the manual (https://www.nodo-shop.nl/nl/index.php?controller=attachment&id_attachment=47).
B) Install a Raspberry PI Zero W and run it headless (https://www.raspberrypi.org/documentation/configuration/wireless/headless.md)
C) Connect all the things
Connect the OTGW and RPI through TTL-USB (https://www.electrodragon.com/product/usb-ttl-serial-ch340-board/) and connect DuPont Jumper Cable connecting GND, RTX, TRX. Read the manual for the OTGW for images illustrating how it’s done. You need a connector cable to connect the TTL-USB to the RPI Zero (Adapter Cable Micro USB 2.0 Female to Micro B Male Converter Adaptor Cable).
D) Build and Run OTMonitor
Retreive the latest OTMonitor from github (https://github.com/basmeerman/otmonitor) build, configure and run it according to the readme and documentation listed in the repository.
- Note to configure the correct USB device in the config file, otherwise no output/debug information is printed to the logs.
- Make sure to create the otmonitor.conf file containing the configuration (the MQTT broker information).
- Install otmonitor as a system service/daemon (see https://github.com/basmeerman/otmonitor readme)
E) Now in OpenHAB: Create things in .thing file:
Thing topic openthermgateway "OpenThermGateway" {
Channels:
// powermode {mode string}
// thermostat {connected boolean}
// error {code byte}
Type number : error "Error Code" [ stateTopic="events/central_heating/otmonitor/error", transformationPattern="JSONPATH:$.value"]
// flame {on boolean}
Type switch : flame "Flame" [ stateTopic="events/central_heating/otmonitor/flame", transformationPattern="JSONPATH:$.value", on="true", off="false"]
// hotwater {on boolean}
Type switch : hotwater "Hotwater" [ stateTopic="events/central_heating/otmonitor/hotwater", transformationPattern="JSONPATH:$.value", on="true", off="false"]
// centralheating {on boolean}
Type switch : centralheating "Central Heating" [ stateTopic="events/central_heating/otmonitor/centralheating", transformationPattern="JSONPATH:$.value", on="true", off="false"]
// fault {on boolean}
Type switch : fault "Fault" [ stateTopic="events/central_heating/otmonitor/fault", transformationPattern="JSONPATH:$.value", on="true", off="false"]
// diagnostic {on boolean}
// cooling {on boolean}
// centralheating2 {on boolean}
// electricity {on boolean}
// roomtemperature {temp float}
Type number : roomtemperature "Room Temperature" [ stateTopic="events/central_heating/otmonitor/roomtemperature", transformationPattern="JSONPATH:$.value"]
// roomtemperature2 {temp float}
// outsidetemperature {temp float}
// setpoint {temp float}
Type number : roomsetpoint "Room Setpoint" [ stateTopic="events/central_heating/otmonitor/setpoint", transformationPattern="JSONPATH:$.value"]
// setpoint2 {temp float}
// controlsetpoint {temp float}
Type number : controlsetpoint "Control Setpoint" [ stateTopic="events/central_heating/otmonitor/controlsetpoint", transformationPattern="JSONPATH:$.value"]
// controlsetpoint2 {temp float}
// dhwenable {on boolean}
Type switch : dhwenable "Hotwater Enabled" [ stateTopic="events/central_heating/otmonitor/dhwenable", transformationPattern="JSONPATH:$.value", on="true", off="false"]
// dhwsetpoint {temp float}
Type number : dhwsetpoint "Hotwater Setpoint Temperature" [ stateTopic="events/central_heating/otmonitor/dhwsetpoint", transformationPattern="JSONPATH:$.value"]
// dhwtemperature {temp float}
//* Niet in MQTT Gezien!
Type number : dhwtemperature "Hotwater Temperature" [ stateTopic="events/central_heating/otmonitor/dhwtemperature", transformationPattern="JSONPATH:$.value"]
// dhwtemperature2 {temp float}
// chenable {on boolean}
Type switch : chenable "Heating Enabled" [ stateTopic="events/central_heating/otmonitor/chenable", transformationPattern="JSONPATH:$.value", on="true", off="false"]
// chsetpoint {temp float}
Type number : chsetpoint "Heating Setpoint" [ stateTopic="events/central_heating/otmonitor/chsetpoint", transformationPattern="JSONPATH:$.value"]
// modulation {level float}
// maxmodulation {level float}
Type number : maxmodulation "Maximum Modulation" [ stateTopic="events/central_heating/otmonitor/maxmodulation", transformationPattern="JSONPATH:$.value"]
// boilerwatertemperature {temp float}
Type number : boilerwatertemperature "Boilerwater Temperature" [ stateTopic="events/central_heating/otmonitor/boilerwatertemperature", transformationPattern="JSONPATH:$.value"]
// boilerwatertemperature2 {temp float}
// returnwatertemperature {temp float}
// chwaterpresure {bar float}
Type number : chwaterpressure "Heating Water Pressure" [ stateTopic="events/central_heating/otmonitor/chwaterpresure", transformationPattern="JSONPATH:$.value"]
// remoteoverrideroomsetpoint {temp float}
// chwaterdeltat {temp float}
// chburnerstarts {count unsigned}
Type number : chburnerstarts "Heating Burner Starts" [ stateTopic="events/central_heating/otmonitor/chburnerstarts", transformationPattern="JSONPATH:$.value"]
// chpumpstarts {count unsigned}
// dhwpumpstarts {count unsigned}
// dhwburnerstarts {count unsigned}
// chburnerhours {count unsigned}
Type number : chburnerhours "Heating Burner Hours" [ stateTopic="events/central_heating/otmonitor/chburnerhours", transformationPattern="JSONPATH:$.value"]
// chpumphours {count unsigned}
// dhwpumphours {count unsigned}
// dhwburnerhours {count unsigned}
Type number : dhwburnerhours "Hotwater Burner Hours" [ stateTopic="events/central_heating/otmonitor/dhwburnerhours", transformationPattern="JSONPATH:$.value"]
}
F) Create items in .item file:
// OpenTherm Gateway
Number ErrorCodeCentralHeating "CV Error Code" <switch> (GClimate) {channel="mqtt:topic:broker:openthermgateway:error"}
Switch SwitchFlameCentralHeating "CV Brander" <switch> (GClimate) {channel="mqtt:topic:broker:openthermgateway:flame"}
Switch SwitchHotwaterCentralHeating "CV Warmwater" <switch> (GClimate) {channel="mqtt:topic:broker:openthermgateway:hotwater"}
Switch SwitchHeatingCentralHeating "CV Verwarming" <switch> (GClimate) {channel="mqtt:topic:broker:openthermgateway:centralheating"}
Switch SwitchFaultCentralHeating "CV Fout" <switch> (GClimate) {channel="mqtt:topic:broker:openthermgateway:fault"}
Number TemperatureRoomCentralHeating "CV Temperatuur" <temperature> (GClimate) {channel="mqtt:topic:broker:openthermgateway:roomtemperature"}
Number TemperatureSetpointRoomCentralHeating "CV Setpoint" <heating> (GClimate) {channel="mqtt:topic:broker:openthermgateway:roomsetpoint"}
Number TemperatureControlSetpointCentralHeating "Controle Setpoint" <heating> (GClimate) {channel="mqtt:topic:broker:openthermgateway:controlsetpoint"}
Switch SwitchHotwaterEnabledCentralHeating "CV Warmwater Bedrijf Enabled" <switch> (GClimate) {channel="mqtt:topic:broker:openthermgateway:dhwenable"}
Number TemperatureHotwaterSetpointCentralHeating "CV Warmwater Setpoint" <heating> (GClimate) {channel="mqtt:topic:broker:openthermgateway:dhwsetpoint"}
Number TemperatureHotwaterCentralHeating "CV Warmwater Temperatuur" <temperature> (GClimate) {channel="mqtt:topic:broker:openthermgateway:dhwtemperature"}
Switch SwitchCentralHeatingEnabledCentralHeating "CV Bedrijf Enabled" <switch> (GClimate) {channel="mqtt:topic:broker:openthermgateway:chenable"}
Number TemperatureCentralHeatingSetpointCentralHeating "CV Setpoint" <heating> (GClimate) {channel="mqtt:topic:broker:openthermgateway:chsetpoint"}
Number PercentageMaximumModulationCentralHeating "CV Maximale Modulatie" <incline> (GClimate) {channel="mqtt:topic:broker:openthermgateway:maxmodulation"}
Number TemperatureBoilerWaterCentralHeating "CV Boiler Temperatuur" <temperature> (GClimate) {channel="mqtt:topic:broker:openthermgateway:boilerwatertemperature"}
Number PressureWaterCentralHeating "CV Warmwater Druk" <pressure> (GClimate) {channel="mqtt:topic:broker:openthermgateway:chwaterpressure"}
Number NumberBurnerStartsCentralHeating "CV Brander Starts" <line> (GClimate) {channel="mqtt:topic:broker:openthermgateway:chburnerstarts"}
Number HoursBurnerCentralHeating "CV Bedrijf Brander Uren" <time> (GClimate) {channel="mqtt:topic:broker:openthermgateway:chburnerhours"}
Number HoursHotwaterBurnerCentralHeating "CV Warmwater Berijf Brander Uren" <time> (GClimate) {channel="mqtt:topic:broker:openthermgateway:dhwburnerhours"}
G) Create a small sitemap to demo the controls
sitemap centralheating label="CentralHeating" icon="heating"
{
Frame label="Central Heating" {
Group item=GClimate label="Climaat Beheersing" icon="heating"
}
}
Troubleshooting)
- If things do not work directly trace back your steps diligently, the solution contains a lot of steps.
- You can find a lot of info on the links provided in the article and on the website.
- Please note you need to compile the OTMonitor on the RPI in order to receive the latest MQTT implementation and receive more attributes than in previous versions.
- It’s a good idea to first test the OTGW hardware with for example a Windows/Linux desktop so you know the hardware is working. Then proceed to connecting and configuring the Raspberry PI and finish the solution.
- Since not all central heaters/boilers are created equal, they communicate a different set of data attributes over OpenTherm. Therefor the sample does not have a complete scenario. I happen to own an Intergas 30/36HRE and it’s is not publishing a lot of details. You can subscribe to your MQTT broker with a wildcard subscription in order to see the complete list of messages OTMonitor publishes (or you need to read the TCL code :-))
That’s all. It was a fun project to do.