MODBUS and System air

modbus
Tags: #<Tag:0x00007f014c9e4d10>

(Gunnar Skjold) #61

I thought I’d update here with my current configuration including modbus cfg, items, rules and sitemap. Maybe someone can make use of it and also come up with some other ideas I haven’t thought of :slight_smile:

modbus.cfg:

serial.vvfan.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvfan.id=1
serial.vvfan.start=100
serial.vvfan.length=38
serial.vvfan.type=holding
serial.vvfan.valuetype=int16

serial.vvhc.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvhc.id=1
serial.vvhc.start=200
serial.vvhc.length=21
serial.vvhc.type=holding
serial.vvhc.valuetype=int16

serial.vvrot.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvrot.id=1
serial.vvrot.start=350
serial.vvrot.length=2
serial.vvrot.type=holding
serial.vvrot.valuetype=int16

serial.vvsys.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvsys.id=1
serial.vvsys.start=500
serial.vvsys.length=7
serial.vvsys.type=holding
serial.vvsys.valuetype=int16

serial.vvnvm.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvnvm.id=1
serial.vvnvm.start=548
serial.vvnvm.length=1
serial.vvnvm.type=holding
serial.vvnvm.valuetype=int16

serial.vvclock.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvclock.id=1
serial.vvclock.start=550
serial.vvclock.length=7
serial.vvclock.type=holding
serial.vvclock.valuetype=int16

serial.vvfilter.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvfilter.id=1
serial.vvfilter.start=600
serial.vvfilter.length=2
serial.vvfilter.type=holding
serial.vvfilter.valuetype=int16

serial.vvdefr.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvdefr.id=1
serial.vvdefr.start=670
serial.vvdefr.length=2
serial.vvdefr.type=holding
serial.vvdefr.valuetype=int16

serial.vvdig.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvdig.id=1
serial.vvdig.start=700
serial.vvdig.length=9
serial.vvdig.type=holding
serial.vvdig.valuetype=int16

serial.vvtsf.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvtsf.id=1
serial.vvtsf.start=3488
serial.vvtsf.length=5
serial.vvtsf.type=coil
serial.vvtsf.valuetype=bit

serial.vvdi.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvdi.id=1
serial.vvdi.start=11200
serial.vvdi.length=7
serial.vvdi.type=coil
serial.vvdi.valuetype=bit

serial.vvpcu.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vvpcu.id=1
serial.vvpcu.start=12000
serial.vvpcu.length=3
serial.vvpcu.type=coil
serial.vvpcu.valuetype=bit

serial.vval.connection=/dev/ttyUSB0:19200:8:none:1:rtu:35:5000
serial.vval.id=1
serial.vval.start=12800
serial.vval.length=9
serial.vval.type=coil
serial.vval.valuetype=bit

items:

Group Villavent

Group VillaventTemperatureGroup
Number VillaventTemperatureGroupGraph

Number VillaventNvm "Store NVM" (Villavent) { modbus="vvnvm:0" }

Number VillaventFan "Fan speed" <fan> (Villavent, Persist) { modbus="vvfan:0" }
Number VillaventSupplyFanRpm "Supply fan RPM [%d]" <fan> (Villavent, Persist) { modbus="vvfan:10" }
Number VillaventSupplyFanGraph (PersistAndRestore)
Number VillaventExtractFanRpm "Extract fan RPM [%d]" <fan> (Villavent, Persist) { modbus="vvfan:11" }
Number VillaventExtractFanGraph (PersistAndRestore)

Number VillaventFrostProtection "Frost protection level [%d]" <temperature> (Villavent, Persist) { modbus="vvhc:5" }
Number VillaventTempLvl "Temperature level [%d]" <heating> (Villavent, Persist) { modbus="vvhc:6" }
Number VillaventHeatSetpoint "Set temperature" <heating> (Villavent, Persist) { modbus="vvhc:7" }

Number VillaventSupplyAirTemp "Supply air temperature [%.1f °C]" <temperature> (Villavent, VillaventTemperatureGroup, Temperature)
Number VillaventSupplyAirTemp_in "Supply air temperature [%d]" (Villavent) { modbus="vvhc:13" }
Number VillaventSupplyAirGraph (PersistAndRestore)

Number VillaventExtractAirTemp "Extract air temperature [%.1f °C]" <temperature> (Villavent, VillaventTemperatureGroup, Temperature)
Number VillaventExtractAirTemp_in "Extract air temperature [%d]" (Villavent) { modbus="vvhc:14" }
Number VillaventExtractAirGraph (PersistAndRestore)

Number VillaventExhaustAirTemp "Exhaust air temperature [%.1f °C]" <temperature> (Villavent)
Number VillaventExhaustAirTemp_in "Exhaust air temperature [%d]" (Villavent) { modbus="vvhc:15" }
Number VillaventExhaustAirGraph (PersistAndRestore)

