Having Issues With Motion Events Collection

I'am having issues collection motion events using Aeon Multisensor Gen 6 because, using the code bellow, it collects all events, including temperature, humidity, etc. while it is set in settings only as a motion sensor so I'd assume it should not register any other events that the ones is subscribed to. However, judging by the events log of the device itself, it appears that the integer value corresponds exactly to the number of ALL events that this device parsed, not just motion events as I would have expected it.

Can someone help me and let me know what I'm doing wrong int this collection? Let me know if you need more context.

Note: in this instance I'm using only 1 device, so the iteration is not what causes the issue.

boolean stillActive()
{
    int events = 0
    def thisDeviceEvents = []
    boolean result = true // default is true  always return Active = true when no sensor is selected by the user

    if(motionSensors)
    {
        logging("motion test is running and collecting events at $motionSensors")
        long deltaMinutes = noMotionTime * 1000 * 60   
        int s = motionSensors.size() 
        int i = 0

        for(s != 0; i < s; i++) // if any of the sensors returns at least one event within the time threshold, then return true
        { 

            thisDeviceEvents = motionSensors[i].eventsSince(new Date(now() - deltaMinutes), [max:100]) }.flatten() // collect events for each sensor
            events += thisDeviceEvents.size()
        }

        result = events >= 1 // loop breaks when 1 sensor returns more than 0 event, so see if that's the case here

    } 

    log.info "motion returns ${result} with $events events in the last $noMotionTime minutes"
    return result
}

Firstly, it appears you are trying to aggregate multiple motion sensors to act as one sensor. If so, there is an app built into Hubitat for this. It's called Zone Motion Controller. Chances are it will do what you need.

With regard to your code. You are collecting the eventsSince of the device. This will collect ALL events from the device. It does matter what capability you used to select the device as that is basically just to filter your choices in the drop-down. Once the device is chosen from the input, you have access to all it's functions and attributes. If you want to use motion events only you would have to subscribe that those specific events and apply your logic there.

Eg.

subscribe(motionSensors, "motion", motionHandler)

You could then insert some logic into to motionHandler() method. Maybe set a state variable to a timestamp when motion=active and use that as your lastMotion time.

There is probably a way to also filter the eventsSince() results as well but I have never tried and I'm not at my PC to test options.

2 Likes

Right after posting the above I remember I did in fact filter eventssince once in a button device driver I worked on. Here is a snippet of the code.

def processEvent(type){
    def recentEvents = device.eventsSince(new Date(now() - 5000)).findAll{it.name == type}
        log.info recentEvents.size
        if(recentEvents.size == 0){
        	sendEvent(name: type, value: "1", descriptionText: "${device.displayName} button 1 was ${type}", isStateChange: true, displayed: true)
            log.info "${device.displayName} Button 1 ${type}"
        }
    else {log.debug "Likely redundant event detected. Discarding second ${type} event."}
    
}

In your case you could filter with
it.name=="motion"

1 Like

Thanks. Figured it might be the reason but I was kind of "sure" I could use it that way before. I guess it is because I was using motion sensors that returned no other events.

I don't know why I had this collection in my code, actually. Now that I took it out and replaced it with a simple findAll(), I can call it.value == "active". Thank you so much!

In fact, I still have not been able to completely resolve this issue, beside using the event handler, which is far from ideal as a solution instead of event collection.

Using this:

   long tB4 = now()
        log.warn "tB4 = $tB4"

        for(s != 0; i < s; i++) 
{ 

  thisDeviceEvents = motionSensors[i].eventsSince(new Date(now() - deltaMinutes)).findAll{it.value == "active"} // collect motion events for each sensor separately
events += thisDeviceEvents.size() // aggregate the total number of events

}

        double elapsed = (now() - tB4)/1000/60
        log.info "motion events collection took $elapsed seconds for $i devices"

this code still considerably slows the whole platform. I have run the test countless times now, using a flashing light command. Every time I comment out the event collection, the light that serves here as a test, flashes consistently and, on the other end, every time I un-comment the event collection line of code, the flashing starts lagging again and everything becomes much less responsive, increasingly less responsive.

Maybe @bravenel could look into it quickly and let me know what sense to make of this. (complete code can be found here: CODE