Rules - Getting item status for different items out of one string

Dear community,

I need some advice: I have a script that results in a string:

bash /etc/openhab2/scripts/vclient.sh 
Aussentemperatur:
-3.300000 Grad Celsius
Pufferspeichertemperatur:
40.599998 Grad Celsius
Warmwassertemperaturoben:
48.900002 Grad Celsius
Warmwassersolltemperatur:
50.000000 Grad Celsius
Zirkulationspumpe:
0
Raumsolltemperaturnormal:
22.000000 Grad Celsius
RaumsolltemperaturreduzierterBetrieb:
16.000000 Grad Celsius
NeigungderHeizkennlinie:
0.500000 
NiveauderHeizkennlinie:
5.000000 
VorlauftemperaturHK2:
39.900002 Grad Celsius
VorlauftemperaturSek:
41.200001 Grad Celsius
RuecklauftemperaturSek:
37.799999 Grad Celsius
VorlauftemperaturPrimaer:
3.800000 Grad Celsius
RuecklauftemperaturPrimaer:
0.700000 Grad Celsius

I created items with the same name as the lines with ā€œ:ā€ e.g. Aussentemperatur.

I tried to create a rule that splits the string into several values using an array:

rule "heizung alle 5 minuten"
when
	Time cron "0 */1 * ? * *"
then
	var List<String> array2 = new ArrayList
	val results = executeCommandLine("/etc/openhab2/scripts/vclient.sh",5000)
	val array = results.toString.split("\n|\r\n")
	array.forEach[ value |
		if (value.toString.contains("Grad")) {
			array2 = value.toString.split(" ").get(0)
		}
	]
	postUpdate(HeizungAussentemperatur,array2.get(0))
	postUpdate(Pufferspeichertemperatur,array2.get(1))
	postUpdate(Warmwassertemperaturoben,array2.get(2))
	postUpdate(Zirkulationspumpe,array2.get(3))
	postUpdate(Raumsolltemperaturnormal,array2.get(4))
	postUpdate(RaumsolltemperaturreduzierterBetrieb,array2.get(5))
	postUpdate(NeigungderHeizkennlinie,array2.get(6))
	postUpdate(NiveauderHeizkennlinie,array2.get(7))
	postUpdate(VorlauftemperaturHK2,array2.get(8))
	postUpdate(VorlauftemperaturSek,array2.get(9))
	postUpdate(RuecklauftemperaturSek,array2.get(10))
	postUpdate(VorlauftemperaturPrimaer,array2.get(11))
	postUpdate(RuecklauftemperaturPrimaer,array2.get(12))
	//logInfo("Exec", "Results from vclient fuer Aussentemperatur: " + results)
	//postUpdate(HeizungAussentemperatur,results)

end

Currently my log file shows:

2019-12-27 15:39:00.009 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'heizung alle 5 minuten': An error occurred during the script execution: null

Is there an easier way to handle this? Maybe an array is not the best.

Thank you.
Michael

Do you has access to the script? If yes make it output in JSON format. Much easier to handle
If not, let me thinkā€¦

array2 is not an array, itā€™s a string

rule "heizung alle 5 minuten"
when
	Time cron "0 */1 * ? * *"
then
	var array2 = ""
	val results = executeCommandLine("/etc/openhab2/scripts/vclient.sh",5000)
	val array = results.toString.split("\n|\r\n")
	array.forEach[ value |
		if (value.toString.contains("Grad")) {
			array2 = value.toString.split(" ").get(0)
		}
	]
	postUpdate(HeizungAussentemperatur,array2.get(0))

But that would not workā€¦
Try splitting the string with :

