I have a few questions about things - or maybe I’m just thinking too complicated 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
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?
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.
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.
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.