Attach Stiebel Eltron LWZ 504 using USBtin and CAN bus

This is about how to setup the OpenHab Raspberry to get information from a Stiebel Eltron LWZ 504 without buying much to expensive Gateways. To reach that target we will use the CAN bus, that is available at the LWZ 504. We will not use the serial- or USB-Port that is in front of the heating.

This tutorial may also work for other Stiebel Eltron Heatings that have a CAN bus.

Required Hardware

You will need a USB device, that is able to connect to the CAN bus. I use USBtin to connect.
You can get it on Amazon* or directly at the manufacturer. If you have prime, at time of writing Amazon is cheaper (incl. shipping costs), but if you don’t have it, the direct order is cheaper.

You will have to connect or solder a cable to the three PINs of the USBtin and connect the other side to the LWZ 504. I am using a standard Ethernet cable to connect.

USBtin with soldered connection cables

Connection to the CAN Bus interface at the heating

Prepare

beside of updating and upgrading Raspbian and it’s application it is also required to update the kernel and the firmware of the Raspberry. Todo so, execute:

sudo apt-get update
sudo apt-get upgrade
sudo rpi-update
sudo reboot

After the reboot, be sure, that the USBtin is not connected to the Raspberry right now.
Execute the following commands to load required kernel modules.

sudo modprobe can
sudo modprobe can-raw
sudo modprobe slcan

Now plug in your USBtin and execute

tail /var/log/kern.log

you should see logs, that a USB device, the USBtin, was connected and in the last line you see the logical interface name.

That will be the interface, you can use to communicate with the CAN Bus using USBtin.

Now we configure the interface. Clone the CAN utils Github repository and compile it:

cd ~
sudo apt-get install -y git
git clone https://github.com/linux-can/can-utils.git
cd can-utils
make

Now we attach and configure the interface. In case your interface was not ttyACM0, you have to replace the interface name with your value.
Note: the -s1 in the first statement means 20.000 bit as bitrate which seems to be the bitrate Stiebel Eltron uses. -b 11 determinates to use 11 bit based encoding.

sudo ./slcan_attach -f -s1 -b 11 -o /dev/ttyACM0
sudo ./slcand ttyACM0 slcan0
sudo ifconfig slcan0 up

Let’s check the configuration:

Execute

./candump slcan0

In case your CAN bus has any active devices right now, you should see CAN bus message in the output. In case of Stiebel Eltron heatings, there should be at least one package each minute that is transmitting the current time of the heating.

Finally we want that the slcan0 port is created on each reboot. Create a scriptfile:

nano /home/pi/createSlcan.sh

Paste the following content:

#! /bin/sh
sudo /home/pi/can-utils/slcan_attach -f -s1 -b 11 -o /dev/ttyACM0
sudo /home/pi/can-utils/slcand ttyACM0 slcan0
sudo ifconfig slcan0 up
exit 0

Save with Ctrl+O and quit with Ctrl+X.

Now we want to execute that file on each reboot. To do that we add the path the the file int the file /etc/rc.local:

sudo mv /home/pi/createSlcan.sh /etc/init.d

Finally mark the file as executable and set the startup settings:

cd /etc/init.d
sudo chmod 755 createSlcan.sh
sudo update-rc.d createSlcan.sh defaults

On each reboot the file will be executed and connects the canbus to the Raspberry.

Install can2mqtt

To read the USBtin and send information to OpenHab we will use can2mqtt. OpenHab will be able to handle the MQTT messages.

We will download the can2mqtt library to a new folder. Create the folder:

sudo mkdir /etc/can2mqtt

change to that folder:

cd /etc/can2mqtt

Go to https://github.com/Hunv/can2mqtt/releases and get the download link of the latest release. i.e. https://github.com/Hunv/can2mqtt/releases/download/v2/can2mqtt_core_v2.zip

Execute the following commands to download and extract that file:

sudo wget https://github.com/Hunv/can2mqtt/releases/download/v2/can2mqtt_core_v2.zip
sudo unzip ./can2mqtt_core_v2.zip

