Getting values from String items

Hi,

I want to get the value from String items within my rule file. I tried following

logInfo("rules", "Fenster 1 state {}", iKonferenz_Homematic_Fenster1_Position)
logInfo("rules", "Fenster 1 state {}", iKonferenz_Homematic_Fenster1_Position.state.toString)

And I got:

10:04:21.038 [INFO ] [.eclipse.smarthome.model.script.rules] - Fenster 1 state iKonferenz_Homematic_Fenster1_Position (Type=StringItem, State=NULL, Label=Position, Category=blinds, Groups=[gKonferenz_Fenster1])
10:04:21.038 [INFO ] [.eclipse.smarthome.model.script.rules] - Fenster 1 NULL

Also I have used it as String in my .items file:

String iKonferenz_Homematic_Fenster1_Position                                  "Position"                                    <blinds>                        (gKonferenz_Fenster1)                                        {channel="homematic:<...>1#STATE"}

Inside my sitemap I sadly got:

Position Window status: locked 

What would work is that I get the values inside MQTT.fx for /messages/states/iKonferenz_Homematic_Fenster1_Position if I subcribe to it. I got the values OPEN, TILTED and CLOSED. Inside my rules following triggers would work:

rule "WindowsClosed"
when
	Item iKonferenz_Homematic_Fenster1_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster2_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster3_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster4_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster5_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster6_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster1_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster2_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster3_Position changed to CLOSED
then
	....
end

rule "WindowsTilted"
when
	Item iKonferenz_Homematic_Fenster1_Position changed to TILTED or
	Item iKonferenz_Homematic_Fenster2_Position changed to TILTED or
	Item iKonferenz_Homematic_Fenster3_Position changed to TILTED or
	Item iKonferenz_Homematic_Fenster4_Position changed to TILTED or
	Item iKonferenz_Homematic_Fenster5_Position changed to TILTED or
	Item iKonferenz_Homematic_Fenster6_Position changed to TILTED or
	Item iMultimedia_Homematic_Fenster1_Position changed to TILTED or
	Item iMultimedia_Homematic_Fenster2_Position changed to TILTED or
	Item iMultimedia_Homematic_Fenster3_Position changed to TILTED

then
	....
end

rule "WindowsOpen"
when
	Item iKonferenz_Homematic_Fenster1_Position changed to OPEN or
	Item iKonferenz_Homematic_Fenster2_Position changed to OPEN or
	Item iKonferenz_Homematic_Fenster3_Position changed to OPEN or
	Item iKonferenz_Homematic_Fenster4_Position changed to OPEN or
	Item iKonferenz_Homematic_Fenster5_Position changed to OPEN or
	Item iKonferenz_Homematic_Fenster6_Position changed to OPEN or
	Item iMultimedia_Homematic_Fenster1_Position changed to OPEN or
	Item iMultimedia_Homematic_Fenster2_Position changed to OPEN or
	Item iMultimedia_Homematic_Fenster3_Position changed to OPEN

then
	....
end

So the problem is not only inside my .rules file to read it correctly. As you can see it never changes inside the sitemap so I have also problems inside my .items file.

Can you show us your Things file configuration? You don’t seem to have your Item linked to a Thing, which will be why your Item state is NULL.

I can see where my mistake is. I use the rule on a different device than the one where the corresponding Thing would be present.

On this device I use the Homematic Binding and added a thing.

Maintenance *unfold_less*

### Signalstärke

homematic:HM-Sec-RHS:MEQ0461285:LEQ1253282:0#SIGNAL_STRENGTH*content_copy*

Number

*unfold_more*

### Niedriger Batteriestatus

homematic:HM-Sec-RHS:MEQ0461285:LEQ1253282:0#LOWBAT*content_copy*

Switch

*unfold_more*

Rotary Handle Sensor *unfold_less*

### State

homematic:HM-Sec-RHS:MEQ0461285:LEQ1253282:1#STATE*content_copy*

String

*edit* *unfold_more*

### Niedriger Batteriestatus

homematic:HM-Sec-RHS:MEQ0461285:LEQ1253282:1#LOWBAT*content_copy*

Switch

I’ll have to come up with something else. My devices exchange state and command via MQTT. As you can see here.

The binding was installed on the “server” and the rule was used on the “proxy”.

