HomeAssistant – Wolf CWL-2 Modbus communication

A quick tutorial on connecting your HomeAssistant to read and write data to Wolf CWL-2 (and other Wolf devices that use the Modbus). All data in this tutorial are get from live installation so you need to edit it to match your setup(unit id/network IP etc).

Requirements

  1. Modbus to TCP bridge – ZLAN5143D Din Rail Mounting Tiny Size RS485 Serial port to TCP/IP Ethernet Converter server Modbus RTU to Modbus TCP
  2. Wolf units with Modbus support

Connection

You are able to connect multiple devices in the chain. In my case, I use one bridge to communicate with 3 Wolf units.

If your communication not working try switching cables A<->B on the unit side or on the bridge side. On other units, the connection must be the same !! Some manufacturers use different naming.

Modbus bridge setup

After you connect the Modbus bridge to the network, it should be set to DHCP client so you need to find its IP. The best way to do it is just to check your router and lease table. The default password for ZLAN is empty. Below you can find the required settings. The baud rate and other serial settings must match your setting on wolf units. Also in case you have multiple units you have to set different unit addresses in each of them.

Wolf unit setup

In the wolf unit, you need to go to the setting in touch display, then find the communication and enable the Modbus, and set the required baud rate, unit id, etc. the params must match with bridge settings.

Home assistant settings

Ok, there is the tricky part of the process. How to get data in Home Assistant. For this, I will use the nore-red addon because I use the node-red for almost every automatization. So you need to install the node-red addon to HA(check google there are many tutorials).

We will need this nodes:

  1. Modbus-Flex-Getter
  2. Modbus-Flex-Write

These nodes need a set/select server and input data to know what to do. The server setup is easy. If you open one of the nodes there is a dropdown box labeled server. If you click the pencil icon you can set up your server. Then you can use the same setup in all nodes. You need just to select it from the dropdown.

Getting data and writing data

The Modbus flex getter needs data as input messages so we can utilize the function node for it. The getter node can read the data in the series, but my required data are in the different parts of memory so we use multiple nodes to get all values. There is an example of a function to prepare request messages. After I get the data I push them to Homa Assistant as the MQTT message (this could be an outdated approach to this problem but I am used to it.). The almost same approach is to set the data to units. I got multiple helpers in Homa Assistants and read the values in some pool intervals and send them to units.

msg.payload = { 
value: msg.payload,
'fc': 4,
'unitid': 20,
'address': 4022,
'quantity': 3 } 
return msg

Final node-red flow

Below you can find the example of my flow in node-red. It extracts basic values from the unit and sends the required level of ventilation. You can easily import it to your node-red. Just click the 3lines (burger menu) on the top right -> import and paste the JSON.

