MODBUS and System air

Gunnar please copy your things file with binding v2 and item to see difference with new binding

Sorry, I’ve been a bit busy the last weeks. The 2x modbus configuration for a complete villavent setup is huge. I used hours to set up mine even when I knew how it was done. There is no way I’ll cover all of it, but here is a partial fan config.

First a modbus serial slave:

Then a poller for the register range you need, here 100 through 138 (start 100, length 38):

And lastly you need a data thing, here for register 111 (actually register 112 in the villavent docs. The config is 0 index):

Read this thread and the modbus pdf from villavent to find the registers you want to read.

Gunnar thx, I will try. Copy code from .items for Villavent and .sitemap and rules

So I am trying to do the same as you Gunnar, migrating to the modbus 2.5 binding.

However I can not get it to work.
I deleted the old modbus.cfg
I removed all {.*} in the villaVent.items file
I followed your description , but added a final step where I linked the dataThing Number channel to the Number VillaventFan "Fan speed" <fan> (Villavent, Persist)

  1. How do I know which USB port to select?
  2. To control Fan speed how come in the data thing you only specify read?
  3. My fan speed jumps around 3000 as a value, am I reading the wrong registry?
  4. Why do you poll so often?

Here is my error:

2019-05-23 23:55:39.819 [ERROR] [core.karaf.internal.FeatureInstaller] - Failed installing 'openhab-binding-modbus1'

2019-05-23 23:13:46.446 [vent.ItemStateChangedEvent] - VillaventFan changed from 3180 to 3300

2019-05-23 23:13:47.643 [vent.ItemStateChangedEvent] - VillaventFan changed from 3300 to 3180

2019-05-23 23:13:48.356 [ome.event.ItemCommandEvent] - Item 'VillaventFan' received command 1

==> /var/log/openhab2/openhab.log <==

2019-05-23 23:13:48.365 [WARN ] [ernal.handler.ModbusDataThingHandler] - Thing modbus:data:systemAirRpm 'systemAirFanSpeed': not processing command 1 since writeStart is missing and transformation output is not a JSON

What’s not working, you’re getting fan rpm?

Register 112 (address 111) is not a speed control, its sensing fan RPM
See Systemair pdf like @gskjold says.
The off-low-high type control is register 101 (address 100)

Why not, it’s free?
Poll as often or as little as you wish, Modbus polls are commonly once per second but it’s only a starting point.

That one is easy enough. You’ve got one of the write parameters set in your channel somewhere, so that the binding doesn’t think its read-only, but not all. Then you’ve sent this read-only speed sensor a command.


The binding will let you do something clever here, if you want to play.
First set autoupdate off for your fan Number Item. This to break the linkage between command and Item state.
Link the Item to the read-polled channel for RPM in register 112, you’ve done that part already.
Now modify that channel to include the write address and type for register 101, the actual speed control. The binding will let you read and write to different registers in one channel.
Now you have an Item whose state will be fan RPM but you can send it commands 0-4 to control speed range.

Looks like you found the usb port you need if you get a 3000rpm read from that register. It is correct as @rossko57 is writing. 111 and 112 is read registers for extract/supply fan rpm sensor. And 500ms poll is just a choice.

Thanks, was a bit late last night and i referred to the wrong register :wink:

However this morning I changed it to 101 to be able to control the fan, however I can not get to work, do you mind sharing how you set off,low,normal,max,auto ?

2019-05-24 08:05:40.652 [ERROR] [core.karaf.internal.FeatureInstaller] - Failed installing 'openhab-binding-modbus1'

==> /var/log/openhab2/events.log <==

2019-05-24 08:05:41.082 [ome.event.ItemCommandEvent] - Item 'VillaventFan' received command 3

2019-05-24 08:05:41.092 [nt.ItemStatePredictedEvent] - VillaventFan predicted to become 3

2019-05-24 08:05:41.114 [vent.ItemStateChangedEvent] - VillaventFan changed from 30 to 3

2019-05-24 08:05:41.124 [vent.ItemStateChangedEvent] - VillaventFan changed from 3 to 30

and how come this pop up all the time:

2019-05-24 08:05:40.652 [ERROR] [core.karaf.internal.FeatureInstaller] - Failed installing 'openhab-binding-modbus1'

I am running on rpi and to decrease the load I was thinking about using 50000ms poll , its noit like temperature or anything changes so quick


You are remembering that Systemair register number 101 gets addressed in Modbus channels as 100 ??

You’ve still got autoupdate enabled on this Item.
That usually only confuses things when you read-poll with Modbus.
Although if you do opt for the slow read-poll, you might choose to leave autoupdate on for a better response at your UI

You’ve got some reference to modbus 1 binding in your addons.cfg or folder somewhere. Clear it out, it cannot coexist with modbus 2

Thanks for the feedback

Its always -1 for some reason, easy to FORGET!!

Here is my config:


how do you switch that off?

Its seems like my dongle went offline for some reason
 I guess symlink are needed

Status: OFFLINE - COMMUNICATION_ERROR Error (ModbusConnectionException) with read. Request: ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@d485c4[slaveId=1,functionCode=READ_MULTIPLE_REGISTERS,start=100,length=38,maxTries=3]. Description: ModbusConnectionException(Error connecting to endpoint=ModbusSerialSlaveEndpoint@b60de2[portName=/dev/ttyUSB1]). Message: Error connecting to endpoint ModbusSerialSlaveEndpoint@b60de2[portName=/dev/ttyUSB1]

When they invented Modbus in the 1970s, they decided Register Number 1 would be found at address 0. Ever since then, there has been confusion about whether people are talking about register numbers or register addresses.
Systemair talk register numbers.
openHAB talk register addresses.

