I’m fighting with a problem that I don’t understand. Added a lot of debug code, but it won’t work.
// presence.items
Switch Presence "Anwesenheit" <presence> (gHome)
// presence.rules
rule "Presence Control - Set Presence"
when
Member of gPresenceControl changed
then
var presence_state = gPresenceControl.members.map[state].reduce[ result, v |
if (v == ON) {
return ON
} else {
if (result == ON) {
return ON
} else {
return OFF
}
}
]
if (presence_state == ON) {
logInfo("Develop","ON")
} else if (presence_state == OFF) {
logInfo("Develop","OFF")
} else {
logInfo("Develop","Something Else")
}
if (Presence.state == presence_state) return;
Presence.sendCommand(presence_state)
end
The result of this rule is the following exception:
2018-11-01 11:42:12.889 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Presence Control - Set Presence': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null
But when changing Presence.sendCommand(presence_state) to Presence.sendCommand(ON) it works.
I’m not sure if it meets your specific requirements, but there is a generic approach to presence detection.
I think you are trying to see if any member of gPresenceControl is ON, correct? If so then you need no code at all and can use
Group:Switch:AND(OFF,ON) gPresenceControl
That will set the state of gPresenceControl to OFF is ALL of its members are OFF and ON if any one of them is not OFF.
Then your Rule completely goes away and you can just use gPresenceControl in place of Presence everywhere.
If you want to do some other logic, such as waiting before setting Presence to OFF just in case you, for example, go check the main and are only away for a few minutes, see the link above.
And for completeness, better ways to find out if there are any members of gPresenceControl that are ON without relying on the Group would be
val presence_state = if(gPresenceControl.members.filter[ s | s.state == ON ].size > 0) ON else OFF
I believe a cleaner way to do it using map/reduce would be
val presence_state = gPresenceControl.members.map[state].reduce[ result, v |
if(result == ON) ON
else if(v == ON) ON
else OFF
]
But the one liner filter is more appropriate and the ability to eliminate the Rule entirely is even better.
This is kind of related to the other thread we had as well. The Rules DSL is differently structured and there is a whole lot that it looks like you are trying to do in Rules that don’t have to be done in Rules if you use Groups.