Thing questions

Hi,

I have a few questions about things - or maybe I’m just thinking too complicated :wink: Here’s my scenario:

I have two IKEA Tradfri bulbs; sometimes, their thing state change to OFFLINE - I think my gateway’s location is not that ideal. That’s why I’d like to catch the thing state of my bulbs, so I can get a “lost bulb”-warning and my rules can depend on it. But I found no possibility to depend my rule on a thing’s state as there is no possibility for AND conditions in when - is that right? I mean something like the following:

rule "Schalte Licht"
when
  Bewegungsmelder_1 changed from OFF to ON and
  Thing "tradfri:0100:ikea1:65539" is ONLINE
then
  ...

So sad. As a working solution I created “helper switch items” such like Tischleuchte_Reachable with two rules associated:

rule "Tischleuchte offline"
when
  Thing "tradfri:0100:ikea1:65539" changed to OFFLINE
then
  Tischleuchte_Reachable.sendCommand(OFF)
end
rule "Tischleuchte online"
when
  Thing "tradfri:0100:ikea1:65539" changed to ONLINE
then
  Tischleuchte_Reachable.sendCommand(ON)
end

As said: it’s a working solution, but it’s not sexy as I have to setup these online-offline-magic-rules separate for each thing. I’m looking for a more compact solution which is better to maintain. I thought about a construct like this:

rule "Offline Things"
when
  Thing "bla" changed to OFFLINE or
  Thing "fasel" changed to OFFLINE (...)
then
  // determine the triggering thing
  // do anything related

But there seems no easy way to determine a triggering item; the only approach I’ve found is the way over Groups, respectively performance data (which group member changed its state in the last 1 second?). But as far I can see

  • it is not possible to put a thing in a group and
  • things don’t write performance data

:smiley:

How could I solve this concern? At the beginning I thought “how hard can it be?”, and now I’m stuck with big question marks over my head. Can some of you give me an idea?

Thanks a lot in advance!

Cheers,
Marianne

you could always add a item for each bulb and put all of them in a Group. You can then configure the Group to be “OFFLINE”, if one of its item is offline. And in a rule for the Group being OFFLINE you can iterate through all items and take actions on the OFFLINE one.

Group:Switch:OR(OFFLINE, ONLINE)	gLights		"Alle Tradfris"	(All)

Hint: I did not test “ONLINE” and “OFFLINE”, perhaps you have to play with this one… it works for me with ON/OFF

For your rule, it would be something like:

rule "Tradfri Offline"
when
	Item gLights changed to OFFLINE
then
	gLights.members.forEach[tradfri|
		if (tradfri.state == 'OFFLINE') {
			// do your stuff 
		}
	]
end

…but still - that doesn’t solve your issue? what do you do, if you get somehow an alert, your bulbs are OFFLINE? You can’t do anything about it, can you?
From what I understand you need to optimize the location of your gateway. If possible, I would put the gateway in a better position and spare me the hassle.

That is correct. Rule triggers are events. You will never receive the ON/OFF event and ONLINE events from those two triggers at the same time so it makes no sense for an and in Rule triggers.

I’m not sure if there is a good way to go about this. One hacky way I can think of is to:

  • put each Thing ID into a text file, one ID per line

  • trigger the Rule like you describe, one trigger for each Thing going OFFLINE

  • load and parse the file into a List with

    val things = executeCommandLine(“cat /path/to/things.txt”, 1000).split("\n")

  • create a .map file mapping the “Reachable” Item with the Thing ID

  • put your Reachable Items into a Group

  • iterate over the Things that are OFFLINE and process the fact that they are OFFLINE

val message = new StringBuilder()
message.append("The following Tradfri lights are OFFLINE")
things.filter[id | ThingAction.getThingStatusInfo(id).getStatus() == "OFFLINE"].forEach[id |
    message.append(id+",")
    val reachable = gReachables.members.findFirst[ r | r.name ==  transform("MAP", "reachable.map", id]
    if(reachable.state != OFF) reacahble.sendCommand(OFF)
]
logInfo("lights", message.toString)

It is ugly and depends on a lot of external stuff but the code is at least pretty short and you can add/remove Things by changing the text file instead of modifying Rules.

Dear @rlkoshak,

thank you very much for your very detailed answer!
In fact ThingAction.getThingStatusInfo(id).getStatus() did the trick for me - not that way via an extra file and split, but I think I’m now able to understand the concepts.

Thanks again! :green_heart: