Thermostat Integration in Home Assistant for MBTEK Apollo (MC6)
Step-by-Step Guide
This guide assists in integrating the MBTEK Apollo thermostat (which is an MC6 under the hood) with Home Assistant. The MBTEK Apollo should have the right firmware out of the box. By following these steps, you will set up a virtual MQTT thermostat to talk to the modbus interface on the thermostat.
Also consult mc6 thread: MC6 Thermostat
And my code is based on this defunct guide: Termostato MC6 – Integración en Home Assistant – Domaray
Putting the Thermostat into Modbus Mode
To integrate the MBTEK Apollo thermostat with Home Assistant, you need to enable Modbus mode. Follow these steps to activate Modbus mode on the MC6 thermostat:
-
Configure Modbus on Apollo:
- Go to the thermostat’s display.
- Navigate to the settings menu (gear icon).
- Select “access level”
-
Unlock the Communications Config Screen:
- Click on “Screen Lock.”
- Enter the code
3036
. - Click on the lock icon to unlock the screen.
-
Enable Modbus TCP:
- Select “WiFi Modbus TCP.”
- An information screen will appear, and the relay will begin to activate and deactivate.
- Click “Exit,” and the device will restart.
-
Configure Network Settings:
- After the device restarts, go back to the Settings menu.
- Click on “Network settings.”
- Fill in the following fields:
- AP SSID: Enter the SSID of your WiFi router.
- AP Password: Enter the password for your WiFi.
- Gateway: Enter your router’s IP address.
- NetMask: Enter the network mask.
- IP: Assign a static IP address to your MC6 thermostat.
- Port: Set to
502
(default Modbus port).
-
Save and Restart:
- Save the settings and allow the thermostat to restart.
Note: Activating Modbus will disable the mobile app functionality of the thermostat.
Install the Mosquitto MQTT Add-on
- Navigate to the Supervisor tab in Home Assistant.
- Click on the Add-on Store.
- Search for “Mosquitto broker” and install it.
- Start the Mosquitto broker after installation.
Enable Modbus Add-on in Node-RED
Ensure the Modbus add-on is enabled in Node-RED:
- Go to the Node-RED add-on in Home Assistant.
- Start Node-RED and go to the Palette Manager.
- Search for “node-red-contrib-modbus” and install it.
Import Node-RED Flow
- Go to the Node-RED interface.
- Click on the hamburger menu (three horizontal lines) and select Import.
- Paste the following Node-RED flow and click Import:
[{"id":"c7ae10d2.116ce","type":"mqtt out","z":"56deb452.46025c","name":"Get Current Temperature","topic":"home/termostato/current_temperature/state","qos":"0","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"99ab3ff6.4455d","x":1750,"y":432,"wires":[]},{"id":"64a0672c.6b54c8","type":"mqtt in","z":"56deb452.46025c","name":"Set Temperature Setpoint","topic":"home/termostato/temperature_setpoint/set","qos":"0","datatype":"auto-detect","broker":"99ab3ff6.4455d","nl":false,"rap":false,"inputs":0,"x":1330,"y":1240,"wires":[["13520fdf.ee69a"]]},{"id":"967c846b.4ec788","type":"modbus-write","z":"56deb452.46025c","name":"Set Temperature Setpoint","showStatusActivities":false,"showErrors":false,"showWarnings":true,"unitid":"","dataType":"MHoldingRegisters","adr":"64","quantity":"1","server":"36e9f5f4.01499a","emptyMsgOnFail":false,"keepMsgProperties":false,"delayOnStart":false,"startDelayTime":"","x":2070,"y":1240,"wires":[[],[]]},{"id":"a4fd90ac.9d17b","type":"mqtt out","z":"56deb452.46025c","name":"Get Temperature Setpoint","topic":"home/termostato/temperature_setpoint/state","qos":"0","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"99ab3ff6.4455d","x":1750,"y":592,"wires":[]},{"id":"582f3cd6.0433b4","type":"json","z":"56deb452.46025c","name":"","property":"payload","action":"","pretty":false,"x":1870,"y":1240,"wires":[["967c846b.4ec788"]]},{"id":"13520fdf.ee69a","type":"function","z":"56deb452.46025c","name":"","func":"msg.payload*=10;\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1560,"y":1240,"wires":[["bf5397e8.9daf18"]]},{"id":"bf5397e8.9daf18","type":"template","z":"56deb452.46025c","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"[{{ payload }}]","output":"str","x":1720,"y":1240,"wires":[["582f3cd6.0433b4"]]},{"id":"93c8a67f.ff0818","type":"mqtt out","z":"56deb452.46025c","name":"Get Current Mode","topic":"home/termostato/mode/mode","qos":"0","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"99ab3ff6.4455d","x":2010,"y":660,"wires":[]},{"id":"cbde474c.988668","type":"mqtt out","z":"56deb452.46025c","name":"Get Current Mode","topic":"home/termostato/status/state","qos":"0","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"99ab3ff6.4455d","x":1730,"y":700,"wires":[]},{"id":"1e7e7c1a.ced034","type":"mqtt out","z":"56deb452.46025c","name":"Get Current Humidity","topic":"home/termostato/humidity/state","qos":"0","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"99ab3ff6.4455d","x":1740,"y":512,"wires":[]},{"id":"1b9065ba.078dfa","type":"modbus-flex-getter","z":"56deb452.46025c","name":"","showStatusActivities":false,"showErrors":false,"showWarnings":true,"logIOActivities":false,"server":"36e9f5f4.01499a","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":false,"delayOnStart":false,"startDelayTime":"","x":1150,"y":740,"wires":[["c57738f6.fa7538","5db36dd8.ca6654","b7d029fb.83d3c8","cd0f13e3.29767","efaf078c.272528","31702aeb72712b58","b209f42e78567e36"],[]]},{"id":"5d5a96ab.394ab8","type":"function","z":"56deb452.46025c","name":"Prepare Request","func":"var newMsg = { payload: msg.payload.length,\n topic: \"\"\n};\nvar ts = new Date();\n\nnewMsg.payload = {\n 'value': ts.getTime(),\n 'fc': 3,\n 'unitid': 1,\n 'address': 0,\n 'quantity': 86\n};\n\nreturn newMsg;\n","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1110,"y":460,"wires":[["1b9065ba.078dfa"]]},{"id":"e372074b.8e3c48","type":"inject","z":"56deb452.46025c","name":"Read","props":[{"p":"payload"}],"repeat":"10","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"num","x":850,"y":420,"wires":[["5d5a96ab.394ab8"]]},{"id":"c57738f6.fa7538","type":"function","z":"56deb452.46025c","name":"Get Temperature Setpoint","func":"const register = 64;\nmsg.payload = msg.payload[register]; \nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1450,"y":592,"wires":[["a4fd90ac.9d17b"]]},{"id":"5db36dd8.ca6654","type":"function","z":"56deb452.46025c","name":"Get Current Temperature","func":"const register = 0;\nmsg.payload = msg.payload[register]; \nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1450,"y":432,"wires":[["c7ae10d2.116ce"]]},{"id":"b7d029fb.83d3c8","type":"function","z":"56deb452.46025c","name":"Get Current Humidity","func":"const register = 2;\nmsg.payload = msg.payload[register]; \nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1440,"y":512,"wires":[["1e7e7c1a.ced034"]]},{"id":"cd0f13e3.29767","type":"function","z":"56deb452.46025c","name":"Get Current Mode","func":"const register = 62;\nmsg.payload = msg.payload[register]; \nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1430,"y":660,"wires":[["cbde474c.988668","2ad7f0fc.1f337"]]},{"id":"efaf078c.272528","type":"function","z":"56deb452.46025c","name":"Get Action Status","func":"const register = 4; //was 9 \nmsg.payload = msg.payload[register]; \nif(msg.payload == 0){\n msg.payload = \"Idle\";\n} else {\n msg.payload = \"Cool\";\n}\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1430,"y":860,"wires":[["1da278e0.f0bf57"]]},{"id":"1da278e0.f0bf57","type":"mqtt out","z":"56deb452.46025c","name":"Get Action","topic":"home/termostato/action/state","qos":"0","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"99ab3ff6.4455d","x":1710,"y":860,"wires":[]},{"id":"2ad7f0fc.1f337","type":"change","z":"56deb452.46025c","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"1","fromt":"num","to":"heat","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"2","fromt":"num","to":"cool","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"3","fromt":"num","to":"fan_only","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"4","fromt":"num","to":"dehumidify","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"5","fromt":"num","to":"auto","tot":"str"},{"t":"set","p":"savedMode","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1720,"y":660,"wires":[["93c8a67f.ff0818"]]},{"id":"fan_speed_set","type":"mqtt in","z":"56deb452.46025c","name":"Set Fan Mode","topic":"home/termostato/fan_mode/set","qos":"0","datatype":"auto-detect","broker":"99ab3ff6.4455d","nl":false,"rap":true,"rh":0,"inputs":0,"x":1290,"y":1340,"wires":[["fan_speed_convert"]]},{"id":"fan_speed_convert","type":"function","z":"56deb452.46025c","name":"Convert Fan Mode","func":"if (!msg.payload || typeof msg.payload !== 'string') {\n node.error(\"Payload is not a string: \" + typeof msg.payload);\n return null; // Stop the flow if payload is not valid\n}\n\nconst speed = msg.payload.toLowerCase();\nlet modbusValue;\n\nswitch(speed) {\n case 'high':\n modbusValue = \"0\";\n break;\n case 'medium':\n modbusValue = \"1\";\n break;\n case 'low':\n modbusValue = \"2\";\n break;\n case 'auto':\n modbusValue = \"3\";\n break;\n default:\n node.warn('Invalid fan speed: ' + speed);\n return null;\n}\n\nmsg.payload = modbusValue;\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1830,"y":1340,"wires":[["0c6aa9d636748ad1"]]},{"id":"859502bc48cbb8b1","type":"mqtt out","z":"56deb452.46025c","name":"Get Current Fan Status","topic":"home/termostato/fan_mode/state","qos":"0","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"99ab3ff6.4455d","x":1750,"y":360,"wires":[]},{"id":"31702aeb72712b58","type":"function","z":"56deb452.46025c","name":"Get Current Fan Mode","func":"const register = 63;\nmsg.payload = msg.payload[register]; \nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1440,"y":360,"wires":[["859502bc48cbb8b1","f3245d050175dba5"]]},{"id":"0c6aa9d636748ad1","type":"modbus-write","z":"56deb452.46025c","name":"Set Status","showStatusActivities":false,"showErrors":false,"showWarnings":true,"unitid":"","dataType":"MHoldingRegisters","adr":"63","quantity":"1","server":"36e9f5f4.01499a","emptyMsgOnFail":false,"keepMsgProperties":false,"delayOnStart":false,"startDelayTime":"","x":2070,"y":1340,"wires":[[],[]]},{"id":"b209f42e78567e36","type":"function","z":"56deb452.46025c","name":"Get On/Off Status","func":"const register = 61\nmsg.payload = msg.payload[register]; \nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1430,"y":760,"wires":[["fdc0f6621b4e660d"]]},{"id":"fdc0f6621b4e660d","type":"mqtt out","z":"56deb452.46025c","name":"Get On/Off Status","topic":"home/termostato/onoff/state","qos":"0","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"99ab3ff6.4455d","x":1730,"y":760,"wires":[]},{"id":"f3245d050175dba5","type":"change","z":"56deb452.46025c","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"0","fromt":"num","to":"high","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"1","fromt":"num","to":"medium","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"2","fromt":"num","to":"low","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"3","fromt":"num","to":"auto","tot":"str"},{"t":"set","p":"savedFanMode","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1720,"y":320,"wires":[["f8552a6ed3f07a6b"]]},{"id":"f8552a6ed3f07a6b","type":"mqtt out","z":"56deb452.46025c","name":"Get Current Fan Mode","topic":"home/termostato/fan_mode/mode","qos":"0","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"99ab3ff6.4455d","x":1960,"y":320,"wires":[]},{"id":"8cbe39de04565ae6","type":"mqtt in","z":"56deb452.46025c","name":"Set Mode","topic":"home/termostato/mode/set","qos":"0","datatype":"auto-detect","broker":"99ab3ff6.4455d","nl":false,"rap":true,"rh":0,"inputs":0,"x":1280,"y":1520,"wires":[["4a0c662259317d6d"]]},{"id":"4a0c662259317d6d","type":"function","z":"56deb452.46025c","name":"Convert Mode","func":"if (!msg.payload || typeof msg.payload !== 'string') {\n node.error(\"Payload is not a string: \" + typeof msg.payload);\n return null; // Stop the flow if payload is not valid\n}\n\nconst speed = msg.payload.toLowerCase();\nlet modbusValue;\n\nswitch(speed) {\n case 'heat':\n modbusValue = \"0\";\n break;\n case 'cool':\n modbusValue = \"1\";\n break;\n case 'fan_only':\n modbusValue = \"2\";\n break;\n case 'dehumidify':\n modbusValue = \"3\";\n break;\n case 'auto':\n modbusValue = \"4\";\n break;\n default:\n node.warn('Invalid mode: ' + speed);\n return null;\n}\n\nmsg.payload = modbusValue;\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1840,"y":1520,"wires":[["92482b81b3077544"]]},{"id":"92482b81b3077544","type":"modbus-write","z":"56deb452.46025c","name":"Set Mode","showStatusActivities":false,"showErrors":false,"showWarnings":true,"unitid":"","dataType":"MHoldingRegisters","adr":"62","quantity":"1","server":"36e9f5f4.01499a","emptyMsgOnFail":false,"keepMsgProperties":false,"delayOnStart":false,"startDelayTime":"","x":2060,"y":1520,"wires":[[],[]]},{"id":"861d0968.494578","type":"mqtt in","z":"56deb452.46025c","name":"Set On/Off","topic":"home/termostato/onoff/set","qos":"0","datatype":"auto-detect","broker":"99ab3ff6.4455d","nl":false,"rap":false,"inputs":0,"x":1280,"y":1140,"wires":[["5257703f.d5da3"]]},{"id":"5257703f.d5da3","type":"template","z":"56deb452.46025c","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"[{{ payload }}]","output":"str","x":1520,"y":1140,"wires":[["8685cea6.1935c"]]},{"id":"8685cea6.1935c","type":"json","z":"56deb452.46025c","name":"","property":"payload","action":"","pretty":false,"x":1670,"y":1140,"wires":[["940d1c82.2b838"]]},{"id":"940d1c82.2b838","type":"modbus-write","z":"56deb452.46025c","name":"Set Status","showStatusActivities":false,"showErrors":false,"showWarnings":true,"unitid":"","dataType":"MHoldingRegisters","adr":"61","quantity":"1","server":"36e9f5f4.01499a","emptyMsgOnFail":false,"keepMsgProperties":false,"delayOnStart":false,"startDelayTime":"","x":1910,"y":1140,"wires":[[],[]]},{"id":"527f2f054560cb64","type":"complete","z":"56deb452.46025c","name":"Read After Write","scope":["967c846b.4ec788","0c6aa9d636748ad1","92482b81b3077544","940d1c82.2b838"],"uncaught":false,"x":860,"y":560,"wires":[["5d5a96ab.394ab8"]]},{"id":"99ab3ff6.4455d","type":"mqtt-broker","name":"MQTT HA Server","broker":"localhost","port":"1883","tls":"","clientid":"","autoConnect":true,"usetls":false,"compatmode":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"autoUnsubscribe":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"36e9f5f4.01499a","type":"modbus-client","name":"Termostato","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"failureLogEnabled":true,"tcpHost":"192.168.1.89","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"","unit_id":"1","commandDelay":"200","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true,"showErrors":true,"showWarnings":true,"showLogs":true}]
- Open the Configuration Menu (three horizontal lines or a hamburger icon).
- Navigate to the Termostato Node
- Edit “IP Address” and “Port”. Recommend making IP static on your router. Port should be 502.
- Deploy Changes - “Deploy” button is usually located in the top right corner.
Modify configuration.yaml
# MQTT Broker Configuration
mqtt:
# MQTT Climate Configuration
climate:
- name: apollo
modes:
- "cool"
- "fan_only"
fan_modes:
- "low"
- "medium"
- "high"
- "auto"
fan_mode_command_topic: "home/termostato/fan_mode/set"
fan_mode_state_topic: "home/termostato/fan_mode/mode"
#fan_mode_state_template: "{{ value_json }}" # Modify as needed
temperature_command_topic: "home/termostato/temperature_setpoint/set"
temperature_state_topic: "home/termostato/temperature_setpoint/state"
temperature_state_template: "{{ value_json|float / 10 }}"
current_temperature_topic: "home/termostato/current_temperature/state"
current_temperature_template: "{{ value_json|float / 10 }}"
mode_state_topic: "home/termostato/mode/mode"
mode_command_topic: "home/termostato/mode/set"
temperature_unit: f
max_temp: 90
min_temp: 65
temp_step: 1
retain: true
# MQTT Switch Configuration
switch:
- name: "Apollo On/Off"
state_topic: "home/termostato/onoff/state"
command_topic: "home/termostato/onoff/set"
value_template: "{{ value_json }}"
payload_on: "1"
payload_off: "0"
qos: 0
retain: true
icon: mdi:power
# MQTT Sensor Configuration
sensor:
- name: "Apollo Humidity"
state_topic: "home/termostato/humidity/state"
value_template: "{{ value_json|int }}"
device_class: humidity
unit_of_measurement: '%' # Specify the unit of measurement as percentage
- name: "Apollo Temperature"
state_topic: "home/termostato/current_temperature/state"
value_template: "{{ value_json|float / 10 }}"
device_class: temperature
unit_of_measurement: '°F'
Modify the Lovelace Interface
- Navigate to the Home Assistant dashboard.
- Click on the “Configure UI” button (usually found in the top right corner).
- Click on the “Add Card” button at the bottom right.
- Select “Manual” from the card picker.
- Copy and paste the following configuration into the card configuration:
square: false
type: grid
columns: 1
cards:
- type: thermostat
entity: climate.apollo
features:
- style: icons
hvac_modes:
- cool
- fan_only
type: climate-hvac-modes
- style: icons
fan_modes:
- low
- medium
- high
- auto
type: climate-fan-modes
show_current_as_primary: false
- type: entities
entities:
- entity: switch.apollo_on_off
- entity: sensor.apollo_temperature
- entity: sensor.apollo_humidity
show_header_toggle: false
state_color: true
Other Lock Code PINS
8657 Master key
5209 Set lock pin
0907 Installer
1976 MQTT Setup [MBTEK claims to be working on this]
3036 Communications Config Screen