but it’s a String type Item,no?

	Item iKonferenz_Homematic_Fenster1_Position changed to "CLOSED" or

It’s just getting the syntax right.

I think this should’t be the problem. Because this code works:

rule "WindowsClosed"
when
	Item iKonferenz_Homematic_Fenster1_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster2_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster3_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster4_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster5_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster6_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster1_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster2_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster3_Position changed to CLOSED
then
		// Switch lamps off
		for(var int i = 0; i < hueLampsMWBright.size(); i++){
			hueLampsMWBright.get(i).sendCommand(100)
		}
		Thread::sleep(100)
		for(var int i = 0; i < hueLampsMWColor.size(); i++){
			hueLampsMWColor.get(i).sendCommand(HSBType.WHITE)
		}
		Thread::sleep(100)
		for(var int i = 0; i < hueLampsMWToggle.size(); i++){
			hueLampsMWToggle.get(i).sendCommand(OFF)
		}
end

What I want to do is that the lights only get switched off when all windows are closed. To use AND instead of or is not right in the WHEN-Clause because you can open, tilt and close only one window at one time or does human have multiple arms?

So I added an if-Clause which should detect if there is still a window opened or tilted.

rule "WindowsClosed"
when
	Item iKonferenz_Homematic_Fenster1_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster2_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster3_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster4_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster5_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster6_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster1_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster2_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster3_Position changed to CLOSED
then
	//if(iKonferenz_Homematic_Fenster1_Position.state == CLOSED && iKonferenz_Homematic_Fenster2_Position.state == CLOSED && iKonferenz_Homematic_Fenster3_Position.state == CLOSED && iKonferenz_Homematic_Fenster4_Position.state == CLOSED && iKonferenz_Homematic_Fenster5_Position.state == CLOSED && iKonferenz_Homematic_Fenster6_Position.state == CLOSED && iMultimedia_Homematic_Fenster1_Position.state == CLOSED && iMultimedia_Homematic_Fenster2_Position.state == CLOSED && iMultimedia_Homematic_Fenster3_Position.state == CLOSED) {
	logInfo("rules", "All windows are closed")
	logInfo("rules", "Fenster 1 state {}", iKonferenz_Homematic_Fenster1_Position)
	logInfo("rules", "Fenster 1 state {}", iKonferenz_Homematic_Fenster1_Position.state.toString)

		// Switch lamps off
		for(var int i = 0; i < hueLampsMWBright.size(); i++){
			hueLampsMWBright.get(i).sendCommand(100)
		}
		Thread::sleep(100)
		for(var int i = 0; i < hueLampsMWColor.size(); i++){
			hueLampsMWColor.get(i).sendCommand(HSBType.WHITE)
		}
		Thread::sleep(100)
		for(var int i = 0; i < hueLampsMWToggle.size(); i++){
			hueLampsMWToggle.get(i).sendCommand(OFF)
		}
	}
end

But I have found the problem. If I run the rule first all states are NULL. I got something like this:

13:21:09.873 [INFO ] [.eclipse.smarthome.model.script.rules] - Fenster 1 state NULL
13:21:09.882 [INFO ] [.eclipse.smarthome.model.script.rules] - Fenster 2 state NULL
13:21:09.899 [INFO ] [.eclipse.smarthome.model.script.rules] - Fenster 3 state CLOSED
13:21:09.909 [INFO ] [.eclipse.smarthome.model.script.rules] - Fenster 4 state NULL
13:21:09.923 [INFO ] [.eclipse.smarthome.model.script.rules] - Fenster 5 state NULL
13:21:09.929 [INFO ] [.eclipse.smarthome.model.script.rules] - Fenster 6 state CLOSED

I opened window 3 and 6 and closed it.