Now we need to download and install .Net Core 2.2 or later to execute the can2mqtt application. The following part may change because Microsoft changes the .Net Core website very often. First we need to get the downloadlink. Goto https://dotnet.microsoft.com/download/thank-you/dotnet-runtime-2.2.6-linux-arm32-binaries and copy the link address shown (see arrow below). (i.e. https://download.visualstudio.microsoft.com/download/pr/428aaa32-f66c-4847-b845-aa21f90504e4/1cf033db866414997140c2672bd75069/dotnet-runtime-2.2.6-linux-arm.tar.gz):

sudo apt-get -y update
wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo add-apt-repository universe
sudo apt-get install apt-transport-https
sudo dpkg --purge packages-microsoft-prod && sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install dotnet-runtime-2.2

Remark: the last command will change for newer versions. Replace the 2.2 with the version you have.

Check .Net Core installation:

dotnet --info

You should see something similar to this:

Configure OpenHab MQTT Broker to receive MQTT messages

This is really easy. Open the PaperUI in OpenHAB and navigate to “Addons” and select the “Misc” tab. Install the “Embedded MQTT Broker” addon. Done.

Register canlogserver as service

Execute this to create a new service definition file using the nano editor:

sudo nano /etc/systemd/system/canlogserver.service

Paste the following to your file:

[Unit]
Description=canlogserver
After=network.target

[Service]
ExecStart=/home/pi/can-utils/canlogserver slcan0
WorkingDirectory=/home/pi/can-utils
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi

[Install]
WantedBy=multi-user.target

Execute this to reload the systemctl daemon-configs:

sudo systemctl daemon-reload

execute this to start the service and check the status:

sudo systemctl start canlogserver.service
sudo systemctl status canlogserver.service
sudo systemctl enable canlogserver.service

the result should look like this:

Register and configure can2mqtt as service

Execute this to create a new service definition file using the nano editor:

sudo nano /etc/systemd/system/can2mqtt.service

Paste the following to your file and replace the IPs in that ExecStart line. If everything is running on your device, it should be the local IP. Be aware, that the loopback-address (127.0.0.1) does not work!

[Unit]
Description=can2mqtt
After=network.target

[Service]
ExecStart=/usr/local/bin/dotnet /etc/can2mqtt/can2mqtt_core.dll --Daemon:CanServer="192.168.0.10" --Daemon:MqttServer="192.168.0.10" --Daemon:MqttClientId="Can2Mqtt" --Daemon:MqttTopic="Heating" --Daemon:MqttTranslator="StiebelEltron" --Daemon:CanlogserverPath="/home/pi/can-utils/canlogserver" --Daemon:CanlogserverSocket="slcan0" --Daemon:NoUnits="true"
WorkingDirectory=/etc/can2mqtt/
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi

[Install]
WantedBy=multi-user.target

Execute this to reload the systemctl daemon-configs:

sudo systemctl daemon-reload

execute this to start the service and check the status:

sudo systemctl start can2mqtt.service
sudo systemctl status can2mqtt.service
sudo systemctl enable can2mqtt.service

the result should look like this:

Setup Heating thing in OpenHab

comming soon…

Configure CAN requests

To actively request the latest values of the heating and not just waiting for it to send, we can execute the application cansend via Exec Binding. To do so, we need to install the Exec Binding via Paper UI at “Addons” and the “Bindings” tab. Search for “Exec” and install the binding.

After that in the Paper UI navigate to “Configuration” => “Things” and click the blue + to add a new thing manually.

In the list of bindings, select the Exec Binding, followed by selecting “Command” from the next list.

Now we can configure what we need. Enter a good name, in this case for trigger the sending of the outside temperature. Enter the command “/home/pi/can-utils/cansend slcan0 6A2#3100FA000C0000” to make the binding executing the cansend application we installed before with the parameters required to read the outside temperature. Also set the interval to a setting that makes sense. i.e. 10 Minutes (=600 seconds) is very frequent for that value.

Click the blue bubble with the check to save our new thing, that just executes the command every 10 minutes. You will see, that the temperature property we configured for our heating thing before will have a value now!

Remark: If it don’t work, it may be possible, that you have to replace the “6A2” with “680” in each command. This seems to be related to the heating model you have. For Stiebel Eltron LWZ 504 the 6A2 is correct.

