Hubitat-Combined-Presence icon indicating copy to clipboard operation
Hubitat-Combined-Presence copied to clipboard

Bug in departed/arrived mode

Open abarnas opened this issue 6 years ago • 1 comments

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}")
		}
    }
}

}

abarnas avatar Nov 02 '19 07:11 abarnas

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!

joelwetzel avatar Nov 06 '19 13:11 joelwetzel