It’s a property of the Item, I think there’s a box in PaperUI
If you are going to do slow polls, you could leave it enabled and you will get a faster response to clicking at your UI.

With the new binding we need two things for every item, a poller and a data thing. Isn’t that a bit overhead?

I will have a closer look this evening when I get home, kinda hard to debug remotely


A poller can read a block of many registers. Last one that you showed us of yours read 38, for example.

You need a data thing to describe each register in that block and how to interpret it - 16/32 bit, signed etc. - if you want to create a channel. You need a channel to link Items with bindings because that’s how OH2 works.

A poller can have many data things. You do not need to have a data thing for every register in the polled block, unless you want to use them in a channel.

Sorry, but Modbus is quite new for an aerospace engineer so apologize for the newbie questions.
So we can use the poller and read out all from 101 to 602 at bulk from the system air register and then create a data thing for each register?

Not quite. A limitation of modbus protocol is that you can only read 120 or so registers in one poll. 1970s technology, remember.
You’d need to make several pollers to read 500 registers in chunks.
If you worry about using resource with fast polling, you’d probably want to be a bit more selective though.
It is efficient to have as few pollers as possible, even when parts of the block are unused. But pointless to fetch say 400-499 if you only want register 425.

Beware that some modbus devices allow you to read a block including registers undefined by the manufacturer. Some will not, and reject the attempt.

Part of the fiddly configuring is to allow you the flexibility to make choices about these things.

  • Registers for fan control 38 Registers 101-138 Poll 500ms
  • Registers for heater control 21 registers 201-221 Poll 50000ms
  • Registers for the rotor 1 register 351 Poll 50000ms
  • Registers for system parameters 57 registers 501-557 Poll 50000ms
  • Registers for the filter 2 Registers 601-602 Poll 50000ms

Is what you will recommend then.
However most user probably only need first one on the list

I don’t recommend anything, it’s up to you what suits.

It all works fine now, its just the bug with old modbus binding :slight_smile:

Hi Kim,

can you copy code with new modbus binding for things, items and sitemap??

Please


So I finally got around to fiddle with the HVAC again, I am going to make a tutorial of it, but here is my ventilation rule in case someone can use it as inspiration:


import java.math.BigDecimal
import java.util.Calendar

rule "Adjust Fan"
when
    Item Bathroom_Scene changed or 
    Item Livingroom_Scene changed or 
    Item Group_CO2_Max changed or
    Item vTimeOfDay changed or 
    Item Presence_Home changed
then
    logInfo("Notification", "Fan rule")

    //Turn off vent at night
    if (vTimeOfDay.state.toString.contains("NIGHT") || Presence_Home.state==OFF){
        logInfo("Notification", "Fan Off")
        if (VillaventFan.state as Number !=0) { VillaventFan.sendCommand(0)}
        
    }

    // Turn fan on max, when cooking and going to the toilet....
    if ( ((Bathroom_Scene.state as Number > 0 ) || 
         (Livingroom_Scene.state as Number ==7) || 
         (Group_CO2_Max.state as Number > 1000)) && 
         (vTimeOfDay.state.toString.contains("NIGHT")==false || Group_CO2_Max.state as Number > 2500) ){
        logInfo("Notification", "Fan Max")
        if (VillaventFan.state as Number !=3) { VillaventFan.sendCommand(3)}
    }
    
    // Turn fan to low
    else{ 
        if (Livingroom_Scene.state as Number != 7){
            logInfo("Notification", "Fan low")
            createTimer(now.plusSeconds(300))[|
                if (VillaventFan.state as Number !=1) { VillaventFan.sendCommand(1)}
            ]
        }
    }

    //Medium CO2
    if (Group_CO2_Max.state as Number > 1500){
       
        if (vTimeOfDay.state.toString.contains("NIGHT")) {
            logInfo("Notification", "Fan low")
            if (VillaventFan.state as Number !=1) { VillaventFan.sendCommand(1)} 
        }
        else {
            logInfo("Notification", "Fan medium")
            if (VillaventFan.state as Number !=2) { VillaventFan.sendCommand(2)}
        }
        
    }
    //High CO2 level
    if (Group_CO2_Max.state as Number > 2000){
        if (vTimeOfDay.state.toString.contains("NIGHT")) {
            logInfo("Notification", "Fan medium")
            if (VillaventFan.state as Number !=2) { VillaventFan.sendCommand(2)} 
        }
        else{
            logInfo("Notification", "Fan max")
            if (VillaventFan.state as Number !=3) { VillaventFan.sendCommand(3)} 
        }
    }



    //Humidity
end



I am considering also control the system air depending of humidity, how does @gskjold implement his rules?

Maybe someone can help me rerwrite it to a switch statement instead of so many nested if sentences


@skatun I don’t have any rules based on humidity. This is something that is a bit hard to deal with properly, because you have to know the outdoor humidity as well and recalculate based on the temperature on the supply air to know if you are actually supplying air with less humidity and change based on that. I don’t think it is worth it to be honest.

Right now my ruleset switch to low when I am away. When home it is at normal for both day and night.
Sets to high if firealarm goes off. Also I have a rule switching off the heater if the extract temperature exceeds the setpoint or the intake temperature if higher than set temperature-4. Then it switch the heater back on if extract temp is below setpoint-2 and intake-8.

Not sure if this have been mentioned before, but switching the fan off over longer time is highly discouraged because of risk of condensation. You don’t save much more than 1 NOK by switching it off at night anyway. And if noise is an issue, setting it to low is enough in my experience.