To configure the same for other settings, just replace the last part of the command for the following properties:

Outside temperature /home/pi/can-utils/cansend slcan0 6A2#3100FA000C0000
Operational Status /home/pi/can-utils/cansend slcan0 6A2#3100FA01760000
Summer mode? /home/pi/can-utils/cansend slcan0 6A2#3100FA033B0000
Program setting /home/pi/can-utils/cansend slcan0 6A2#3100FA01120000
Return flow temperature /home/pi/can-utils/cansend slcan0 6A2#3100FA00160000
Boiler temperature (to be) /home/pi/can-utils/cansend slcan0 6A2#3100FA00030000
Boiler temperature (current) /home/pi/can-utils/cansend slcan0 6A2#3100FA000E0000
Power usage heating kWh (sum) /home/pi/can-utils/cansend slcan0 6A2#3100FA09200000
Power usage heating MWh (sum) /home/pi/can-utils/cansend slcan0 6A2#3100FA09210000
Power usage heating /home/pi/can-utils/cansend slcan0 6A2#3100FA02CC0000
Power usage heating kWh (today) /home/pi/can-utils/cansend slcan0 6A2#3100FA091F0000
Power usage heating Wh (today) /home/pi/can-utils/cansend slcan0 6A2#3100FA091E0000
Power usage Boiler /home/pi/can-utils/cansend slcan0 6A2#3100FA02CE0000
Power usage warm water kWh (sum) /home/pi/can-utils/cansend slcan0 6A2#3100FA091C0000
Power usage warm water MWh (sum) /home/pi/can-utils/cansend slcan0 6A2#3100FA091D0000
Power usage warm water kWh (today) /home/pi/can-utils/cansend slcan0 6A2#3100FA091B0000
Power usage warm water Wh (today) /home/pi/can-utils/cansend slcan0 6A2#3100FA091A0000
Excavator temperature /home/pi/can-utils/cansend slcan0 6A2#3100FA00140000
Volume flow /home/pi/can-utils/cansend slcan0 6A2#3100FA01DA0000
Flow temperature /home/pi/can-utils/cansend slcan0 6A2#3100FA000F0000
Heat recovery heating kWh (sum) /home/pi/can-utils/cansend slcan0 6A2#3100FA03B10000
Heat recovery heating kWh (today) /home/pi/can-utils/cansend slcan0 6A2#3100FA03B00000
Heat recovery heating MWh (sum) /home/pi/can-utils/cansend slcan0 6A2#3100FA03B60000
Heat recovery heating Wh (today) /home/pi/can-utils/cansend slcan0 6A2#3100FA03AF0000
Room temperature /home/pi/can-utils/cansend slcan0 6A2#3100FA00110000

Bonus: Set the room temperature of the heating

Comming soon…

The heating has a value to read or write the room temperature. By default, if you don’t have an additional console somewhere in the living room, there is the value of 19°C that is used by the heating to calculate the heating level. Using any source that is attached to OpenHab, we can set this value.

In the following example, I use the temperature value my KNX switch in the living room that reports to OpenHab. I am using this value to set the room temperature in the heating using a rule, that is triggered everytime the KNX switch temperature changes. You can use any temperature source you like (i.e. ZigBee devices, weather stations, …).

Right now I am stuck. I have setup everything and writing the value to the heating but it is overwritten after some minutes with 19°C. I haven’t figured out why this is happening and how to change this behaviour. I will report as soon as I have a solution.

Good to know…

I had the problem, that the CAN BUS Id 6A1 is my contol unit (the display) at the heating. This was configured to be terminal ID 4. As long this was the case I had the problem, that this control unit wasn’t working. Doesn’t matter if I use 6A2 or 6A1 for communicating with the Bus. After I changed the terminal ID to 3, the CAN BUS Id of the control Unit also changed to 6A0. After that, everything was working.

References

USBtin setup: https://www.fischl.de/usbtin/linux_can_socketcan/
Elster definitions: http://juerg5524.ch/data/ElsterTable.inc
More IDs: https://elkement.blog/2016/08/24/hacking-my-heat-pump-part-2-logging-energy-values/