Number VillaventProtectAirTemp "Overheating/Frosprotection temperature [%.1f °C]" <temperature> (Villavent, VillaventTemperatureGroup, Temperature)
Number VillaventProtectAirTemp_in "Overheating/Frosprotection temperature [%d]" (Villavent) { modbus="vvhc:16" }
Number VillaventProtectAirGraph (PersistAndRestore)

Number VillaventIntakeAirTemp "Intake air temperature [%.1f °C]" <temperature> (Villavent, VillaventTemperatureGroup, Temperature)
Number VillaventIntakeAirTemp_in "Intake air temperature [%d]" (Villavent) { modbus="vvhc:17" }
Number VillaventIntakeAirGraph (PersistAndRestore)

Number VillaventHeaterType "Heater type" <smoke> (Villavent, Persist) { modbus="vvhc:0" }
Number VillaventCoolerType "Cooler type" <climate> (Villavent, Persist) { modbus="vvhc:1" }
Number VillaventPreHeaterType "Pre-heater type" <smoke> (Villavent, Persist) { modbus="vvhc:19" }

Number VillaventFlowUnits "Fan speed flow unit" <pressure> (Villavent, Persist) { modbus="vvfan:7" }
Number VillaventFanControlType "Fan control" <flow> (Villavent, Persist) { modbus="vvfan:37" }
Number VillaventAllowFanStop "Control panel fan stop allowed" <switch> (Villavent, Persist) { modbus="vvfan:13" }

Number VillaventSupplyFanSystemCurve "Supply fan system curve [%d]" <line> (Villavent, Persist) { modbus="vvfan:35" }
Number VillaventSupplyFanSpeedLow "Supply fan speed for low [%d]" <fan> (Villavent, Persist) { modbus="vvfan:1" }
Number VillaventSupplyFanSpeedNom "Supply fan speed for nominal [%d]" <fan> (Villavent, Persist) { modbus="vvfan:3" }
Number VillaventSupplyFanSpeedHigh "Supply fan speed for high [%d]" <fan> (Villavent, Persist) { modbus="vvfan:5" }

Number VillaventExtractFanSystemCurve "Extract fan system curve [%d]" <line> (Villavent, Persist) { modbus="vvfan:36" }
Number VillaventExtractFanSpeedLow "Extract fan speed for low [%d]" <fan> (Villavent, Persist) { modbus="vvfan:2" }
Number VillaventExtractFanSpeedNom "Extract fan speed for nominal [%d]" <fan> (Villavent, Persist) { modbus="vvfan:4" }
Number VillaventExtractFanSpeedHigh "Extract fan speed for high [%d]" <fan> (Villavent, Persist) { modbus="vvfan:5" }

Number VillaventRotorState "Rotor state [MAP(vvrotstate.map):%s]" <sun> (Villavent, Persist) { modbus="vvrot:0" }
Switch VillaventRotorRelayActive "Rotor relay [%s]" <switch> (Villavent, VillaventTemperatureGroup, Persist) { modbus="vvrot:1" }

Number VillaventDefrostState "Defrosting state [MAP(vvdefrstate.map):%s]" <rain> (Villavent, Persist) { modbus="vvdefr:0" }
Number VillaventDefrostMode "Defrosting mode [%d]" <qualityofservice> (Villavent, Persist) { modbus="vvdefr:1" }

Number VillaventFilterPeriod "Filter replace time [%d months]" <calendar> (Villavent, Persist) { modbus="vvfilter:0" }
Number VillaventFilterDays "Filter days since last replacement [%d days]" <time> (Villavent, Persist) { modbus="vvfilter:1" }

Number VillaventSystemType "System type [MAP(vvsystype.map):%s]" <contact> (Villavent, Persist) { modbus="vvsys:0" }

String VillaventProgVersion "Program version [%s]" <shield> (Villavent, Persist)
Number VillaventProgVH (Villavent) { modbus="vvsys:1" }
Number VillaventProgVM (Villavent) { modbus="vvsys:2" }
Number VillaventProgVL (Villavent) { modbus="vvsys:3" }
String VillaventBootVersion "Boot version [%s]" <shield> (Villavent, Persist)
Number VillaventBootVH (Villavent) { modbus="vvsys:4" }
Number VillaventBootVM (Villavent) { modbus="vvsys:5" }
Number VillaventBootVL (Villavent) { modbus="vvsys:6" }

DateTime VillaventClock "Clock [%s]" <time> (Villavent)
Number VillaventClockS "Clock seconds [%d]" (Villavent) { modbus="vvclock:0" }
Number VillaventClockM "Clock minutes [%d]" (Villavent) { modbus="vvclock:1" }
Number VillaventClockH "Clock hours [%d]" (Villavent) { modbus="vvclock:2" }
Number VillaventClockD "Clock day of month [%d]" (Villavent) { modbus="vvclock:3" }
Number VillaventClockMNTH "Clock month [%d]" (Villavent) { modbus="vvclock:4" }
Number VillaventClockY "Clock year [%d]" (Villavent) { modbus="vvclock:5" }

