Hubitat-Combined-Presence
Hubitat-Combined-Presence copied to clipboard
Bug in departed/arrived mode
Hi, I think you had a bug in the presenceEventHandler for the Advanced Instance. In your code the "newPresence" was evaluated outside of the "if (!oldPresence) ....." block. Right above that if statement you initialize newPresence as false. Then, by evaluating newPresence outside of the "if (!oldPresence) ....." block, if there is a change to an included Presence device, it will always mark the combined presence device as "departed". I changed the code and tested it in my scenarion to this:
def presenceChangedHandler(evt) { log "PRESENCE CHANGED for: ${evt.device.name}" //log.debug groovy.json.JsonOutput.toJson(evt)
def oldPresent = outputSensor.currentValue("presence") == "present"
log "oldPresent: ${oldPresent}"
if (!oldPresent) {
def anyHaveArrived = false
inputSensorsArrivingOr.each { inputSensor ->
if (inputSensor.currentValue("presence") == "present" && inputSensor.name == evt.device.name) {
log "ARRIVED: ${inputSensor.name}"
anyHaveArrived = true
}
}
def allHaveArrived = inputSensorsArrivingAnd && inputSensorsArrivingAnd.size() > 0
inputSensorsArrivingAnd.each { inputSensor ->
if (inputSensor.currentValue("presence") != "present") {
allHaveArrived = false
}
}
if (anyHaveArrived || allHaveArrived) {
outputSensor.arrived()
log "${outputSensor.displayName}.arrived()"
if (notifyAboutStateChanges) {
sendNotification("Arrived: ${outputSensor.displayName}")
}
}
}
else
{
def anyHaveDeparted = false
inputSensorsDepartingOr.each { inputSensor ->
if (inputSensor.currentValue("presence") != "present" && inputSensor.name == evt.device.name) {
log "DEPARTED: ${inputSensor.name}"
anyHaveDeparted = true
}
}
def allHaveDeparted = inputSensorsDepartingAnd && inputSensorsDepartingAnd.size() > 0
inputSensorsDepartingAnd.each { inputSensor ->
if (inputSensor.currentValue("presence") == "present") {
allHaveDeparted = false
}
}
if (anyHaveDeparted || allHaveDeparted) {
outputSensor.departed()
log "${outputSensor.displayName}.departed()"
if (notifyAboutStateChanges) {
sendNotification("Departed: ${outputSensor.displayName}")
}
}
}
}
I've analyzed it and I believe your code is functionally identical to mine, with the exception that mine can call outputSensor.arrived() and outputSensor.departed() repeatedly. This should not be a problem though - calling arrived() on a present sensor (or departed() on a not present sensor) does not cause a state change in that sensor.
Or did I misunderstand your comment? Thanks for the feedback!