Here is how I approached it in my setup. I’m using some Bluetooth detectors instead of PIRs but the concept is the same.
I make all of my presence detectors to be Switches.
I put all my presence detectors into a gPresence Group
In your case I would probably create a Proxy switch for your motion sensors and create a Timer to switch the Switch from ON to OFF after a certain period of time so that a PIR going to OPEN lasts longer than the sensor would report. I’ve seen five minutes be pretty common timeout. See @bob_dickenson’s posting about Proxy items here. for an example.
I think this is far better than polling.
Then you can create a rule that triggers on updates to gPresence and if all the member switches are OFF switch a Present swtich Item to OFF. You can use a timer here as well so all the gPresence switched have to be off for five minutes before switching the main Present swtich to OFF to cover cases like going to check the mail.
Rules that care about your presence would refer to the state of Present.
Here are my rules (they don’t include the proxy idea mentioned above, see the link for an example of that) for reference. NOTE: these rules are the result of almost a year’s worth of learning. My original rule was over 300 lines lone and didn’t really work very well.
Items:
Switch Present "Someone is Present" <present> // turns off 5 minutes after everyone leaves
Group gPresent "Present group" <present>
Group gRichPresent "Rich Present" <present>
Group gWifePresent "Wife Present" <present>
// Used to tell if a client is reconnected
Switch S_V_RichPhoneIP <network> (gRichPresent, gPresent) { nh="192.168.1.102" }
Switch S_V_RichChimeraBT <bluetooth> (gRichPresent, gPresent, gChimeraSensors) { mqtt="<[mosquitto:presence_sensors/bluetooth/chimeraRich:state:default]" }
Switch S_V_RichGarageaBT <bluetooth> (gRichPresent, gPresent, gGarageSensors) { mqtt="<[mosquitto:presence_sensors/bluetooth/garageRich:state:default]" }
Switch S_V_RichHydraBT <bluetooth> (gRichPresent, gPresent, gHydraSensors) { mqtt="<[mosquitto:presence_sensors/bluetooth/hydraRich:state:default]" }
Switch S_V_WifePhoneIP <network> (gWifePresent, gPresent) { nh="192.168.1.103" }
Switch S_V_WifeChimeraBT <bluetooth> (gWifePresent, gPresent, gChimeraSensors) { mqtt="<[mosquitto:presence_sensors/bluetooth/chimeraWife:state:default]" }
Switch S_V_WifeGarageBT <bluetooth> (gWifePresent, gPresent, gGarageSensors) { mqtt="<[mosquitto:presence_sensors/bluetooth/garageWife:state:default]" }
Switch S_V_WifeHydraBT <bluetooth> (gWifePresent, gPresent, gHydraSensors) { mqtt="<[mosquitto:presence_sensors/bluetooth/hydraWife:state:default]" }
Rule:
import org.openhab.model.script.actions.*
var Timer presenceTimer = null
rule "gPresent changed"
when
Item gPresent received update
then
val isPresent = gPresent.allMembers.filter(s | s.state == ON).size > 0
// Someone came home
if(isPresent && Present.state != ON) {
logInfo("Presence", "Someone is home")
if(presenceTimer != null) {
presenceTimer.cancel
presenceTimer = null
}
Present.sendCommand(ON)
}
// Everyone is gone
else if(!isPresent && Present.state != OFF) {
logInfo("Presence", "No one is home, setting timer")
if(presenceTimer != null) {
presenceTimer.cancel
}
presenceTimer = createTimer(now.plusMinutes(5), [|
logInfo("Presence", "No one is home after five minutes")
if(Present.state != OFF) Present.sendCommand(OFF)
])
}
end
NOTE: If you indent your lines by four spaces it will treat your lines as code which makes it soooo much easier to read postings with code.