Switch VillaventSupplyAirTempFault "Supply air temperature sensor fault [%s]" <siren> (Villavent, Persist) { modbus="vvtsf:0" }
Switch VillaventExtractAirTempFault "Extract air temperature sensor fault [%s]" <siren> (Villavent, Persist) { modbus="vvtsf:0" }
Switch VillaventExhaustAirTempFault "Exhaust air temperature sensor fault [%s]" <siren> (Villavent, Persist) { modbus="vvtsf:0" }
Switch VillaventProtectAirTempFault "Overheating/Frostprotection temperature sensor fault [%s]" <siren> (Villavent, Persist) { modbus="vvtsf:0" }
Switch VillaventIntakeAirTempFault "Intake air temperature sensor fault [%s]" <siren> (Villavent, Persist) { modbus="vvtsf:0" }

Switch VillaventDigital1 "Digital input 1 [%s]" <switch> (Villavent, Persist) { modbus="vvdi:0" }
Number VillaventDigital1SF "Supply fan speed at DI1 [%s]" <fan> (Villavent, Persist) { modbus="vvdig:3" }
Number VillaventDigital1EF "Extract fan speed at DI1 [%s]" <fan> (Villavent, Persist) { modbus="vvdig:4" }
Switch VillaventDigital2 "Digital input 2 [%s]" <switch> (Villavent, Persist) { modbus="vvdi:1" }
Number VillaventDigital2SF "Supply fan speed at DI2 [%s]" <fan> (Villavent, Persist) { modbus="vvdig:5" }
Number VillaventDigital2EF "Extract fan speed at DI2 [%s]" <fan> (Villavent, Persist) { modbus="vvdig:6" }
Switch VillaventDigital3 "Digital input 3 [%s]" <switch> (Villavent, Persist) { modbus="vvdi:2" }
Number VillaventDigital3SF "Supply fan speed at DI3 [%s]" <fan> (Villavent, Persist) { modbus="vvdig:7" }
Number VillaventDigital3EF "Extract fan speed at DI3 [%s]" <fan> (Villavent, Persist) { modbus="vvdig:8" }
Switch VillaventDigital4 "Stop heat [%s]" <switch> (Villavent, Persist) { modbus="vvdi:3" }
Switch VillaventDigital5 "Extended run [%s]" <switch> (Villavent, Persist) { modbus="vvdi:4" }
Number VillaventDigital5Min "Extended running time [%d]" <time> (Villavent, Persist) { modbus="vvdig:1" }
Number VillaventDigital5Speed "Extended running speed [%d]" <fan> (Villavent, Persist) { modbus="vvdig:2" }
Switch VillaventDigital6 "Rotor top sensor [%s]" <switch> (Villavent, Persist) { modbus="vvdi:5" }
Switch VillaventDigital7 "Away [%s]" <switch> (Villavent, Persist) { modbus="vvdi:6" }

Switch VillaventFilterAlarm "Filter alarm [%s]" <siren> (Villavent, Persist) { modbus="vval:0" }
Switch VillaventFanAlarm "Fan alarm [%s]" <siren> (Villavent, Persist) { modbus="vval:1" }
Switch VillaventRotorAlarm "Rotor alarm [%s]" <siren> (Villavent, Persist) { modbus="vval:3" }
Switch VillaventFrostAlarm "Frost alarm [%s]" <siren> (Villavent, Persist) { modbus="vval:4" }
Switch VillaventPcuPbAlarm "PCU-PB alarm [%s]" <siren> (Villavent, Persist) { modbus="vval:5" }
Switch VillaventTempSensorAlarm "Temperature sensor alarm [%s]" <siren> (Villavent, Persist) { modbus="vval:6" }
Switch VillaventThermostatAlarm "Emergency thermostat alarm [%s]" <siren> (Villavent, Persist) { modbus="vval:7" }
Switch VillaventDamperAlarm "Damper alarm [%s]" <siren> (Villavent, Persist) { modbus="vval:8" }

Switch VillaventPreHeaterRelay "Preheater relay [%s]" <switch> (Villavent, Persist) { modbus="vvpcu:0" }
Switch VillaventHeaterRelay "Heater relay [%s]" <switch> (Villavent, Persist) { modbus="vvpcu:1" }
Switch VillaventCommonHeaterRelay "Common relay [%s]" <switch> (Villavent, Persist) { modbus="vvpcu:2" }

rules:

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

rule "Villavent home"
when
    Item PresenceState changed to HOME