I hoped checking if the state was closed or null would work, but sadly it doesn’t:

	if((iKonferenz_Homematic_Fenster1_Position.state == CLOSED || iKonferenz_Homematic_Fenster1_Position.state == NULL) &&
		(iKonferenz_Homematic_Fenster2_Position.state == CLOSED || iKonferenz_Homematic_Fenster2_Position.state == NULL) &&
		(iKonferenz_Homematic_Fenster3_Position.state == CLOSED || iKonferenz_Homematic_Fenster3_Position.state == NULL) &&
		(iKonferenz_Homematic_Fenster4_Position.state == CLOSED || iKonferenz_Homematic_Fenster4_Position.state == NULL) &&
		(iKonferenz_Homematic_Fenster5_Position.state == CLOSED || iKonferenz_Homematic_Fenster5_Position.state == NULL) &&
		(iKonferenz_Homematic_Fenster6_Position.state == CLOSED || iKonferenz_Homematic_Fenster6_Position.state == NULL) &&
		(iMultimedia_Homematic_Fenster1_Position.state == CLOSED || iMultimedia_Homematic_Fenster1_Position.state == NULL) &&
		(iMultimedia_Homematic_Fenster2_Position.state == CLOSED || iMultimedia_Homematic_Fenster2_Position.state == NULL) &&
		(iMultimedia_Homematic_Fenster3_Position.state == CLOSED || iMultimedia_Homematic_Fenster3_Position.state == NULL)) {

Also I tried it with == null or == 'NULL' because it was a String type.

Item states are NULL at system start time, and stay that way until they get updated with something else. Often that will be from a report from a device.

Persistence services can be used to “remember” states and restore at start-up.
That’s not always a good idea if you want to know “real” states, like here. NULL represents “don’t know yet”, which might be more useful than “it was like this in the past”.

Item states may also get reinitialized to NULL when editing Things or Items.

1 Like

It’s a String type Item. The state will never be CLOSED, which is a valid state but only for Contact type Items (this is why the rule does not error).
String type will be “CLOSED”

yourItem.state == “CLOSED”

NULL is a valid state but not a string.

yourItem.state == NULL

APPLE is neither a string nor a known system constant type.

yourItem.state == APPLE

will cause a rule error.

1 Like

Thanks mate,

I got it. I am wondering why you can write CLOSED inside a When-Clause but you have to write "CLOSED" as if statement. So following worked:

rule "WindowsClosed"
when
	Item iKonferenz_Homematic_Fenster1_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster2_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster3_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster4_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster5_Position changed to CLOSED or
	Item iKonferenz_Homematic_Fenster6_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster1_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster2_Position changed to CLOSED or
	Item iMultimedia_Homematic_Fenster3_Position changed to CLOSED
then
	if((iKonferenz_Homematic_Fenster1_Position.state == "CLOSED" || iKonferenz_Homematic_Fenster1_Position.state == NULL) &&
		(iKonferenz_Homematic_Fenster2_Position.state == "CLOSED" || iKonferenz_Homematic_Fenster2_Position.state == NULL) &&
		(iKonferenz_Homematic_Fenster3_Position.state == "CLOSED" || iKonferenz_Homematic_Fenster3_Position.state == NULL) &&
		(iKonferenz_Homematic_Fenster4_Position.state == "CLOSED" || iKonferenz_Homematic_Fenster4_Position.state == NULL) &&
		(iKonferenz_Homematic_Fenster5_Position.state == "CLOSED" || iKonferenz_Homematic_Fenster5_Position.state == NULL) &&
		(iKonferenz_Homematic_Fenster6_Position.state == "CLOSED" || iKonferenz_Homematic_Fenster6_Position.state == NULL) &&
		(iMultimedia_Homematic_Fenster1_Position.state == "CLOSED" || iMultimedia_Homematic_Fenster1_Position.state == NULL) &&
		(iMultimedia_Homematic_Fenster2_Position.state == "CLOSED" || iMultimedia_Homematic_Fenster2_Position.state == NULL) &&
		(iMultimedia_Homematic_Fenster3_Position.state == "CLOSED" || iMultimedia_Homematic_Fenster3_Position.state == NULL)) {

The handler for when clause is less picky. But will likely mess up e.g. with a space PART OPEN or with a keyword like end.
Keep your own sanity by treating strings as “strings”.

1 Like

Now that it works we can talk about some improvements.

Create a Group:String and add all of those Items, let’s call it Fensters.

Then you can change your rule trigger to just

Member of Fensters changed to CLOSED

And your if statement can become

if(Fensters.members.filter[fenster | fenster.state == "CLOSED" || fenster.state == NULL].size != 0)

It might be length instead of size, I’m going from memory.

Also, there are some cases where an Item could be set to UNDEF which is another special state like NULL. You might need to check for that as well.

1 Like