A bonus question. If multiple devices subscribe to the same event / event handler, how do I know which device (type Device) caused the event handler to be called?
parse() is not an arbitrary method name … it is a standard and required (?) method for Device Handlers, except for Cloud-Connected Device Types. It doesn’t make sense to overload “parse(String)” with an additional signature, such as “parse(Map)”
or is Paul referring to a Cloud-Connected Device (which uses a different method parseEventData(Map) in the documented example):
Devices don’t subscribe to Events, only SmartApps, according to my interpretation of the Documentation for SmartDevice Type and Device. Neither of these mentions a subscribe() method.
This question doesn’t make sense to me, because devices do not “subscribe to events”; instead, SmartApps do. And the subscription for device events is either to a specific device’s events, or the event data is returned by the subscription as an Object of type Event, which contains the ID of the Device Instance or other generator of that Event (very specifically, because Event includes the Hub and Location ID too).
Here is the caveat: I haven’t looked at this since November of last year and I believe a lot of the documentation has been improved since.
In SmartThings, a motion sensor generates two event types: “active” and “inactive”. However, the Philio (Zipato) motion sensor only generates a single event “motion detected”. In Z-Wave terms, it generates a “command: 3003, payload: FF 0C”, but never a “command: 3003, payload: 00 0C”.
I have a helper app which subscribes to the events of motion sersor device handler.
The helper app sends an inactive event to the device handler. The device handler has an overloaded parse(map) defined.
// Device Handler
def parse(Map evt) {
def result = [];
if (evt)
result << evt;
return result
}
Do I like it? Not really. But I wasn’t able to figure out how to get it working in any other way.
1 Like
tgauchat
(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy)
7
Thanks for the followup, Paul – It looks like you found a creative workaround to a sticky situation. Such things are something inelegant but if it works … it works, right?
There’s always a possibility that fresh eyes might come up with an alternative way to handle this. and/or
Your solution may be helpful in similar situations!!!
If you would like to share the entire code (SmartApp and Device Handler) with paste or a Github link … then see what feedback arises. I’m not sure how much I can do without the actual device to test with … though I suppose the Simulator can be configured to send a representation of the single Motion Detected Event as if from the physical device…
BTW: That seems like unusually sloppy behavior for a motion sensor, right? Did you come up with any explanation? I suppose that typical motion sensors send “inactive” after a certain timeout period, and that triggers the “inactive” event message; whereas Philio must still have this concept of timeout – since it needs to decide whether or not to send the next “active” event message; it’s just too lazy to send the “inactive” in between. Is my understanding correct?
So I’m wildly speculating whether or not this concept of timeout could be included in the Device Handler without a helper SmartApp. If you can’t call the parse() method directly, wouldn’t it be sufficient to call sendEvent() from within the Device Handler after some “pause” amount? Yet the Device Handler exits after the platform calls parse() for the “active” message… we’d have to inhibit that or spawn another process… Can a DeviceHandler call “runIn()”? Is there an execution time limit like for SmartApps?
I really dislike the idea of having to run a helper app to solve this problem. It is not efficient and you have to manage an additional SmartApp.
I tried to create both the “active” and “inactive” events in the device handler, but at times those events would be handled out of order and I couldn’t figure out how to create a delay.
I am not sure whether to call it “sloppy”; maybe a different philosophy. The manual explicitly specifies this behavior and considering that the motion sensor can be configured for different modes with different behaviors there must have put quite some thought in the design.
tgauchat
(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy)
9
I’m not sure I’m as concerned about the use of the helper SmartApp in the solution. It is almost intuitive: Most Motion Sensors report a “inactive” sometime after reporting “active”. In the case of the Zipato, there is no “inactive” message, so you need something to send this message. Devices can’t directly interact with other Devices (unless they are Child Devices of the same Parent (?) – and that would involve a Service-Manager SmartApp; i.e., a helper SmartApp; anyway… so essentially the same solution components, just even more complicated.
At first I thought this must be like a Capability “Momentary”; since a Momentary doesn’t have any Attributes; it just fires a State change (?!). That would be like firing the “active” Motion detected event. The Virtual sample code for Momentary, though, makes it a Switch as well, and just does an immediate reset with no time delay; the Z-Wave sample, though, expects an “on” and “off” message from the Device like a Switch (i.e., while it is not “pushed = on, unpushed = off”; but rather “pushed = on and then immediately off” … there are two distinct messages from the device).
So if avoiding the use of a helper SmartApp is desired, the challenge is figuring out what sort of synchronous sequencing and any delays are necessary and possible within a single Device Handler. The “out of order” stuff you encountered is not unexpected and unless someone has already solved it, it would take some creative experimentation and/or expert help to solve.
This is a good one for @Mager to think about and increase his expertise!