then
    VillaventFan.sendCommand(2)
    VillaventDigital7.sendCommand(OFF)
end

rule "Villavent away"
when
    Item PresenceState changed to AWAY
then
    VillaventFan.sendCommand(1)
    VillaventDigital7.sendCommand(ON)
end

rule "Correct supply air temp"
when
    Item VillaventSupplyAirTemp_in changed
then
    val BigDecimal ret = (VillaventSupplyAirTemp_in.state as DecimalType).toBigDecimal.movePointLeft(1)
    VillaventSupplyAirTemp.postUpdate(new DecimalType(ret))
end

rule "Correct extract air temp"
when
    Item VillaventExtractAirTemp_in changed
then
    val BigDecimal ret = (VillaventExtractAirTemp_in.state as DecimalType).toBigDecimal.movePointLeft(1)
    VillaventExtractAirTemp.postUpdate(new DecimalType(ret))
end

rule "Correct exhaust air temp"
when
    Item VillaventExhaustAirTemp_in changed
then
    val BigDecimal ret = (VillaventExhaustAirTemp_in.state as DecimalType).toBigDecimal.movePointLeft(1)
    VillaventExhaustAirTemp.postUpdate(new DecimalType(ret))
end

rule "Correct protect air temp"
when
    Item VillaventProtectAirTemp_in changed
then
    val BigDecimal ret = (VillaventProtectAirTemp_in.state as DecimalType).toBigDecimal.movePointLeft(1)
    VillaventProtectAirTemp.postUpdate(new DecimalType(ret))
end

rule "Correct intake air temp"
when
    Item VillaventIntakeAirTemp_in changed
then
    val BigDecimal ret = (VillaventIntakeAirTemp_in.state as DecimalType).toBigDecimal.movePointLeft(1)
    VillaventIntakeAirTemp.postUpdate(new DecimalType(ret))
end

rule "Filter alert"
when
    Item VillaventFilterDays changed
then
    if (((VillaventFilterDays.state as DecimalType).intValue % Math::round(((VillaventFilterPeriod.state as DecimalType).intValue * 30.5) - 30)) == 0) {
        pushover("WARN: Villavent filter replacement is due")
    } else {
        if ((VillaventFilterDays.state as DecimalType).intValue >= (VillaventFilterPeriod.state as DecimalType).intValue * 30.5) {
            pushover("ERROR: Villavent filter replacement overdue")
        }
    }
end

rule "VV read clock"
when
    Item VillaventClockS changed
then
    var Calendar cal = Calendar::getInstance()
    cal.set(Calendar::HOUR_OF_DAY, (VillaventClockH.state as DecimalType).intValue)
    cal.set(Calendar::MINUTE, (VillaventClockM.state as DecimalType).intValue)
    cal.set(Calendar::SECOND, (VillaventClockS.state as DecimalType).intValue)
    cal.set(Calendar::DAY_OF_MONTH, (VillaventClockD.state as DecimalType).intValue)
    cal.set(Calendar::MONTH, (VillaventClockMNTH.state as DecimalType).intValue)
    cal.set(Calendar::YEAR, (VillaventClockY.state as DecimalType).intValue+2000)
    cal.clear(Calendar::MILLISECOND)
    VillaventClock.postUpdate(new DateTimeType(cal))
end

rule "VV write clock"
when
    System started or
    Time cron "0 0 6 * * ?"
then
    var Calendar cal = Calendar::getInstance()
    VillaventClockH.sendCommand(cal.get(Calendar::HOUR_OF_DAY))
    VillaventClockM.sendCommand(cal.get(Calendar::MINUTE))
    VillaventClockS.sendCommand(cal.get(Calendar::SECOND))

    VillaventClockD.sendCommand(cal.get(Calendar::DAY_OF_MONTH))
    VillaventClockMNTH.sendCommand(cal.get(Calendar::MONTH))
    VillaventClockY.sendCommand(cal.get(Calendar::YEAR)-2000)
end

rule "Write NVM"
when
    Time is midnight
then
    VillaventNvm.sendCommand(165)
end

rule "Villavent Program Version"
when
    System started or
    Item VillaventProgVH changed or
    Item VillaventProgVM changed or
    Item VillaventProgVL changed or
    Time is midnight
then
    VillaventProgVersion.postUpdate(String::format("%1$d.%2$02d.%3$02d",
        (VillaventProgVH.state as DecimalType).intValue,
        (VillaventProgVM.state as DecimalType).intValue,
        (VillaventProgVL.state as DecimalType).intValue
    ))
end

rule "Villavent Boot Version"
when
    System started or
    Item VillaventBootVH changed or
    Item VillaventBootVM changed or
    Item VillaventBootVL changed or
    Time is midnight
