[Solved] Modbus Binding 1.12 TCP Stiebel-Eltron LWZ403 ISG Web

Dear all,

I am trying to connect my Stiebel-Eltron LWZ403 via Modbus TCP (ISG Web) to control the venting system and read some base parameters. I got stuck and would be happy to read from Modbus at all before attempting to write. Any help and guidance is highly welcome!

I am using OpenHab2 (2.3.0-1) and Modbus Binding 1.12.0

Here is my modbus config

Here is the error message I am getting
2018-07-31 23:49:03.219 [INFO ] [b.core.service.AbstractActiveService] - Modbus Polling Service has been started
2018-07-31 23:49:03.284 [ERROR] [.binding.modbus.internal.ModbusSlave] - ModbusSlave (lwz1): Error getting modbus data for request net.wimpi.modbus.msg.ReadMultipleRegistersRequest@2c90e7f9. Error: Error Code = 2. Endpoint ModbusTCPSlaveEndpoint@528213fb[address=,port=502]. Connection: TCPMasterConnection@e88c15d[socket=Socket[addr=/,port=502,localport=40424]]
2018-07-31 23:49:13.295 [ERROR] [.binding.modbus.internal.ModbusSlave] - ModbusSlave (lwz1): Error getting modbus data for request net.wimpi.modbus.msg.ReadMultipleRegistersRequest@75cc2aaf. Error: Error Code = 2. Endpoint ModbusTCPSlaveEndpoint@528213fb[address=,port=502]. Connection: TCPMasterConnection@1cd83edb[socket=Socket[addr=/,port=502,localport=40464]]

The documentation of Stiebel’s implementation and registers can be found here: https://www.stiebel-eltron.de/content/dam/ste/cdbassets/current/bedienungs-_u_installationsanleitungen/ISG_Modbus_Stiebel__f6023bb0-ab00-11e6-b2bc-005056a95add.pdf


Ok, I could fix this one problem on my own reading the SimplyModbus docu and looking for error code 2: http://www.simplymodbus.ca/exceptions.htm

Adjusting the holding registers marked the trick… Will keep you posted. But for now I can read data from Stiebel Eltron ISG via ModbusTCP :slight_smile:


While I can read values, I am currently struggling to write values. I am trying to change the venting level (0 = off to 3 = max). If I use a simple switch w/o config I can set venting to 1 = ON or 0 = OFF, however so far no success in setting any higher level than 1.

Current error message is

[rest.core.internal.item.ItemResource] - Received HTTP POST request at ‘items/LuefterTag’ with an invalid status value ‘2’.

Will continue with trial & error and post any results. If somebody does have an idea or knows how to do this, I would be greatful :slight_smile:


Ok, I got it working with a little tweaking: following the OpenHAB Modbus Doc, I rather quickly managed to write data to StiebelEltron ISG using the ON/OFF trigger which would set the venting system to level 0 (Off) or level 1 (On).

However, the venting system has a total of 4 different states: 0-Off, 1-Low, 2-Med, 3-High

Playing with the write item confit leveraging transformation, I could as well set other values than 0 and 1

>[slaveName:writeIndex:trigger=TRIGGER, transformation=TRANSFORMATION, valueType=VALUETYPE]

So, as a workaround I simply defined a “proxy” item that I added to my Sitemap as a switch with key mapping and 4 items, each linked to Modbus slave&register and with transformation setting the according values (0-3) when trigger is ON for my 4 states in the transformation. Finally adding some simple rules on state change “ITEM received update” to toggle the correct item and then writing the correct value to Modbus.

Once I have a bit more time, I will check if I get a leaner config doing the same but for now: my use case is ready and I can steer air ventilation depending on outside temperature! Gives me a cheap air conditioning in the summer (as long as it is cooling down during the night).

Cheers & thank you to the OpenHAB developers enabling me to do this with OH2 and the Modbus Binding! You rock!


1 Like

Perhaps you’re being misled by the OH Item type name ‘Switch’. So far as OH is concerned, such a type can only be ON or OFF.
If you want something to take on states 0 to 3, that would be a Number type Item. The Modbus binding will find it quite natural to link a Number to a register for writing.