```php
rule "heizung alle 5 minuten"
when
    Time cron "0 */1 * ? * *"
then
    var array2 = ""
    val results = executeCommandLine("/etc/openhab2/scripts/vclient.sh",5000)
    val array1 = results.toString.split(":")
    for(int i = 0; i < array1.length; i++) {
        if(!intArr[i].toString.contains("Grad")) {
            // drop element not containing "Grad" and shift elements
            for(int j = i; j < array1.length - 1; j++) {
                intArr[j] = intArr[j+1];
            }
            break;
        }
    }
    //Do it again to retreive the number value only
    for(int i = 0; i < array1.length; i++) {
        array1[i] = array1[i].toString.split(" ").get(0)
    }
    // Now you should have an array containing only numbers (In string format) in the same order as they came in
    // You need to know the order in which they come
    HeizungAussentemperatur.postUpdate(array1.get(0))
    ....

This is a quick and dirty impro script and probably full of bugs and not tested
Add logInfo statements everywhere and get to it

Thank you for your answer. Sadly I am unable to access the script. I will try your solutions and will let you know.

Thanks
Michael

Hello Vincent,

this is my modified rule:

rule "heizung alle 5 minuten"
when
	Time cron "0 */1 * ? * *"
then
	var array2 = newArrayList(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
	var help = ""
	val results = executeCommandLine("/etc/openhab2/scripts/vclient.sh",5000)
	var array1 = results.toString.split("\n")
    	for(var i=0; i<array1.length; i++) {
		//logInfo("heizung.rules", array1.get(i))
        	if(!array1.get(i).toString.contains("Grad")) {
            	// drop element not containing "Grad" and shift elements
            	for(var j=i; j<(array1.length-1); j++) {
			//logInfo("heizung.rules","Wert von j: "+j)
			//logInfo("heizung.rules","array an stelle j:"+ array1.get(j))
                	array1.set(j,array1.get(j+1))
            		}
        	}
    	}
    	//Do it again to retreive the number value only
    	for(var i=0; i<13; i++) {
		logInfo("heizung.rules", "Array1 in Stelle: "+i+ " hat den Wert: "+array1.get(i))
        	help = array1.get(i).toString.split(" ").get(0)
		logInfo("heizung.rules", "Hilfsvariable help Nummer " + i +" = "+help)
		//array2.set(i,help)
		array2.set(i,array1.get(i).toString.split(" ").get(0))
		logInfo("Heizung.rules", "Array2 in Stelle: "+i+" hat den Wert: "+array2.get(i))
    	}
	postUpdate(HeizungAussentemperatur,array2.get(0))
	postUpdate(Pufferspeichertemperatur,array2.get(1))
	postUpdate(Warmwassertemperaturoben,array2.get(2))
	postUpdate(Zirkulationspumpe,array2.get(3))
	postUpdate(Raumsolltemperaturnormal,array2.get(4))
	postUpdate(RaumsolltemperaturreduzierterBetrieb,array2.get(5))
	postUpdate(NeigungderHeizkennlinie,array2.get(6))
	postUpdate(NiveauderHeizkennlinie,array2.get(7))
	postUpdate(VorlauftemperaturHK2,array2.get(8))
	postUpdate(VorlauftemperaturSek,array2.get(9))
	postUpdate(RuecklauftemperaturSek,array2.get(10))
	postUpdate(VorlauftemperaturPrimaer,array2.get(11))
	postUpdate(RuecklauftemperaturPrimaer,array2.get(12))
end

The error I get is when it comes to update my items:

2019-12-29 21:51:09.215 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'heizung alle 5 minuten': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,java.lang.Number) on instance: null

Maybe this is a problem with the array value and the number format of the item?

My items definition for Aussentemperatur:

Number HeizungAussentemperatur "AuƟentemperatur [%.1f Ā°C]" (gHeizungTemperaturen)

Thank you for your help.
Michael

First use the method item.postUpdate instead of the action:

HeizungAussentemperatur.postUpdate(array2.get(0))

Then what do the logs say?

Hello Vincent,

Thank you for your reply. The error message is the same:

2019-12-29 22:22:05.541 [INFO ] [smarthome.model.script.heizung.rules] - array2.get(0) = 0.000000
2019-12-29 22:22:05.548 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'heizung alle 5 minuten': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,java.lang.Number) on instance: null

I added some extra logging:

	logInfo("heizung.rules","array2.get(0) = "+array2.get(0))
	HeizungAussentemperatur.postUpdate(array2.get(0))

btw: 0.00000 is correct. I have currently 0 Ā°C outside.

Try that:

HeizungAussentemperatur.postUpdate(array2.get(0).toString)

Brrrr!!!

Hello Vincent,

a different error message appears.

2019-12-29 22:32:06.934 [INFO ] [smarthome.model.script.heizung.rules] - array2.get(0) = 0.100000

2019-12-29 22:32:06.941 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'heizung alle 5 minuten': An error occurred during the script execution: Could not invoke method: java.lang.Integer.toString() on instance: 0.100000

Better

HeizungAussentemperatur.postUpdate(array2.get(0) as Number)

Hello Vincent,

I modified the rule as you suggested and a different error message appears:

2019-12-29 22:38:07.514 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'heizung alle 5 minuten': Could not cast 0.200000 to java.lang.Number; line 21, column 37, length 23

Type casting is a B***

HeizungAussentemperatur.postUpdate((array2.get(0) as Number).toString)

Hello Vincent,

the error message stays the same:

Could not cast 0.200000 to java.lang.Number

I guess the problem is the declaration of the variable array2 at the very beginning:

	var array2 = newArrayList(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)

I nearly spent the whole day to find a way how to declare an array. This code worked for me but to be honest I am not quite sure what it exactly does. Does this create an array with the numbers 0, 1 etc. in it?

Maybe the problem is that this is a integer array and the values I add have a ā€œ.ā€ ?

Thank you again for your help.
Michael

Yes I think so.

I am a bit stumped. I donā€™t work with array at all. I have never needed to.

Have you tried:

	var array2 = newArrayList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0)

I do not think it is any sort of array in particular, so itā€™s decided to be ā€˜floatā€™ perhaps.

Iā€™d try typing it

var String[] array1 = results.....

ā€œarraysā€ are always a bit of a horror in rules DSL

1 Like