then
    VillaventBootVersion.postUpdate(String::format("%1$d.%2$02d.%3$02d",
        (VillaventBootVH.state as DecimalType).intValue,
        (VillaventBootVM.state as DecimalType).intValue,
        (VillaventBootVL.state as DecimalType).intValue
    ))
end

rule "Villavent filter alarm"
when
    Item VillaventFilterAlarm changed from OFF to ON
then
    pushover("ERROR: Villavent filter")
end

rule "Villavent filter ok"
when
    Item VillaventFilterAlarm changed from ON to OFF
then
    pushover("OK: Villavent filter")
end

rule "Villavent fan alarm"
when
    Item VillaventFanAlarm changed from OFF to ON
then
    pushover("ERROR: Villavent fan")
end

rule "Villavent fan ok"
when
    Item VillaventFanAlarm changed from ON to OFF
then
    pushover("OK: Villavent fan")
end

rule "Villavent rotor alarm"
when
    Item VillaventRotorAlarm changed from OFF to ON
then
    pushover("ERROR: Villavent rotor")
end

rule "Villavent rotor ok"
when
    Item VillaventRotorAlarm changed from ON to OFF
then
    pushover("OK: Villavent rotor")
end

rule "Villavent frost alarm"
when
    Item VillaventFrostAlarm changed from OFF to ON
then
    pushover("ERROR: Villavent frost")
end

rule "Villavent frost ok"
when
    Item VillaventFrostAlarm changed from ON to OFF
then
    pushover("OK: Villavent frost")
end

rule "Villavent PCU-PB alarm"
when
    Item VillaventPcuPbAlarm changed from OFF to ON
then
    pushover("ERROR: Villavent PCU-PB")
end

rule "Villavent PCU-PB ok"
when
    Item VillaventPcuPbAlarm changed from ON to OFF
then
    pushover("OK: Villavent PCU-PB")
end

rule "Villavent temp sensor alarm"
when
    Item VillaventTempSensorAlarm changed from OFF to ON
then
    pushover("ERROR: Villavent temp sensor")
end

rule "Villavent temp sensor ok"
when
    Item VillaventTempSensorAlarm changed from ON to OFF
then
    pushover("OK: Villavent temp sensor")
end

rule "Villavent thermostat alarm"
when
    Item VillaventThermostatAlarm changed from OFF to ON
then
    pushover("ERROR: Villavent emergency thermostat")
end

rule "Villavent thermostat ok"
when
    Item VillaventThermostatAlarm changed from ON to OFF
then
    pushover("OK: Villavent emergency thermostat")
end

rule "Villavent damper alarm"
when
    Item VillaventDamperAlarm changed from OFF to ON
then
    pushover("ERROR: Villavent damper")
end

rule "Villavent damper ok"
when
    Item VillaventDamperAlarm changed from ON to OFF
then
    pushover("OK: Villavent damper")
end

sitemap:

sitemap villavent label="Villavent" {
	Selection item=VillaventTempLvl mappings=[11="22 °C", 10="21 °C", 9="20 °C", 8="19 °C", 7="18 °C", 6="17 °C", 5="16 °C", 4="15 °C", 3="14 °C", 2="13 °C", 1="12° C", 0="Summer mode"]
	Selection item=VillaventFan icon=qualityofservice mappings=[4="Auto", 3="Max", 2="Normal", 1="Low", 0="Off"]
	Text item=VillaventSupplyAirTemp {
		Switch item=VillaventSupplyAirGraph label="Graph period" mappings=[1="Hour", 2="Day", 3="Week", 4="Month", 5="Year"]
		Chart item=VillaventSupplyAirTemp period=h refresh=30000 visibility=[VillaventSupplyAirGraph==1]
		Chart item=VillaventSupplyAirTemp period=D refresh=900000 visibility=[VillaventSupplyAirGraph==2]
		Chart item=VillaventSupplyAirTemp period=W refresh=3600000 visibility=[VillaventSupplyAirGraph==3]
		Chart item=VillaventSupplyAirTemp period=M refresh=3600000 visibility=[VillaventSupplyAirGraph==4]
		Chart item=VillaventSupplyAirTemp period=Y refresh=3600000 visibility=[VillaventSupplyAirGraph==5]
	}
	Text item=VillaventSupplyFanRpm {
		Switch item=VillaventSupplyFanGraph label="Graph period" mappings=[1="Hour", 2="Day", 3="Week", 4="Month", 5="Year"]
		Chart item=VillaventSupplyFanRpm period=h refresh=30000 visibility=[VillaventSupplyFanGraph==1]
		Chart item=VillaventSupplyFanRpm period=D refresh=900000 visibility=[VillaventSupplyFanGraph==2]
		Chart item=VillaventSupplyFanRpm period=W refresh=3600000 visibility=[VillaventSupplyFanGraph==3]
		Chart item=VillaventSupplyFanRpm period=M refresh=3600000 visibility=[VillaventSupplyFanGraph==4]
		Chart item=VillaventSupplyFanRpm period=Y refresh=3600000 visibility=[VillaventSupplyFanGraph==5]
	}
	Text item=VillaventExtractAirTemp {
		Switch item=VillaventExtractAirGraph label="Graph period" mappings=[1="Hour", 2="Day", 3="Week", 4="Month", 5="Year"]
		Chart item=VillaventExtractAirTemp period=h refresh=30000 visibility=[VillaventExtractAirGraph==1]
		Chart item=VillaventExtractAirTemp period=D refresh=900000 visibility=[VillaventExtractAirGraph==2]
		Chart item=VillaventExtractAirTemp period=W refresh=3600000 visibility=[VillaventExtractAirGraph==3]
		Chart item=VillaventExtractAirTemp period=M refresh=3600000 visibility=[VillaventExtractAirGraph==4]
		Chart item=VillaventExtractAirTemp period=Y refresh=3600000 visibility=[VillaventExtractAirGraph==5]
	}
	Text item=VillaventExtractFanRpm {
		Switch item=VillaventExtractFanGraph label="Graph period" mappings=[1="Hour", 2="Day", 3="Week", 4="Month", 5="Year"]
		Chart item=VillaventExtractFanRpm period=h refresh=30000 visibility=[VillaventExtractFanGraph==1]
		Chart item=VillaventExtractFanRpm period=D refresh=900000 visibility=[VillaventExtractFanGraph==2]
		Chart item=VillaventExtractFanRpm period=W refresh=3600000 visibility=[VillaventExtractFanGraph==3]
		Chart item=VillaventExtractFanRpm period=M refresh=3600000 visibility=[VillaventExtractFanGraph==4]
		Chart item=VillaventExtractFanRpm period=Y refresh=3600000 visibility=[VillaventExtractFanGraph==5]
	}
	Text item=VillaventIntakeAirTemp {
		Switch item=VillaventIntakeAirGraph label="Graph period" mappings=[1="Hour", 2="Day", 3="Week", 4="Month", 5="Year"]
		Chart item=VillaventIntakeAirTemp period=h refresh=30000 visibility=[VillaventIntakeAirGraph==1]
		Chart item=VillaventIntakeAirTemp period=D refresh=900000 visibility=[VillaventIntakeAirGraph==2]
		Chart item=VillaventIntakeAirTemp period=W refresh=3600000 visibility=[VillaventIntakeAirGraph==3]
		Chart item=VillaventIntakeAirTemp period=M refresh=3600000 visibility=[VillaventIntakeAirGraph==4]
		Chart item=VillaventIntakeAirTemp period=Y refresh=3600000 visibility=[VillaventIntakeAirGraph==5]
	}
	Text item=Villavent label="Configuration" icon=settings {
		Frame label="Information" {
			Text item=VillaventSystemType
			Text item=VillaventClock
			Text item=VillaventProgVersion
			Text item=VillaventBootVersion
		}
		Frame label="Fan" {
			Selection item=VillaventFanControlType mappings=[0="Air flow", 1="Speed"]
			Selection item=VillaventFlowUnits mappings=[0="l/s", 1="m3/h"]
			Setpoint item=VillaventSupplyFanSystemCurve minValue=0 maxValue=20 step=1
			Setpoint item=VillaventExtractFanSystemCurve minValue=0 maxValue=10 step=1
			Setpoint item=VillaventSupplyFanSpeedLow minValue=10 maxValue=100 step=1
			Setpoint item=VillaventExtractFanSpeedLow minValue=10 maxValue=100 step=1
			Setpoint item=VillaventSupplyFanSpeedNom minValue=10 maxValue=100 step=1
			Setpoint item=VillaventExtractFanSpeedNom minValue=10 maxValue=100 step=1
			Setpoint item=VillaventSupplyFanSpeedHigh minValue=10 maxValue=100 step=1
			Setpoint item=VillaventExtractFanSpeedHigh minValue=10 maxValue=100 step=1
			Switch item=VillaventAllowFanStop
		}
		Frame label="Filter" {
			Setpoint item=VillaventFilterPeriod minValue=6 maxValue=12 step=1 label="Replace interval"
			Text item=VillaventFilterDays label="Days since last replace"
		}
		Frame label="Heater and cooler" {
			Selection item=VillaventHeaterType mappings=[3="Contactor", 2="Electrical", 1="Water", 0="None"]
			Text item=VillaventHeaterRelay
			Selection item=VillaventPreHeaterType mappings=[1="Electrical", 0="None"]
			Text item=VillaventPreHeaterRelay
			Selection item=VillaventCoolerType mappings=[1="Water", 0="None"]
			Text item=VillaventCommonHeaterRelay
			Selection item=VillaventFrostProtection mappings=[120="12° C", 110="11° C", 100="10° C", 90="9° C", 80="8° C", 70="7° C"]
			Switch item=VillaventDigital4
			Text item=VillaventHeatSetpoint
		}
		Frame label="Rotor" {
			Text item=VillaventRotorState label="State"
			Text item=VillaventRotorRelayActive label="Relay"
			Text item=VillaventDigital6 label="Rotation sensor"
		}
		Frame label="Defrosting" {
			Text item=VillaventDefrostState label="State"
			Selection item=VillaventDefrostMode mappings=[0="0", 1="1", 2="2", 3="3", 4="4", 5="5"] label="Mode"
		}
		Frame label="Digital inputs" {
			Switch item=VillaventDigital7
		}
		Frame label="" {
			Switch item=VillaventDigital1
			Selection item=VillaventDigital1SF mappings=[3="Max", 2="Normal", 1="Low", 0="Off"]
			Selection item=VillaventDigital1EF mappings=[3="Max", 2="Normal", 1="Low", 0="Off"]
		}
		Frame label="" {
			Switch item=VillaventDigital2
			Selection item=VillaventDigital2SF mappings=[3="Max", 2="Normal", 1="Low", 0="Off"]
			Selection item=VillaventDigital2EF mappings=[3="Max", 2="Normal", 1="Low", 0="Off"]
		}
		Frame label="" {
			Switch item=VillaventDigital3
			Selection item=VillaventDigital3SF mappings=[3="Max", 2="Normal", 1="Low", 0="Off"]
			Selection item=VillaventDigital3EF mappings=[3="Max", 2="Normal", 1="Low", 0="Off"]
		}
		Frame label="" {
			Switch item=VillaventDigital5
			Setpoint item=VillaventDigital5Min minValue=1 maxValue=60 step=1
			Selection item=VillaventDigital5Speed mappings=[3="Max", 2="Normal", 1="Low", 0="Off"]
		}
		Frame label="Temperature sensors" {
			Text item=VillaventSupplyAirTemp
			Text item=VillaventSupplyAirTempFault
			Text item=VillaventExtractAirTemp
			Text item=VillaventExtractAirTempFault
			Text item=VillaventExhaustAirTemp
			Text item=VillaventExhaustAirTempFault
			Text item=VillaventProtectAirTemp
			Text item=VillaventProtectAirTempFault
			Text item=VillaventIntakeAirTemp
			Text item=VillaventIntakeAirTempFault
		}
		Frame label="Alarms" {
			Text item=VillaventFilterAlarm
			Text item=VillaventFanAlarm
			Text item=VillaventRotorAlarm
			Text item=VillaventFrostAlarm
			Text item=VillaventPcuPbAlarm
			Text item=VillaventTempSensorAlarm
			Text item=VillaventThermostatAlarm
			Text item=VillaventDamperAlarm
		}
	}
	Text item=VillaventTemperatureGroup label="Temperature graph" icon=line {
		Switch item=VillaventTemperatureGroupGraph label="Graph period" mappings=[1="Hour", 2="Day", 3="Week", 4="Month", 5="Year"]
		Chart item=VillaventTemperatureGroup period=h refresh=30000 visibility=[VillaventTemperatureGroupGraph==1]
		Chart item=VillaventTemperatureGroup period=D refresh=900000 visibility=[VillaventTemperatureGroupGraph==2]
		Chart item=VillaventTemperatureGroup period=W refresh=3600000 visibility=[VillaventTemperatureGroupGraph==3]
		Chart item=VillaventTemperatureGroup period=M refresh=3600000 visibility=[VillaventTemperatureGroupGraph==4]
		Chart item=VillaventTemperatureGroup period=Y refresh=3600000 visibility=[VillaventTemperatureGroupGraph==5]
	}
}