Your biggest challenge will be the best way to present the choices of number in your UI !

This looks helpful - note that the sitemap ‘Switch’ form presentation is being used with a Number Item, important distinction

Hi Rossko57

thank you for the eye-opener. That actually did the trick and I can get rid of all my workaround :slight_smile:

Regarding presentation in UI all ways are working now: Slider or Switch with Key-Mapping,… Really nice.

Here is my config for the item:
Number Luefter “Luefter Tag” (ALL) {modbus=">[lwz1:1]"}

Can you Post Your current Version of
Things and items Files for the stiebel modbus?

Hi Shorty707

sure here we go:


# sets refresh interval to Modbus polling service.
# Value in milliseconds (optional, defaults to 200)

## Example of Modbus TCP slave

# Connection parameters to Modbus TCP server ("slave"), values separated by colon (:)
# - host or ip of the modbus server ("slave"), mandatory
# - port, optional, default 502
# - interTransactionDelayMillis, optional, in milliseconds, default 60
# - reconnectAfterMillis, optional, in milliseconds, default 0
# - interConnectDelayMillis, optional, in milliseconds, default 0
# - connectMaxTries, optional, default 3
# - connectTimeout, optional, in milliseconds, default 0 (=infinite or OS default)
# As a general rule, usually only host needs to be specified. Parameters other than host
# and port should be overridden only in cases when extreme performance is required, or when there are
# errors with the default parameter values.
# See wiki for more details.
#    (slave name)      (host or IP)
#    |                 |             (port)
#    |                 |             |   (interTransactionDelayMillis, in milliseconds)
#    |                 |             |   |  (reconnectAfterMillis, in milliseconds)
#    |                 |             |   |  | (interConnectDelayMillis, in milliseconds)
#    |                 |             |   |  | | (connectMaxTries)
#    |                 |             |   |  | | | (connectTimeout)
#    |                 |             |   |  | | | |

# Lüfter (lesen/schreiben) | Venting (read-write)

# Sonstige Heizungswerten (lesen) | Other parameters (read)

# The data type, can be "coil" "discrete" "holding" "input". See wiki for more details.

# The slave id (optional, defaults to '1')

# The slave start address (optional, defaults to '0')

# The number of data item to read
# (optional, defaults to '0' - but set it to something meaningful)

# Value type, required for combined registers (details: http://www.simplymodbus.ca/FAQ.htm#Types)
# Can be "bit", "int8", "uint8", "int16", "uint16", "int32", "uint32", "float32"
# (optional, defaults to 'uint16')

# For other slave parameters, consult the wiki.

## Example of Modbus Serial slave

# Connection parameters to Modbus Serial server ("slave"), values separated by colon (:)
# - serial port, mandatory. Example: /dev/ttyS0 (linux) or COM3 (windows)
# - baudRate, optional, default 9600
# - dataBits, optional, in milliseconds, default 8
# - parity, optional, default none
# - stopBits, optional, default 1
# - encoding, optional, default rtu
# - interTransactionDelayMillis, optional, in milliseconds, default 35
# - receiveTimeoutMillis, optional, in milliseconds, default 1500
# - flowControlIn, optional, default none
# - flowControlOut, optional, default none
# As a general rule, usually one needs to specify serial port, baudRate, dataBits, parity, stopBits, and encoding. Other parameters
# should be overriden only in cases when extreme performance is required, or when there are
# errors with the default parameter values.
# See wiki for more details.
#       (slave name)      (host or IP)
#       |                 |          (baud)
#       |                 |          |     (dataBits)
#       |                 |          |     | (parity)
#       |                 |          |     | |    (stopBits)
#       |                 |          |     | |    | (encoding)
#       |                 |          |     | |    | |   (interTransactionDelayMillis)
#       |                 |          |     | |    | |   |  (receiveTimeoutMillis)
#       |                 |          |     | |    | |   |  |    (flowControlIn)
#       |                 |          |     | |    | |   |  |    |    (flowControlOut)
#       |                 |          |     | |    | |   |  |    |    |
#       |                 |          |     | |    | |   |  |    |    |

