I’m trying to create a rule that will determine if I am home alone for a prolonged period.
So I’m looking for any member of gPresence except Vanja and checking if it changed since 3 days.
rule “Single Mode”
when
Item Presence changed
then
if ( gPresence.allMembers.exists
[ i | !i.name.contains(“Vanja”) && i.changedSince(now.minusDays(3)) ] )
{SingleMode.sendCommand(OFF)}
else
{SingleMode.sendCommand(ON)}
end
I tried different variations, but always getting
Validation issues found in configuration model 'staging.rules', using it anyway:
There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures into a typed context.
edit: nevermind, the error stopped, after various editing sessions…still not sure if the rule works though
I’ve never used exists on a List in Rules DSL before. Hopefully it’s something real and not something ChatGPT made up. If you are not getting errors I would assume it’s real.
If it isn’t real or doesn’t do what is expected, you can use filter and size.
This error usually means that at compile time there is no enough information in the code to figure out the types of the arguments to the anonymous function (i.e. the stuff between [ ]. It’s going to try to use the function anyway, as the warning says and there may not be an error when it runs.
But you can fix such errors by helping the parser and compiler know the type of the arguments. In this case by telling it that i is of type GenericItemwhich is the parent of all Item types.
if ( gPresence.allMembers.exists
[ GenericItem i | !i.name.contains(“Vanja”) && i.changedSince(now.minusDays(3)) ] )
Before you got and add type to every thing, beware that usually Rules DSL punishes you when you do that. So be selective and only set the type where you really need to and let it figure out the type on it’s own in all other circumstances.
yeah, i started with filter but it suggested exists as it will allegedly stop at the first item it finds to satisfy the condition, as I don’t care if multiple items are found.
It also suggested to use that generic item to solve the error, but eventually the error disappeared. I used wrong(non existent) group name, but instead of saying no such item, dsl gave the error above. when it finally spit out the correct error, i changed the group name and no more errors of any kind, so i didnt use the generic item, and it seems the rule works so far.
Oh, another approach that could work would be to assign COUNT as the aggregation function of the Group. Then you can just check the state of the Group without using filter or exists. But I think that is only easy to do if the gPresence Group members have a state and it’s not a Group of Groups whose members have state.
You’d check to see if the state > 1, since you don’t want to include yourself.
would not that logic be flawed if he was gone and 2 other members of the group are present?
To make that really valid it would have to be specific to his presence being true and one or more other presences also being true I would think.
I would assume there would be a check in the rule to test for that.
I was only really referencing the iteration over the members of the Group, not the whole rule.
If this were a UI rule, I’d just add a simple condition so the rule only runs when Vanja is not home. Since it’s not, I’d include it in the if statement
But this does raise a potential logic problem I didn’t see before.
The rule triggers when Presence changed. I think this rule will only run and command SingleMode to ON if Vanja just came home and no one else has been there for three days. If Vanja is there and present for three days after everyone else leaves, there’s nothing to trigger the rule so SingleMode never gets commanded to ON.
If a long delay between when SingleMode should be turned on and when it actually is turned on every does become a problem, there are a couple of easy approaches.
trigger the role with a cron trigger maybe over an hour or so
Set a timer when everyone is gone but you to turn on SingleMode after three days. If someone comes back before the river goes off cancel it and set SongkeModel to OFF.
I didn’t normally advocate for polling solutions like 1, but I’m also cautious about timers that take more than a day to run. So I would probably choose option 1. As a bonus all you need to change in the code is the role trigger.
Well, I have a similar rule where house should realize everyone went for vacation and switch on VacationMode. It happens if there was no change of Presence group for 2 days.
If I dont want to wait for 2 days, I can always enable it manually while driving to the airport…
I apply the same logic for single mode, If I don’t want to wait 3+ days I can always enable it manually…
These rules are more like a fuse - in case I forget, it will happen sooner or later anyway
This is the nature of these events - they are not really instant or timely…
I could run them every time a TimeOfDay changes, or every morning, to expedite the execution, but the fact remains they will never activate as fast as manual human input would…