Dear colleagues,
Due to time issues I was not able yet to solve my request by my own with a script for the exec binding. For now, my solution looks like the following, maybe this will help other beginners, too.
For each value, I created a single thing for the Exec binding which I initially wanted to avoid:
//Exec things
Thing exec:command:getTempA "getTempA" [command="vclient -h 127.0.01 -p 3002 -m -c getTempA | cut -d\" \" -f2", interval=0, timeout=600, autorun=false]
Thing exec:command:getTempWWIst "getTempWWIst" [command="vclient -h 127.0.01 -p 3002 -m -c getTempWWIst | cut -d\" \" -f2", interval=0, timeout=600, autorun=false]
Thing exec:command:getTempKesselIst "getTempKesselIst" [command="vclient -h 127.0.01 -p 3002 -m -c getTempKesselIst | cut -d\" \" -f2", interval=0, timeout=600, autorun=false]
Thing exec:command:getTempVLSoll "getTempVLSoll" [command="vclient -h 127.0.01 -p 3002 -m -c getTempVLSoll | cut -d\" \" -f2", interval=0, timeout=600, autorun=false]
Thing exec:command:getLaufzeitBrenner "getLaufzeitBrenner" [command="vclient -h 127.0.01 -p 3002 -m -c getLaufzeitBrenner | cut -d\" \" -f2", interval=0, timeout=600, autorun=false]
Thing exec:command:getStartsBrenner "getStartsBrenner" [command="vclient -h 127.0.01 -p 3002 -m -c getStartsBrenner | cut -d\" \" -f2", interval=0, timeout=600, autorun=false]
Thing exec:command:getTempRaumNorSoll "getTempRaumNorSoll" [command="vclient -h 127.0.01 -p 3002 -m -c getTempRaumNorSoll | cut -d\" \" -f2", interval=0, timeout=600, autorun=false]
Thing exec:command:getTempRaumRedSoll "getTempRaumRedSoll" [command="vclient -h 127.0.01 -p 3002 -m -c getTempRaumRedSoll | cut -d\" \" -f2", interval=0, timeout=600, autorun=false]
Thing exec:command:getKennlinieNeigung "getKennlinieNeigung" [command="vclient -h 127.0.01 -p 3002 -m -c getKennlinieNeigung | cut -d\" \" -f2", interval=0, timeout=600, autorun=false]
Thing exec:command:getKennlinieNiveau "getKennlinieNiveau" [command="vclient -h 127.0.01 -p 3002 -m -c getKennlinieNiveau | cut -d\" \" -f2", interval=0, timeout=6e00, autorun=false]
My whitelist of course contains all of the mentioned shell commands:
vclient -h 127.0.01 -p 3002 -m -c getTempA | cut -d" " -f2
vclient -h 127.0.01 -p 3002 -m -c getTempWWIst | cut -d" " -f2
vclient -h 127.0.01 -p 3002 -m -c getTempKesselIst | cut -d" " -f2
vclient -h 127.0.01 -p 3002 -m -c getTempVLSoll | cut -d" " -f2
vclient -h 127.0.01 -p 3002 -m -c getLaufzeitBrenner | cut -d" " -f2
vclient -h 127.0.01 -p 3002 -m -c getStartsBrenner | cut -d" " -f2
vclient -h 127.0.01 -p 3002 -m -c getTempRaumNorSoll | cut -d" " -f2
vclient -h 127.0.01 -p 3002 -m -c getTempRaumRedSoll | cut -d" " -f2
vclient -h 127.0.01 -p 3002 -m -c getKennlinieNeigung | cut -d" " -f2
vclient -h 127.0.01 -p 3002 -m -c getKennlinieNiveau | cut -d" " -f2
Now I added for each value an item for the run
-channel, output
-channel and lastexecution
channel as well as a proxy Number
item in order to convert the string ouput to a number for influxdb:
//Exec items for run
Switch getTempA_Run "Run" {channel="exec:command:getTempA:run", autoupdate="false"}
Switch getTempWWIst_Run "Run" {channel="exec:command:getTempWWIst:run", autoupdate="false"}
Switch getTempKesselIst_Run "Run" {channel="exec:command:getTempKesselIst:run", autoupdate="false"}
Switch getTempVLSoll_Run "Run" {channel="exec:command:getTempVLSoll:run", autoupdate="false"}
Switch getLaufzeitBrenner_Run "Run" {channel="exec:command:getLaufzeitBrenner:run", autoupdate="false"}
Switch getStartsBrenner_Run "Run" {channel="exec:command:getStartsBrenner:run", autoupdate="false"}
Switch getTempRaumNorSoll_Run "Run" {channel="exec:command:getTempRaumNorSoll:run", autoupdate="false"}
Switch getTempRaumRedSoll_Run "Run" {channel="exec:command:getTempRaumRedSoll:run", autoupdate="false"}
Switch getKennlinieNeigung_Run "Run" {channel="exec:command:getKennlinieNeigung:run", autoupdate="false"}
Switch getKennlinieNiveau_Run "Run" {channel="exec:command:getKennlinieNiveau:run", autoupdate="false"}
//Exec items for raw information
String getTempA_Raw {channel="exec:command:getTempA:output"}
String getTempWWIst_Raw {channel="exec:command:getTempWWIst:output"}
String getTempKesselIst_Raw {channel="exec:command:getTempKesselIst:output"}
String getTempVLSoll_Raw {channel="exec:command:getTempVLSoll:output"}
String getLaufzeitBrenner_Raw {channel="exec:command:getLaufzeitBrenner:output"}
String getStartsBrenner_Raw {channel="exec:command:getStartsBrenner:output"}
String getTempRaumNorSoll_Raw {channel="exec:command:getTempRaumNorSoll:output"}
String getTempRaumRedSoll_Raw {channel="exec:command:getTempRaumRedSoll:output"}
String getKennlinieNeigung_Raw {channel="exec:command:getKennlinieNeigung:output"}
String getKennlinieNiveau_Raw {channel="exec:command:getKennlinieNiveau:output"}
//Items for converted number information
Number getTempA_Num "Außentemperatur [%.1f °C]"
Number getTempWWIst_Num "Warmwasser [%.1f °C]"
Number getTempKesselIst_Num "Kesseltemperatur [%.1f °C]"
Number getTempVLSoll_Num "Vorlauftemperatur [%.1f °C]"
Number getLaufzeitBrenner_Num "Brenner Laufzeit"
Number getStartsBrenner_Num "Brenner Starts"
Number getTempRaumNorSoll_Num "Raumtemperatur Normal [%.1f °C]"
Number getTempRaumRedSoll_Num "Raumtemperatur Reduziert [%.1f °C]"
Number getKennlinieNeigung_Num "Heizkennlinie Neigung"
Number getKennlinieNiveau_Num "Heizkennlinie Niveau"
//Exec items for last ececution information
DateTime getTempA_Last {channel="exec:command:getTempA:lastexecution"}
DateTime getTempWWIst_Last {channel="exec:command:getTempWWIst:lastexecution"}
DateTime getTempKesselIst_Last {channel="exec:command:getTempKesselIst:lastexecution"}
DateTime getTempVLSoll_Last {channel="exec:command:getTempVLSoll:lastexecution"}
DateTime getLaufzeitBrenner_Last {channel="exec:command:getLaufzeitBrenner:lastexecution"}
DateTime getStartsBrenner_Last {channel="exec:command:getStartsBrenner:lastexecution"}
DateTime getTempRaumNorSoll_Last {channel="exec:command:getTempRaumNorSoll:lastexecution"}
DateTime getTempRaumRedSoll_Last {channel="exec:command:getTempRaumRedSoll:lastexecution"}
DateTime getKennlinieNeigung_Last {channel="exec:command:getKennlinieNeigung:lastexecution"}
DateTime getKennlinieNiveau_Last {channel="exec:command:getKennlinieNiveau:lastexecution"}
With the following rule, every ten seconds a value is requested with the exec channel. The rule runs every two minutes. So the mentioned “cooldown” the adapter needs is 10 seconds, which, at least for now, seems to be enough to respons properly:
rule "Viessmann openv collection"
when
// System started or
Time cron "0 */2 * ? * *"
then
createTimer(now.plusSeconds(0), [ getTempA_Run.sendCommand(ON) ])
createTimer(now.plusSeconds(10), [ getTempWWIst_Run.sendCommand(ON) ])
createTimer(now.plusSeconds(20), [ getTempKesselIst_Run.sendCommand(ON) ])
createTimer(now.plusSeconds(30), [ getTempVLSoll_Run.sendCommand(ON) ])
createTimer(now.plusSeconds(40), [ getLaufzeitBrenner_Run.sendCommand(ON) ])
createTimer(now.plusSeconds(50), [ getStartsBrenner_Run.sendCommand(ON) ])
createTimer(now.plusSeconds(60), [ getTempRaumNorSoll_Run.sendCommand(ON) ])
createTimer(now.plusSeconds(70), [ getTempRaumRedSoll_Run.sendCommand(ON) ])
createTimer(now.plusSeconds(80), [ getKennlinieNeigung_Run.sendCommand(ON) ])
createTimer(now.plusSeconds(90), [ getKennlinieNiveau_Run.sendCommand(ON) ])
end
The next rules are the for the string to number conversion for each value in order to be ready for the influxdb.persistence:
rule "Convert getTempA"
when
Item getTempA_Raw changed
then
getTempA_Num.postUpdate(Float::parseFloat(String::format("%s",getTempA_Raw.state).replace(' ','')))
end
rule "Convert getTempWWIst"
when
Item getTempWWIst_Raw changed
then
getTempWWIst_Num.postUpdate(Float::parseFloat(String::format("%s",getTempWWIst_Raw.state).replace(' ','')))
end
rule "Convert getTempKesselIst"
when
Item getTempKesselIst_Raw changed
then
getTempKesselIst_Num.postUpdate(Float::parseFloat(String::format("%s",getTempKesselIst_Raw.state).replace(' ','')))
end
rule "Convert getTempVLSoll"
when
Item getTempVLSoll_Raw changed
then
getTempVLSoll_Num.postUpdate(Float::parseFloat(String::format("%s",getTempVLSoll_Raw.state).replace(' ','')))
end
rule "Convert getLaufzeitBrenner"
when
Item getLaufzeitBrenner_Raw changed
then
getLaufzeitBrenner_Num.postUpdate(Float::parseFloat(String::format("%s",getLaufzeitBrenner_Raw.state).replace(' ','')))
end
rule "Convert getStartsBrenner"
when
Item getStartsBrenner_Raw changed
then
getStartsBrenner_Num.postUpdate(Float::parseFloat(String::format("%s",getStartsBrenner_Raw.state).replace(' ','')))
end
rule "Convert getTempRaumNorSoll"
when
Item getTempRaumNorSoll_Raw changed
then
getTempRaumNorSoll_Num.postUpdate(Float::parseFloat(String::format("%s",getTempRaumNorSoll_Raw.state).replace(' ','')))
end
rule "Convert getTempRaumRedSoll"
when
Item getTempRaumRedSoll_Raw changed
then
getTempRaumRedSoll_Num.postUpdate(Float::parseFloat(String::format("%s",getTempRaumRedSoll_Raw.state).replace(' ','')))
end
rule "Convert getKennlinieNeigung"
when
Item getKennlinieNeigung_Raw changed
then
getKennlinieNeigung_Num.postUpdate(Float::parseFloat(String::format("%s",getKennlinieNeigung_Raw.state).replace(' ','')))
end
rule "Convert getKennlinieNiveau"
when
Item getKennlinieNiveau_Raw changed
then
getKennlinieNiveau_Num.postUpdate(Float::parseFloat(String::format("%s",getKennlinieNiveau_Raw.state).replace(' ','')))
end
With the influx persistence, every value is sucessfully passed for a nice visulatation of my Viessmann heater:
As soon I got more time I would like to solve this task with a python script, but I think I heavily rely in your support because these are my first steps at all in this regard.
Anyway, thank you for pushing me into the right direction!
Best regards,
Markus