# The data type, can be "coil" "discrete" "holding" "input". See wiki for more details.

# The slave id (optional, defaults to '1')

# The slave start address (optional, defaults to '0')

# The number of data item to read
# (optional, defaults to '0' - but set it to something meaningful)

# Value type, required for combined registers (details: http://www.simplymodbus.ca/FAQ.htm#Types)
# Can be "bit", "int8", "uint8", "int16", "uint16", "int32", "uint32", "float32"
# (optional, defaults to 'uint16')

# For other slave parameters, consult the wiki.


this is not yet my final setup and I clearly can/should do some clean-up. Yet, it is working :slight_smile:

Number Tag "Luefter-Tag [%s]" {modbus="lwz1:<0:>0"}
Number Nacht "Luefter-Nacht [%s]" {modbus="lwz1:<1:>1"}

// Proxy Items
Number ProxyTag "Luefter-Tag (proxy)"
Number ProxyNacht "Luefter-Nacht (proxy)"
Number ProxyAussentemp "Aussentemperatur (proxy)"

// Luefterstufe Tag
Switch LTag1 "Luefter Tag 1" (ALL) {modbus=">[lwz1:0:trigger=ON,transformation=1],>[lwz1:0:trigger=OFF,transformation=0]"}
Switch LTag2 "Luefter Tag 2" (ALL) {modbus=">[lwz1:0:trigger=ON,transformation=2],>[lwz1:0:trigger=OFF,transformation=0]"}
Switch LTag3 "Luefter Tag 3" (ALL) {modbus=">[lwz1:0:trigger=ON,transformation=3],>[lwz1:0:trigger=OFF,transformation=0]"}
Switch LTag0 "Luefter Tag 0" (ALL) {modbus=">[lwz1:0:trigger=ON,transformation=0],>[lwz1:0:trigger=OFF,transformation=0]"}

// Luefterstufe Nacht
Switch LNacht1 "Luefter Nacht 1" (ALL) {modbus=">[lwz1:1:trigger=ON,transformation=1],>[lwz1:0:trigger=OFF,transformation=0]"}
Switch LNacht2 "Luefter Nacht 2" (ALL) {modbus=">[lwz1:1:trigger=ON,transformation=2],>[lwz1:0:trigger=OFF,transformation=0]"}
Switch LNacht3 "Luefter Nacht 3" (ALL) {modbus=">[lwz1:1:trigger=ON,transformation=3],>[lwz1:0:trigger=OFF,transformation=0]"}
Switch LNacht0 "Luefter Nacht 0" (ALL) {modbus=">[lwz1:1:trigger=ON,transformation=0],>[lwz1:0:trigger=OFF,transformation=0]"}

// Luefter-Test
Number Luefter "Luefter Nacht" (ALL) {modbus=">[lwz1:1],<[lwz1:1]"}

// Heizungswerte
Number Aussentemperatur "Aussentemperatur [%s]" {modbus="lwz2:6"}
Number WWISTTEMP "WW-IST Temperatur [%.2f]" {modbus="lwz2:15"}
Number WWSOLLTEMP "WW-SOLL Temperature [%.1f]" {modbus="lwz2:16"}
Number KOLLEKTORTEMP "KOLLEKTORTEMP [%.1f]" {modbus="lwz2:26"}
Number ABLUFTFEUCHTE "ABLUFTFEUCHTE [%s]" (ALL) {modbus="lwz2:21"}