(Kim Skatun) #62

This is such a great write up, do you reckon you could turn it into a tutorial and also add some screenshots of the setup(both sitemaps and physical wiring). Great work Gunnar!


(Gunnar Skjold) #63

Thanks, I’ll see what I can do over a cold beer one weekend :slight_smile:


(Miha Mihalj) #64

Hi, please can you give some screenshots of wiring on Systemair ventilation?


(Gunnar Skjold) #65

My recommendation, buy something like a FTDI USB-RS485-PCBA and connect like attached image. Solid blue to B and striped blue to A from a standard T568 color coded RJ45 cable.

vv_rs485


(Gunnar Skjold) #66

I have also edited the configuration in my previous comment to match the config I use today.


(Miha Mihalj) #67

OK so that it, just plug one side of the cable RJ-45 to board on Systemair HRV unit and other side with two wires like you mentioned to FTDI USB and then plug it to Raspberry pi…

Please send picture how does it look on OH dashboard…


(Gunnar Skjold) #68

Correct. According to the modbus document from Systemair, the following units use this registry set:
VR400, VR700, VR700DK, VR400DE, VTC300, VTC700, VTR150K, VTR200B, VSR300, VSR500, VSR150, VTR300, VTR500, VSR300DE, VTC200

There may be more that also use the same registry set, but these are at least mentioned in the document.

