Multiple device subscriptions


(Paul) #1

Hey smarter SmartAppers,
When I subscribe to actions from multiple devices, I get calls on my event handlers every time any one of those devices triggers that event. For example:

preferences {
	section("Multiple open close"){
	input "contacts", "capability.contactSensor", multiple: true
	}
}

subscribe(contacts, "contact.closed", contactClosedHandler)

contactClosedHandler gets called every time any one of my contact sensors closes.

Is there an easy way to limit the subscription so contactClosedHandler only gets called when all of the contact sensors are closed? So far, I’ve been checking the state of all of the contact sensors whenever contactClosedHandler is called, but it would be nice if there was an easier way.

Thanks!


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #2

I don’t think there is a way. Checking each time is probably the best you can do.

But watching here for other ideas…


(John S) #3

The typical pattern for checking for all is to use devicemap.find{it.attribute == “value”} == null

so for example, if I have multiple motion sensors, this function returns true if ALL of them are not showing motion:

def isActiveMotion() {
    // check all the motion sensors, make sure none are active
    def noMotion = motionSensors.find{it.currentMotion == "active"} == null
    !noMotion        
}

(Tim Slagle) #4

This is what I use to check for multiple contact statuses :smile:

This will return true if non of the contacts in the set have a “latest value” of “open”… AKA they are all closed… You can also remove the “!” from the contain statement to return true if one of the contacts is open. Dealers choice.

private getDoorsOk() {
	def result = !doors || !doors.latestValue("contact").contains("open")
	log.trace "doorsOk = $result"
	result
}

After you set this up the way you want it you can do something like this…

if(doorsOk){
      //do this thing
      //This is basically saying "if true" then do it
}

(Paul) #5

Tim and John, these are both really helpful. I have been basically achieving the same result with more words… of course both of your suggestions are more elegant :smile:

Essentially I’m trying to build an app that treats a group of contact sensors as if they were wired in series. It’d be neat if there was a way to modify the subscription to only fire when all of the sensors reported that state:

subscribe(contacts, "contact.closed", contactClosedHandler, modifier: allTogetherNow)

Or only fire when the first sensor in a group reported that state (and only fire again once all sensors had reset):

subscribe(contacts, "contact.open", contactOpenHandler, modifier: onlyTheFirst)

Which would save a little time having to put logic into the app every time you want this sort of functionality. But hey, then I’d never get to talk to you fine people.

Thanks again,
~P


(Scott G) #6

Sounds like getting access to the native groups in the Lights/Switches, Damage/Danger, Motion, etc… sections would make this easier. They usually show “on” when one is on and “off” only when all are off (substitute motion/inactive for on/off and the like).


(Paul) #7

It’s true that could be helpful to have access to the native groups. However, I try to avoid making groups as much as possible so the ones I do make are easily accessible.