sitemap lwz label="LWZ403SOL"
        Frame label="LWZ" {
                Switch item=ProxyTag mappings=[0="OFF", 1="MIN", 2="MED", 3="MAX"]
                Switch item=ProxyNacht mappings=[0="OFF", 1="MIN", 2="MED", 3="MAX"]

                Setpoint item=Luefter  minValue=0 maxValue=3 step=1

                Text item=Tag
                Text item=Nacht
                Text item=Aussentemperatur
                //Text item=ProxyAussentemp
                Text item=WWISTTEMP
                Text item=WWSOLLTEMP
                Text item=KOLLEKTORTEMP
                Text item=ABLUFTFEUCHTE

                //Text item=Elektr-NE-Heizen
                //Text item= Elektr-NE-WW

Again, this is work in progress. I am currently trying to read if the electrical heating is on and on what level or not to send me notifications, yet I did not get this to work. Another thing is I want to read warm-water temp and write the data into influxdb timeseries.

Let me know if you make additional progress, it is unfortunately a bit cumersome.

As attachment the Stiebel-Eltron docu that my values (register addresses) are based on:

ISG Modbus_Stiebel_Bedienungsanleitung.pdf (965.8 KB)


Just visited the Modbus Binding documentation and was a bit surprised to see all new configuration (came witih modbus2 binding)… I am still ony Modbus1 and luckily it is still working. Yet, I tried out the new one on a OpenHAB docker container to test but no luck so far…

Does anyone already have experience? I really love OpenHab but the frequent and surprising changes to bindings and stuff make it a bit difficult to follow (if you are not having time to do so regularly) :slight_smile:

Cannot even get Modbus2 installed out of PaperUI in OH v2.3.0

The current binding version is 2, for use with openHAB2.

The v1 binding you’ve been using is likely to continue to work throughout the life of openHAB2, although it’s unlikely any fixes or improvements will now be made to v1 Modbus binding.

openHAB2 treats bindings in a rather different way, introducing Things and channels. In general, this brings flexibility in terms of auto discovery and suchlike. That’s not much direct benefit to Modbus users of course.

Nevertheless, a substantial effort was put in to create a OH2 compatible Modbus binding, incorporating quite a few lessons from v1, to make it “fit” and be consistent with the new native Thing/channel mode of OH2.

It’s the one and only substantial change made to the Modbus binding in six years.

Configuring v2 Modbus remains a manual editing job for now, but with the details going into xxx.things files alongside xxx.items definitions. No longer any modbus.cfg file.

No-one will make you use OH2, or v2 Modbus. Other circumstances might bring you a need for new features.

If you do want to start out with Modbus v2, it is best to start with OH 2.4 onwards.

Thanks, just found this info searching the forum & web. Was confused as the docu is already udated (btw. great to get new version, really happy - if the migration form release to release would be easier, even cooler :slight_smile:

Cheers and will give 2.4 a try in my container


1 Like

I just started an OpenHAB installation with one major goal: not have to run into the cellar anymore to change the fan speed :wink:
So I‘m very happy to see your on the same thing and you manage to solve it! Unfortunately I‘m on OH 2 – but hopefully it will work, too.
Did you use a serial to USB connection? Or is OH running on a device with a nativ serial interface?

Hello Henning,

I use the Stiebel Eltron Internet Service Gateway as it offers the ModBus protocol as well as the Service Portal that allows you to control the whole device. It is not inexpensive (some 400 EUR if I recall). It might work via serial/usb connection, too but guess not via ModBus Protocol then.


Ah, I see. Yes, the Service Gateway seems a little bit too expensive – as it is mainly an HTTP interface to view some statistics.

A year or so ago, I managed to read data via serial2usb interface on FHEM. That’s why I hope to be able to not only read but also send data. It really unbelievable that in year 2018 there is no dynamic ventilation in such an expensive heatpump like Stiebel Eltron. The whole industry lacks digitalisation.

Hopefully I will be able to have such a simple ruleset like “if netatmo alerts to high co2 than set ventilation one step higher.



Your main challenge is you need to integrate into OH. You could certainly use the Serial2USB - but how would you connect it into OH (using which binding) and you need to identify the commands to send over serial to do the same.

ISG with Modbus is quite powerful (still overpriced I agree). My usecase is similar for summer: turn venting down if Netatmo outside temp >= 28 C and turn venting up when outside cooler than 25 C (or whatever you like).


i also use ISG and Modbus for non tinker solution

however the only available binding is even for serial connections…
so @Henning_Emmrich should be good to go

Hi Jens,
Did you manage to read/write values via modbus v2 and OH2 ?

Thanks for your great work :+1:

Hi Stefan, I just started a new topic on this here

Did not get it to work, YET :slight_smile:

1 Like