[{"id":"e369029896741c72","type":"group","z":"7fa0071bab063064","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["728eefe682423e6d","6fd27a1cf79377ac","406715923ec137d5","26b34a74c889429d","fecc02f119c34b6c","c4e147e48d495382","9dabaa8616ed9c80","0c5157dce9b5a67f","01d112de11419682","8ec7ba82f06101fd","2a26b1c93c81fe24","6cbba25dfb8c3c5d","3a3eda4a92c3daa6","f63910f742253338","5109a40fec41f9d5","2e64aba4fe310450","ef95ff0ca8c96f5d","8b1d77230bce7e52","d840814a978c23a5","323ce8395bad4512","4de55b9c860c90c2","63608bc8b925d683","9c4ab06114c6869e","891c79ad54396d38","5f24e7695ca12fe0","70870784fcf4f9fc","eb78463a185951bb","eebd879642bfc6f2","b662b8db88843486","6faaedfe82d72fdf","2e424565a2cae152","d9af14cd68aadbe5","b54b4941b0758df0","9b4e79af6c115915","ca53354910f6e126","2b0d77d60d019022","ae1fff70b248189c","68c7881d4ceac7e1","fd1c70be7c66e4c5"],"x":14,"y":19,"w":1112,"h":622},{"id":"728eefe682423e6d","type":"inject","z":"7fa0071bab063064","g":"e369029896741c72","name":"Every 15sec","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"15","crontab":"","once":true,"onceDelay":"15","topic":"","payloadType":"date","x":140,"y":60,"wires":[["6fd27a1cf79377ac"]]},{"id":"6fd27a1cf79377ac","type":"function","z":"7fa0071bab063064","g":"e369029896741c72","name":"Block1","func":"msg.payload = { \nvalue: msg.payload,\n'fc': 4,\n'unitid': 20,\n'address': 4022,\n'quantity': 3 } \nreturn msg\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":120,"wires":[["3a3eda4a92c3daa6"]]},{"id":"406715923ec137d5","type":"function","z":"7fa0071bab063064","g":"e369029896741c72","name":"Block2","func":"msg.payload = { \nvalue: msg.payload,\n'fc': 4,\n'unitid': 20,\n'address': 4030,\n'quantity': 8 } \nreturn msg\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":240,"wires":[["5f24e7695ca12fe0"]]},{"id":"26b34a74c889429d","type":"function","z":"7fa0071bab063064","g":"e369029896741c72","name":"Block3","func":"msg.payload = { \nvalue: msg.payload,\n'fc': 4,\n'unitid': 20,\n'address': 4040,\n'quantity': 8 } \nreturn msg\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":300,"wires":[["70870784fcf4f9fc"]]},{"id":"fecc02f119c34b6c","type":"function","z":"7fa0071bab063064","g":"e369029896741c72","name":"Block4","func":"msg.payload = { \nvalue: msg.payload,\n'fc': 4,\n'unitid': 20,\n'address': 4100,\n'quantity': 1 } \nreturn msg\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":360,"wires":[["eb78463a185951bb"]]},{"id":"c4e147e48d495382","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Ventilation mode","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[0]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/mode","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":770,"y":120,"wires":[["4de55b9c860c90c2"]]},{"id":"9dabaa8616ed9c80","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Supply pressure","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[1]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/pressure_supply","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":160,"wires":[["4de55b9c860c90c2"]]},{"id":"0c5157dce9b5a67f","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Exhaust pressure","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[2]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/pressure_exhaust","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":770,"y":200,"wires":[["4de55b9c860c90c2"]]},{"id":"01d112de11419682","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Supply air","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[2]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/air_supply","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":240,"wires":[["4de55b9c860c90c2"]]},{"id":"8ec7ba82f06101fd","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Supply fan rpm","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[4]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/rpm_supply","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":280,"wires":[["4de55b9c860c90c2"]]},{"id":"2a26b1c93c81fe24","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Supply temperature","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[6]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/temp_inlet","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":770,"y":320,"wires":[["4de55b9c860c90c2"]]},{"id":"6cbba25dfb8c3c5d","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Inlet humidity","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[7]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/humidity_inlet","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":360,"wires":[["4de55b9c860c90c2"]]},{"id":"3a3eda4a92c3daa6","type":"modbus-flex-getter","z":"7fa0071bab063064","g":"e369029896741c72","name":"","showStatusActivities":true,"showErrors":true,"logIOActivities":false,"server":"52bf34f035c306ba","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":true,"x":510,"y":120,"wires":[["c4e147e48d495382","9dabaa8616ed9c80","0c5157dce9b5a67f"],[]]},{"id":"f63910f742253338","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Exhaust air","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[2]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/air_exhaust","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":400,"wires":[["4de55b9c860c90c2"]]},{"id":"5109a40fec41f9d5","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Exhaust fan rpm","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[4]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/rpm_exhaust","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":440,"wires":[["4de55b9c860c90c2"]]},{"id":"2e64aba4fe310450","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Exhaust temperature","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[6]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/temp_exhaust","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":480,"wires":[["4de55b9c860c90c2"]]},{"id":"ef95ff0ca8c96f5d","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Exhaust humidity","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[7]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/humidity_exhaust","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":770,"y":520,"wires":[["4de55b9c860c90c2"]]},{"id":"8b1d77230bce7e52","type":"change","z":"7fa0071bab063064","g":"e369029896741c72","name":"Dirty filter","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[0]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"wolf1/filter","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":560,"wires":[["4de55b9c860c90c2"]]},{"id":"d840814a978c23a5","type":"mqtt out","z":"7fa0071bab063064","g":"e369029896741c72","name":"","topic":"","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"51780fb1.b79f3","x":990,"y":360,"wires":[]},{"id":"323ce8395bad4512","type":"debug","z":"7fa0071bab063064","g":"e369029896741c72","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1010,"y":280,"wires":[]},{"id":"4de55b9c860c90c2","type":"function","z":"7fa0071bab063064","g":"e369029896741c72","name":"Help merge","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1010,"y":320,"wires":[["323ce8395bad4512","d840814a978c23a5"]]},{"id":"63608bc8b925d683","type":"delay","z":"7fa0071bab063064","g":"e369029896741c72","name":"","pauseType":"delay","timeout":"300","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":210,"y":240,"wires":[["406715923ec137d5"]]},{"id":"9c4ab06114c6869e","type":"delay","z":"7fa0071bab063064","g":"e369029896741c72","name":"","pauseType":"delay","timeout":"600","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":210,"y":300,"wires":[["26b34a74c889429d"]]},{"id":"891c79ad54396d38","type":"delay","z":"7fa0071bab063064","g":"e369029896741c72","name":"","pauseType":"delay","timeout":"900","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":210,"y":360,"wires":[["fecc02f119c34b6c"]]},{"id":"5f24e7695ca12fe0","type":"modbus-flex-getter","z":"7fa0071bab063064","g":"e369029896741c72","name":"","showStatusActivities":true,"showErrors":true,"logIOActivities":false,"server":"52bf34f035c306ba","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":true,"x":510,"y":240,"wires":[["01d112de11419682","8ec7ba82f06101fd","2a26b1c93c81fe24","6cbba25dfb8c3c5d"],[]]},{"id":"70870784fcf4f9fc","type":"modbus-flex-getter","z":"7fa0071bab063064","g":"e369029896741c72","name":"","showStatusActivities":true,"showErrors":true,"logIOActivities":false,"server":"52bf34f035c306ba","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":true,"x":510,"y":300,"wires":[["f63910f742253338","5109a40fec41f9d5","2e64aba4fe310450","ef95ff0ca8c96f5d"],[]]},{"id":"eb78463a185951bb","type":"modbus-flex-getter","z":"7fa0071bab063064","g":"e369029896741c72","name":"","showStatusActivities":true,"showErrors":true,"logIOActivities":false,"server":"52bf34f035c306ba","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":true,"x":510,"y":360,"wires":[["8b1d77230bce7e52"],[]]},{"id":"eebd879642bfc6f2","type":"inject","z":"7fa0071bab063064","g":"e369029896741c72","name":"Every 45 sec","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"45","crontab":"","once":true,"onceDelay":"15","topic":"","payloadType":"date","x":140,"y":120,"wires":[["63608bc8b925d683","9c4ab06114c6869e","891c79ad54396d38"]]},{"id":"b662b8db88843486","type":"poll-state","z":"7fa0071bab063064","g":"e369029896741c72","name":"Required mode 1","server":"ef0b336b.b18ff","version":2,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"15","updateIntervalType":"num","updateIntervalUnits":"seconds","outputinitially":false,"outputonchanged":false,"entity_id":"input_select.wolf_1_level","state_type":"str","halt_if":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"x":140,"y":440,"wires":[["6faaedfe82d72fdf","ca53354910f6e126","2b0d77d60d019022"]]},{"id":"6faaedfe82d72fdf","type":"function","z":"7fa0071bab063064","g":"e369029896741c72","name":"Set modbus","func":"msg.payload = { \n'value' : 2,\n'fc': 6,\n'unitid': 20,\n'address': 8000 ,\n'quantity': 1 } \n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":440,"wires":[["2e424565a2cae152"]]},{"id":"2e424565a2cae152","type":"modbus-flex-write","z":"7fa0071bab063064","g":"e369029896741c72","name":"","showStatusActivities":false,"showErrors":false,"server":"52bf34f035c306ba","emptyMsgOnFail":false,"keepMsgProperties":false,"x":510,"y":440,"wires":[["d9af14cd68aadbe5"],[]]},{"id":"d9af14cd68aadbe5","type":"debug","z":"7fa0071bab063064","g":"e369029896741c72","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":750,"y":600,"wires":[]},{"id":"b54b4941b0758df0","type":"function","z":"7fa0071bab063064","g":"e369029896741c72","name":"Set modbus","func":"\n\nmsg.payload = { \n'value' : 100*msg.payload,\n'fc': 6,\n'unitid': 20,\n'address': 8002 ,\n'quantity': 1 } \n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":500,"wires":[["9b4e79af6c115915"]]},{"id":"9b4e79af6c115915","type":"modbus-flex-write","z":"7fa0071bab063064","g":"e369029896741c72","name":"","showStatusActivities":true,"showErrors":true,"server":"52bf34f035c306ba","emptyMsgOnFail":false,"keepMsgProperties":false,"x":510,"y":500,"wires":[["d9af14cd68aadbe5"],[]]},{"id":"ca53354910f6e126","type":"delay","z":"7fa0071bab063064","g":"e369029896741c72","name":"","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":130,"y":500,"wires":[["b54b4941b0758df0"]]},{"id":"2b0d77d60d019022","type":"function","z":"7fa0071bab063064","g":"e369029896741c72","name":"Block4","func":"msg.payload = { \nvalue: msg.payload,\n'fc': 3,\n'unitid': 20,\n'address': 8000,\n'quantity': 4 } \nreturn msg\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":150,"y":580,"wires":[["ae1fff70b248189c"]]},{"id":"ae1fff70b248189c","type":"modbus-flex-getter","z":"7fa0071bab063064","g":"e369029896741c72","name":"","showStatusActivities":true,"showErrors":true,"logIOActivities":false,"server":"52bf34f035c306ba","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":true,"x":310,"y":580,"wires":[["68c7881d4ceac7e1"],[]]},{"id":"68c7881d4ceac7e1","type":"debug","z":"7fa0071bab063064","g":"e369029896741c72","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":510,"y":580,"wires":[]},{"id":"fd1c70be7c66e4c5","type":"inject","z":"7fa0071bab063064","g":"e369029896741c72","name":"Manual","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":110,"y":160,"wires":[["6fd27a1cf79377ac","63608bc8b925d683","9c4ab06114c6869e","891c79ad54396d38"]]},{"id":"52bf34f035c306ba","type":"modbus-client","name":"Modbus","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":true,"queueLogEnabled":true,"tcpHost":"192.168.10.9","tcpPort":"4196","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"","unit_id":20,"commandDelay":1,"clientTimeout":3000,"reconnectOnTimeout":true,"reconnectTimeout":2000,"parallelUnitIdsAllowed":true},{"id":"51780fb1.b79f3","type":"mqtt-broker","name":"HomeAssistant","broker":"192.168.10.12","port":"1883","clientid":"","usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":""},{"id":"ef0b336b.b18ff","type":"server","name":"Home Assistant","version":4,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m"}]

Other resources

Below you can find the manual of the control board. In the documentation, you can find every memory register that you can read and write. Using the Modbus is quite demanding so you need to invest some time to study. I get this from Wolf support.