How to "Replace" an Exacontrol E7 C Thermostat and Control Your Boiler with Home Assistant #1532
axelere
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
How to "Replace" an Exacontrol E7 C Thermostat with Home Assistant for Boiler Control
This post is here to help anyone like me who isn’t familiar with eBUS avoid wasting hours heading in the wrong direction.
Context
I have a Saunier Duval ThemaFast Condens 30 boiler for hot water and underfloor heating, originally controlled by the Exacontrol E7 C thermostat with an outdoor temperature sensor.
I’m using an eBUS Adapter Shield C6 (Wi-Fi version) to connect the boiler to Home Assistant via the eBUS protocol.
Goal
Initially, I wanted to completely replace the Exacontrol E7 C thermostat (which I find unattractive) with a wall-mounted tablet running a Home Assistant dashboard. That dashboard would then act as the thermostat and control the boiler.
Problem
I quickly realized this wasn’t possible because the heating curve is stored in the thermostat, not in the boiler. Removing the thermostat would mean losing heating logic altogether.
Final Setup
I moved the E7 C thermostat to the boiler room and decided to override its temperature reading dynamically using data from a reference room (like the living room).
That way, the thermostat thinks it's in the reference room, even though it's physically somewhere else.
Requirements
HOW TO: Write values from Home Assistant controls to ebusd (Idiot's guide)
MQTT Entity Setup
If everything is working, your devices will begin to show up one by one in MQTT (this might take a few minutes).
Make sure the thermostat exposes these three values:
RoomTemp temp
→ Measured room temperatureRoomTempCorr
→ Correction value to be appliedRoomTempCorrFact
→ Factory correction valueAllow Writing to
RoomTempCorr
In the
ebusd
CSV definitions,RoomTempCorr
is marked aswi
(write install), meaning it can only be changed in installer mode.To bypass this restriction, add this to your Custom Command Line Options in the Home Assistant
ebusd
add-on:--accesslevel=*
Save and restart the add-on.
Testing via Developer Tools
Go to Developer Tools > Services in Home Assistant, and run:
Dynamic Thermostat Correction via Node-RED & eBUS
This setup allows you to dynamically adjust your boiler thermostat's reading so it behaves as if it were located in another room — without physically moving it.
Formula
To automate this, apply this basic formula:
RoomTempCorr = ReferenceRoomTemp - (RoomTempTemp + RoomTempCorrFact)
This way, the thermostat can think it's in the reference room (living room, bedroom, etc.) rather than the boiler room.
I mainly use Node-RED so here is the code:
Click to expand Node-RED flow JSON
[{"id":"1712581bcc894201","type":"trigger-state","z":"ede4cf8a90bd86c4","name":"Temperatures","server":"808d0070.6617c","version":5,"inputs":0,"outputs":2,"exposeAsEntityConfig":"","entities":{"entity":["sensor.ebusd_e7c_roomtemp_temp","sensor.controleur_fan_rack_temperature_entree_rack"],"substring":[],"regex":[]},"debugEnabled":false,"constraints":[],"customOutputs":[],"outputInitially":true,"stateType":"str","enableInput":false,"x":250,"y":1380,"wires":[["492a95945b9f884b","8fdb5de0eb18e72a","5c479c40c19455ee"],[]]},{"id":"492a95945b9f884b","type":"api-current-state","z":"ede4cf8a90bd86c4","name":"","server":"808d0070.6617c","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.ebusd_e7c_roomtemp_temp","state_type":"str","blockInputOverrides":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":550,"y":1380,"wires":[["a70eecc141401f58"]]},{"id":"8fdb5de0eb18e72a","type":"api-current-state","z":"ede4cf8a90bd86c4","name":"","server":"808d0070.6617c","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.ebusd_broadcast_outsidetemp","state_type":"str","blockInputOverrides":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":560,"y":1420,"wires":[["a70eecc141401f58"]]},{"id":"a70eecc141401f58","type":"join","z":"ede4cf8a90bd86c4","name":"","mode":"custom","build":"array","property":"","propertyType":"full","key":"topic","joiner":"\\n","joinerType":"str","useparts":false,"accumulate":false,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":860,"y":1380,"wires":[["e87542481188255a"]]},{"id":"e87542481188255a","type":"function","z":"ede4cf8a90bd86c4","name":"Calc diff","func":"let sejour = null;\nlet chaudiere = null;\nlet correction = 0;\n\nfor (let i = 0; i < msg.payload.length; i++) {\n const entity = msg.payload[i].data.entity_id;\n const value = parseFloat(msg.payload[i].data.state);\n\n if (entity.includes(\"sensor.ebusd_broadcast_outsidetemp\")) {\n sejour = value;\n } else if (entity.includes(\"roomtemp_temp\")) {\n chaudiere = value;\n } else if (entity.includes(\"roomtempcorrfact\")) {\n correction = value;\n }\n}\n\n// Vérification des valeurs valides\nif (sejour === null || chaudiere === null) {\n node.error(\"Données manquantes pour le calcul.\");\n return null;\n}\n\n// Calcul\nlet result = sejour - (chaudiere + correction);\n\n// Arrondi à 2 décimales\nmsg.payload = parseFloat(result.toFixed(2));\n\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1000,"y":1380,"wires":[["5c801c7f3ea0797f"]]},{"id":"5c801c7f3ea0797f","type":"mqtt out","z":"ede4cf8a90bd86c4","name":"","topic":"ebusd/e7c/RoomTempCorr/set","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"","x":1210,"y":1380,"wires":[]},{"id":"5c479c40c19455ee","type":"api-current-state","z":"ede4cf8a90bd86c4","name":"","server":"808d0070.6617c","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.ebusd_e7c_roomtempcorrfact","state_type":"str","blockInputOverrides":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":550,"y":1340,"wires":[["a70eecc141401f58"]]},{"id":"808d0070.6617c","type":"server","name":"Home Assistant","addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"","connectionDelay":false,"cacheJson":false,"heartbeat":false,"heartbeatInterval":"","statusSeparator":"","enableGlobalContextStore":false}]Node
function
code:Results
Since I haven't moved thermostat to boiler room yet, I used outside temperature as reference temperature. Here are the results:

Thermostat sensor temperature:
Outdoor sensor temperature:

Difference between thermostat and outdoor sensor:

Thermostat display temperature:

Example Use Cases
Final Thoughts
This method allows you to modernize your heating system while keeping the internal logic of the original thermostat (especially the heating curve).
You don’t need to reverse-engineer or replace everything — just redirect the key sensor input.
There you go, I hope this helps 😊
Axel
Beta Was this translation helpful? Give feedback.
All reactions