I have tested this on a Asus Tinkerboard, and the system totally crash when I run openhab with this setup. Without the RS485 USB connected it runs fine. I’m not sure if this is some issue isolated to Tinkerboard and the chipset it uses or if this would apply for Raspberry Pi as well. As far as I could tell when debugging it was related to chipset and IO. I did not use much time to try and fix it as it wasn’t important to me.

An alternative would be to find a modbus rs485 to tcp/ip adapter, but I have no suggestion on what hardware to use or how well it works.

Following is some screenshots from my openhab basicui:

Configuration menu:



Temperature graph:


(Kim Skatun) #69

I guess it would be nice to set up a usb rule, so that in case of shutdown and a new number get assigned it will still work. I am can not rember how to do this now, but it is explained somewhere on the forum here. Just a small tip. It looks awesome @gskjold, and something I will definitely implement over Xmas, are you running it on a RPI?

Do you have link to your dongle?

So which temperatures do you recommend to use? Some models have an optional heating element to preheat the incoming air(supply).


(Gunnar Skjold) #70

I have the followig in my /etc/udev/rules.d/99-usb-serial.rules

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", OWNER="openhab" SYMLINK="modbus"

This creates /dev/modbus as a device, but openhab does not work with this symlink for some reason. I have not chased this issue, so the solution may be simple. On reboot the device stays the same. Only replugging the device will change the identifier.

Not tried this setup on rpi yet. I use a HP G7 micro server.

My dongle is a FTDI USB-RS485-PCBA which you can find on ebay.

As for set temperatures I have 22° set in the winter. I use the electric heater in mine. I just feel this makes for more comfortable air in my house. My rules sets the away flag in the unit which switches off this heater when I am away. You can see it in the temperature graph. Looking at the blue and red line (which overlaps), you can see the ripples in the supply air when I am home, and how it is switched off when I am away. I also set the fan to low when I am away.

Temp graph:
vv_openhab_graph

Fan graph:
vv_openhab_graph2


(Kim Skatun) #71

To your info I got it to work now. I will make some rules and keep you posted on the progress, thanks for the great work…

Some additional information to you.

  1. I am on openhabian, so I just issued system tweaks to get the serial device to work.
  2. Get last connected USB device
    dmesg | awk '/tty/ && /USB/ {print "/dev/"$10}'|tail -1```
    
  3. Get the device number
    lsusb
  4. Edit usb rules: sudo nano /etc/udev/rules.d/99-usb-serial.rules
    SUBSYSTEM=="tty", ATTRS{idVendor}=="XXX", ATTRS{idProduct}=="XXXX", OWNER="openhab" SYMLINK="modbus" however I could not get this to work either…
  5. Go to your fan panel and make sure the modbus settings are correct:
    Baudrate:19200, startIndex =1 Parity:None

So lets now move on to the rules:
So what I want to do with the fan is:

  1. Increase the speed if you go to the bathroom
  2. Switch it off when you are not home
  3. Adjust it automatically depending on CO2 level in the flat

The question is if we should adjust the rpm or do we only have the option to set fan speed to 1,2,3,4, what do you think @gskjold, can these be set dynamically:

Number VillaventSupplyFanRpm 
Number VillaventExtractFanRpm 

So my rule idea is shown below

val Functions.Function2 hvac= [ NumberItem setPoint,NumberItem co2Level ||

if manualOverride.state = OFF {
if((co2Level.state as Number)-100.0<(setPoint.state as Number) ) {

   VillaventFan.sendCommand( VillaventFan.state as Number -1)
}
if((co2Level.state as Number)+100.0>(setPoint.state as Number) ) {

   VillaventFan.sendCommand( VillaventFan.state as Number +1)
}
}

The bathroom rule:

rule "Turn up fan"
when
	Item bathroomLight changed  to ON
then

        VillaventFan.sendCommand(4)
	createTimer(now.plusSeconds(600))[|
	sendCommand(manualOverride, ON)
]
 sendCommand(manualOverride, OFF)
end

(Håvard Berland) #72

Thanks for all the details in here, I will build something similar to replace my existing Z-wave unit attached to my VSR-300 (not working in OH2.4, and also with very limited feature set compared to the solution here).

My OpenHAB server is two floors away from the ventilation unit, so a direct connection is not possible. A Raspberry PI is a candidate, any recommendation on how to connect them? USB over TCP/IP, serial over TCP/IP (maybe the same thing?), or possibly write a MQTT service on the Pi?