OT Thing - An OpenTherm-WiFi Gateway with integrated OT master & slave

Please supply:

  • Brand & model of boiler & roomunit
  • OTthing firmware version
  • status JSON (http://[OTTHING-IP]/status)
  • configuration JSON (http://[OTTHING-IP]/config)
  • OT status JSON (http://[OTTHING-IP]/otitems)
  • OTthing log

what is “DHW blocking” option?

It is an option given to the boiler, behaviour depends on it. Usually this will inhibit the heating circuit while delivering hot tap water

what is “member ID” option?

A supplierdependant value sent to the boiler, some boilers need a specific ID from the master

what is the difference between the heating surface exponent in Dimensioning and the gradient in Heating curve? Should I set them on the same value? I searched for information about it, I know understand how to set the heating curve but I from what I read those parameters seems similar.

Surface exponent depends on the type of heating (floor, radiators, …), it describes the physical behaviour of it (amount of radiation, convection, …). It can be found in the datasheets of your heating elements.
The gradient depends on things like insulation, areas etc.

I read on the project page about the PI controller, I (basically) understand the theory, but how I do know which values I have to put? Or shoud I leave it off for now?

You can find it out empirically, but also on the internet is a lot of information how to tune PI controllers

Thanks a lot for your explanations.
I tried DHW Blocking, seems like on my boiler it deactivates totally DHW production.

After manually updating the firmware to 2.35, it seems to have resolved the issue again. :slight_smile: I have another question: after connecting to the digital input, what is it called in Home Assistant? I have several binary sensors and I don’t know which one is for the digital input. Which one should be used? Which one is the digital input? I can check by unplugging it and checking which one is gone, but I don’t have access to the furnace right now.
OK, I think it was enough to connect on/off to the digital input and your controller gives this command to the furnace and turns on the heating?

The digital input was not yet implemented, please see

Digital input can be configured under setup, then a sensor appears in HA.

Hi Stefan,

Just received the OTThing, thank you.
Heatpump Remeha toros vision full electric
Room unit, Honeywell touch chronotherm.

But lost how it works, i placed the OTThing between the room unit and heatpump obvioulsy and set the OTThing in repeater mode.

But I dont seem to understand how it works,

For example;
Current temp in room is 19.8

I set the roomsetpoint to 18.5 and mode auto so i expect no heating or cooling will occur

Northing happens, until i switch override ch1 to on. The heatpump starts heating… but why?, the actual temp does not require the start.
What is happening, who is controlling what

What I was expecting and wanted is that the OTThing is in repeater mode, the room unit can set and request and OTThing/HA can monitor or override setpoints for example.

But now, if i dont use the override switch nothing happens and when i set the override it just start heating without a need to.
And in that case, who determines when to stop the heating?, is it the room unit?, is it otthing?

Can you guide me please?

try to use OTthing’s master mode and enabled slave interface additionally. If you want to completely shut off on reaching room setpoint use “suspend on roomsetpoint”.

Great that works… thanks Stefan.
A question, changing the mode is that also possible via mqtt? so a command to change from master to bypass for example.
Reason I ask is that if the heat pump is in error the thermostate can display this error and you can enter some keys to solve it. I think that will require a bypass at that time.
Would be great if I can do that from HA if needed instead of the web interface.

I’ll think about a bypasstopic. Maybe you can log what happens on the bus when thermostat is fixing errors

Thanks Stefan, would be great.
Don’t know about logging yet, i just know a couple of weeks ago the heatpump was in error and blocked, the advise i got was to go over in some hidden menus on the thermostate and set a register on a specific number to clear the error and blockage.

I know either setting the mode on bridge in the webapp or even removing power from otthing will do the trick but i would like to concentrate it on one place.

Release v2.38 is out with some new features:

  • sensors for flame / pausetime per cycle
  • configurable AUX inputs (analog, digital, 1wire)
  • Bypass OTthing via MQTT / HA
  • New HTTP endpoint /set for setting all MQTT values
  • adjustable min. flow temperature
  • option for suspending below min. flow
  • adjustable suspend offset

Thanks for this release. Upgraded and it works fine.
Can you define what adjustable suspend offset does?
I use the suspend on room set point feature with an hysteresis of 0,5K, do I need to set the suspend offset on 0 to keep it as it is right now?

suspend offset will switch of CH if setpoint is below the offset of the actual temperature. Setting 0 as offset will remain the old behaviour.

every 5 seconds this message:

2026-03-18 16:29:35.047 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'dict object' has no attribute 'ch2_mode' when rendering '{{ None if (value_json.slave.get('status')) is none else 'ON' if (value_json.slave.status.ch2_mode) else 'OFF' }}'
2026-03-18 16:29:40.055 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'dict object' has no attribute 'ch2_mode' when rendering '{{ None if (value_json.slave.get('status')) is none else 'ON' if (value_json.slave.status.ch2_mode) else 'OFF' }}'
2026-03-18 16:29:45.281 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'dict object' has no attribute 'ch2_mode' when rendering '{{ None if (value_json.slave.get('status')) is none else 'ON' if (value_json.slave.status.ch2_mode) else 'OFF' }}'

Good day, Stefan,
I would like to ask if there is a list of boilers/main boards supported by your OT Thing gateway.
I have a Baxi Luna Duo-Tec IN+ 24 GA with a Bertelli & Partners main board and a Baxi RC 06.20 remote controller. I would be very grateful if you could confirm whether it can be managed by the OT Thing board.
Thank you.
Alex

This should work as your Boiler is already communicating via OT with your roomunit.

Hi, please provide config & status:

status JSON (http://[OTTHING-IP]/status)
configuration JSON (http://[OTTHING-IP]/config)
OT status JSON (http://[OTTHING-IP]/otitems)

With the latest version v2.38 flame rate is no longer sent to HA via MQTT
image

status

{"runtime":42135,"freeHeap":70356,"largestBlock":51188,"resetInfo":12,"fw_version":"2.38","USB_connected":false,"reset_reason0":12,"numWifiDisc":0,"dateTime":"24.03.2026 08:18:07","wifi":{"status":3,"mode":1,"ipsta":"192.168.1.9","mac":"08:92:72:CF:A1:B8","hostname":"otthing","sta_ssid":"FASTWEB-VIHV4D","rssi":-60},"mqtt":{"connected":true,"basetopic":"otthing/CFA1B8","numDisc":1},"slave":{"slave_config_member":{"value":"410b","dhw_present":true,"ctrl_type":false,"cooling_config":false,"dhw_config":false,"master_lowoff_pumpctrl":false,"ch2_present":false,"memberId":11},"slave_ot_version":"3.0","slave_prod_version":"23.1","status":{"value":"200","fault":false,"ch_mode":false,"dhw_mode":false,"flame":false,"cooling":false,"diagnostic":false},"vent_status":null,"max_cap_min_mod":{"max_capacity":19,"min_modulation":27},"dhw_bounds":{"max":65,"min":40},"ch_bounds":{"max":54,"min":0},"rel_mod":0,"ch_pressure":1,"flow_t":46.2,"return_t":45.9,"unsuccessful_burner_starts":1,"num_flame_signal_low":0,"oem_diag_code":0,"burner_starts":25232,"ch_pump_starts":20022,"dhw_pump_starts":2080,"dhw_burner_starts":19507,"burner_op_hours":803,"chpump_op_hours":1488,"dhwpump_op_hours":19295,"dhw_burner_op_hours":110,"fault_flags":{"value":"ff","service_request":false,"lockout_reset":false,"low_water_pressure":false,"gas_flame_fault":false,"air_pressure_fault":false,"water_over_temp":false,"oem_fault_code":255},"rp_flags":{"value":"303","dhw_setpoint_rw":true,"max_ch_setpoint_rw":true,"dhw_setpoint_trans":true,"max_ch_setpoint_trans":true},"boiler_fan":{"setpoint":0,"actual":0},"flame_current":0,"connected":true,"txCount":84232,"rxCount":84152,"timeouts":0,"flameStats":{"duty":0,"freq":0.7,"onTime":0.4,"offTime":63.4}},"thermostat":{"ch_set_t":41.7,"room_t":15.1,"room_set_t":15,"master_prod_version":"1.0","max_rel_mod":80,"master_ot_version":"4.2","master_config_member":{"value":"108","smartPowerImplemented":true,"memberId":8},"dhw_set_t":47,"status":{"value":"200","ch_enable":false,"dhw_enable":true,"cooling_enable":false,"otc_active":false},"outside_t":2.5,"max_set_t":60,"txCount":173171,"rxCount":173171,"invalidCount":1,"smartPower":"low"},"heatercircuit":[{"roomsetpoint":15,"roomTempFilt":15.10841418,"roomtemp":15.1,"ovrdFlow":false,"mode":2,"integState":0,"flowMin":20,"suspended":true},{"roomsetpoint":21,"roomTempFilt":0,"ovrdFlow":false,"mode":2,"integState":0,"flowMin":20}],"bypass":false,"outsideTemp":2.6,"1wire":{},"BLE":{},"aux1":{},"aux2":{}}

config

{"slaveApp":0,"otMode":1,"enableSlave":true,"boiler":{"dhwOn":true,"dhwTemperature":47,"overrideDhw":false,"coolOn":false,"otc":false,"summerMode":false,"dhwBlocking":false,"maxModulation":80},"heating":[{"flow":45,"roomtempcomp":0,"chOn":true,"flowMax":60,"exponent":1.5,"gradient":1.05,"offset":7,"marker":[],"roomsetpoint":{"source":0,"temp":17},"roomtemp":{"source":0},"overrideFlow":false,"roomComp":{"enabled":true,"p":2,"i":0.5,"boost":2},"enableHyst":true,"hysteresis":0.1},{"flow":30,"roomtempcomp":0,"chOn":false,"flowMax":60,"exponent":1.3,"gradient":1.4,"offset":0,"marker":[],"roomsetpoint":{"source":0,"temp":21},"roomtemp":{"source":1},"overrideFlow":false,"roomComp":{"enabled":false},"enableHyst":false}],"vent":{"ventEnable":false,"openBypass":false,"autoBypass":false,"freeVentEnable":false,"setpoint":3},"outsideTemp":{"source":0,"apikey":"undefined","lat":null,"lon":null,"interval":null},"mqtt":{"host":"192.168.1.16","port":1883,"user":"ale","pass":"ca501","tls":false,"keepAlive":15},"masterMemberId":8,"hostname":"otthing","haPrefix":"homeassistant","haName":"OTthing","timezone":3600}

otitems

{"slave":{"slave_config_member":{"id":3,"enabled":true,"lastMsgType":4,"numSet":1,"value":"410b","disc":true},"slave_ot_version":{"id":125,"enabled":true,"lastMsgType":4,"numSet":1,"value":"300","disc":true},"slave_prod_version":{"id":127,"enabled":true,"lastMsgType":4,"numSet":1,"value":"1701","disc":true},"status":{"id":0,"enabled":true,"lastMsgType":4,"numSet":50876,"value":"200","disc":true},"vent_status":{"id":70,"enabled":true,"lastMsgType":3,"numSet":0},"max_cap_min_mod":{"id":15,"enabled":true,"lastMsgType":4,"numSet":1,"value":"131b","disc":true},"dhw_bounds":{"id":48,"enabled":true,"lastMsgType":4,"numSet":1,"value":"4128","disc":true},"ch_bounds":{"id":49,"enabled":true,"lastMsgType":4,"numSet":1,"value":"3600","disc":true},"tr_override":{"id":9,"enabled":false,"lastMsgType":7,"numSet":1},"rel_mod":{"id":17,"enabled":true,"lastMsgType":4,"numSet":4212,"value":"0","disc":true},"ch_pressure":{"id":18,"enabled":true,"lastMsgType":4,"numSet":1406,"value":"100","disc":true},"dhw_flow_rate":{"id":19,"enabled":false,"lastMsgType":7,"numSet":1},"flow_t":{"id":25,"enabled":true,"lastMsgType":4,"numSet":4211,"value":"2df3","disc":true},"flow_t2":{"id":31,"enabled":false,"lastMsgType":7,"numSet":1},"dhw_t":{"id":26,"enabled":false,"lastMsgType":6,"numSet":1},"dhw_t2":{"id":32,"enabled":false,"lastMsgType":7,"numSet":1},"outside_t":{"id":27,"enabled":false,"lastMsgType":7,"numSet":704},"return_t":{"id":28,"enabled":true,"lastMsgType":4,"numSet":4211,"value":"2db3","disc":true},"exhaust_t":{"id":33,"enabled":false,"lastMsgType":6,"numSet":1},"tr_override2":{"id":39,"enabled":false,"lastMsgType":7,"numSet":1},"vent_ot_version":{"id":75,"enabled":false,"lastMsgType":7,"numSet":1},"vent_prod_version":{"id":76,"enabled":false,"lastMsgType":7,"numSet":1},"rel_vent":{"id":77,"enabled":false,"lastMsgType":7,"numSet":1},"rel_hum_exhaust":{"id":78,"enabled":false,"lastMsgType":7,"numSet":1},"co2_exhaust":{"id":79,"enabled":false,"lastMsgType":7,"numSet":1},"supply_inlet_t":{"id":80,"enabled":false,"lastMsgType":7,"numSet":1},"supply_outlet_t":{"id":81,"enabled":false,"lastMsgType":7,"numSet":1},"exhaust_inlet_t":{"id":82,"enabled":false,"lastMsgType":7,"numSet":1},"exhaust_outlet_t":{"id":83,"enabled":false,"lastMsgType":7,"numSet":1},"exhaust_fan_speed":{"id":84,"enabled":false,"lastMsgType":7,"numSet":1},"supply_fan_speed":{"id":85,"enabled":false,"lastMsgType":7,"numSet":1},"power_cycles":{"id":97,"enabled":false,"lastMsgType":7,"numSet":1},"unsuccessful_burner_starts":{"id":113,"enabled":true,"lastMsgType":4,"numSet":703,"value":"1","disc":true},"num_flame_signal_low":{"id":114,"enabled":true,"lastMsgType":4,"numSet":703,"value":"0","disc":true},"oem_diag_code":{"id":115,"enabled":true,"lastMsgType":4,"numSet":703,"value":"0","disc":true},"burner_starts":{"id":116,"enabled":true,"lastMsgType":4,"numSet":703,"value":"6290","disc":true},"ch_pump_starts":{"id":117,"enabled":true,"lastMsgType":4,"numSet":703,"value":"4e36","disc":true},"dhw_pump_starts":{"id":118,"enabled":true,"lastMsgType":4,"numSet":704,"value":"820","disc":true},"dhw_burner_starts":{"id":119,"enabled":true,"lastMsgType":4,"numSet":704,"value":"4c33","disc":true},"burner_op_hours":{"id":120,"enabled":true,"lastMsgType":4,"numSet":141,"value":"323","disc":true},"chpump_op_hours":{"id":121,"enabled":true,"lastMsgType":4,"numSet":140,"value":"5d0","disc":true},"dhwpump_op_hours":{"id":122,"enabled":true,"lastMsgType":4,"numSet":141,"value":"4b5f","disc":true},"dhw_burner_op_hours":{"id":123,"enabled":true,"lastMsgType":4,"numSet":140,"value":"6e","disc":true},"fault_flags":{"id":5,"enabled":true,"lastMsgType":4,"numSet":1406,"value":"ff","disc":true},"rp_flags":{"id":6,"enabled":true,"lastMsgType":4,"numSet":1,"value":"303","disc":true},"remote_override_function":{"id":100,"enabled":false,"lastMsgType":7,"numSet":1},"vent_fault_flags":{"id":72,"enabled":false,"lastMsgType":7,"numSet":1},"boiler_heat_ex_t":{"id":34,"enabled":false,"lastMsgType":7,"numSet":1},"boiler_fan":{"id":35,"enabled":true,"lastMsgType":4,"numSet":1406,"value":"0","disc":true},"flame_current":{"id":36,"enabled":true,"lastMsgType":4,"numSet":1406,"value":"0","disc":true},"brand":{"id":93,"enabled":false,"lastMsgType":7,"numSet":1},"brand_version":{"id":94,"enabled":false,"lastMsgType":7,"numSet":1},"brand_serial":{"id":95,"enabled":false,"lastMsgType":7,"numSet":1},"num_tsps":{"id":10,"enabled":false,"lastMsgType":7,"numSet":1},"size_fhb":{"id":12,"enabled":false,"lastMsgType":7,"numSet":1}},"master":{"ch_set_t":{"id":1,"enabled":true,"lastMsgType":1,"numSet":5033,"value":"2979","disc":true},"ch_set_t2":{"id":8,"enabled":false,"lastMsgType":3,"numSet":0},"room_t":{"id":24,"enabled":true,"lastMsgType":1,"numSet":704,"value":"f19","disc":false},"room_t2":{"id":37,"enabled":false,"lastMsgType":3,"numSet":0},"room_set_t":{"id":16,"enabled":true,"lastMsgType":1,"numSet":704,"value":"f00","disc":false},"room_set_t2":{"id":23,"enabled":false,"lastMsgType":3,"numSet":0},"master_prod_version":{"id":126,"enabled":true,"lastMsgType":1,"numSet":235,"value":"100","disc":true},"max_rel_mod":{"id":14,"enabled":true,"lastMsgType":1,"numSet":235,"value":"5000","disc":false},"master_ot_version":{"id":124,"enabled":true,"lastMsgType":1,"numSet":235,"value":"402","disc":true},"master_config_member":{"id":2,"enabled":true,"lastMsgType":1,"numSet":235,"value":"108","disc":true},"dhw_set_t":{"id":56,"enabled":true,"lastMsgType":1,"numSet":1406,"value":"2f00","disc":false},"status":{"id":0,"enabled":true,"lastMsgType":1,"numSet":50956,"value":"200","disc":true},"vent_status":{"id":70,"enabled":false,"lastMsgType":3,"numSet":0},"day_time":{"id":20,"enabled":false,"lastMsgType":3,"numSet":0},"date":{"id":21,"enabled":false,"lastMsgType":3,"numSet":0},"year":{"id":22,"enabled":false,"lastMsgType":3,"numSet":0},"rel_vent_set":{"id":71,"enabled":false,"lastMsgType":3,"numSet":0},"outside_t":{"id":27,"enabled":true,"lastMsgType":1,"numSet":704,"value":"2b3","disc":false},"max_set_t":{"id":57,"enabled":true,"lastMsgType":1,"numSet":235,"value":"3c00","disc":false}}}

I purchased the Open-Therm interface and have been testing it for a couple of days.
There are some things that aren’t entirely clear to me and that I’d like to explore further.
My heating system consists of a BAXI LUNA IN PLUS 26 boiler controlled by the RC 06.20 climate controller.
My goal is to have all the boiler parameters reported on HA.
The correct configuration seems to be:

  • Mode Master with slave interface enabled.
  • Heat/cool Circuit1, DHW and OTC enabled (i use an external zigbee sensor).
    With this configuration override options ​​(flow temp an DHW) don’t make sense and so I can keep them disabled, correct?

Using the OTthing configuration interface I can correctly set the values ​​of Min and Max flow temperature, default values (if no esternal temp provided) and the heating curve (values ​​are reported in the status section of the web interface).

However, I can’t set the water temperature (DHW) correctly.
If I change the value in the setup section of the configuration interface, the value isn’t reported in the status section.

I’ve also noticed that the entities displayed on HA don’t always match the values ​​set on the device’s web interface. For example, if I change (enable or disable) the Override CH and Override DHW on the web interface (regardless of the selected mode), the settings aren’t reflected on HA (Override entities), and vice versa.

It also happened (occasionally) that by changing some temperature threshold settings via the web interface and saving the values, the climate entities reported on HA for DWH or heating changed status to OFF (randomly) interrupting the boiler operation.

I also noticed that in heating mode, the flame is correctly controlled by the interface but the heating water circulation pump is always on, to turn it off I have to turn OFF the HA climate flow-temperature entity (previously it was in AUTO mode).

Are there any settings I can change to improve my system’s performance?

Release v2.38 is out with some new features:

New HTTP endpoint /set for setting all MQTT values

Thank you,

HTTP set command on endpoint works like a charm in my Shelly Scripts now. This is a strong feature. The Shelly TRVs with your OTthing gateway now fully operate stand-alone w/o HomeAssistant/MQTT. Thank you.