Registering device events in a plugin

Posted on
Mon Jun 22, 2020 8:36 am
jheddings offline
User avatar
Posts: 149
Joined: Dec 01, 2013
Location: Denver, CO

Registering device events in a plugin

I have been looking into alternatives for the polling loops I end up using in most of my plugins... One thing that could help would be registering for device state changes internally, rather than a visible Trigger in Indigo. Effectively, it would be a simple callback registered for a device that allows another plugin to see state changes.

I've been using the EventHook example in several other Python projects, which is very effective for this kind of thing. I'm sure there are other ways to handle this in Indigo, just throwing it out as an example of what I'm looking for.

So a simple use could be:

Code: Select all
# plugin.py

    def deviceStartComm(self, device):
        device.onStateChange += self.deviceStateChanged

    def deviceStateChanged(device, stateName):
        self.logger.debug('State Change: %s[%s] => %s', device.name, stateName, device.states[stateName])



Any thoughts on such a thing?

Posted on
Mon Jun 22, 2020 9:45 am
FlyingDiver offline
User avatar
Posts: 7211
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: Registering device events in a plugin

If you do this in your startup():
Code: Select all
        indigo.devices.subscribeToChanges()


Then you can do something like:

Code: Select all
    def deviceUpdated(self, oldDevice, newDevice):
        indigo.PluginBase.deviceUpdated(self, oldDevice, newDevice)

        for masqDeviceId, masqDevice in sorted(self.masqueradeList.iteritems()):
            baseDevice = int(masqDevice.pluginProps["baseDevice"])
            if oldDevice.id == baseDevice:
                self.updateDevice(masqDevice, oldDevice, newDevice)


Or am I misunderstanding that you're wanting to do?

joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177

Posted on
Mon Jun 22, 2020 10:12 am
jay (support) offline
Site Admin
User avatar
Posts: 18212
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Registering device events in a plugin

Yep, I think you want subscribeToChanges() so that your deviceUpdated method gets called for every device that has a change. You can then decide if the change is one you're interested in or not.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Mon Jun 22, 2020 10:40 am
jheddings offline
User avatar
Posts: 149
Joined: Dec 01, 2013
Location: Denver, CO

Re: Registering device events in a plugin

Good pointer... That is along the lines of what I was trying to do. Now I need to think about how it fits in my plugin architecture :)

Posted on
Mon Jun 22, 2020 10:42 am
FlyingDiver offline
User avatar
Posts: 7211
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: Registering device events in a plugin

jheddings wrote:
Good pointer... That is along the lines of what I was trying to do. Now I need to think about how it fits in my plugin architecture :)


I'm confused about something - from your original code post, it looks like you're trying to catch changes to states for the plugin's own devices. Since the ONLY thing that can change the states of a plugin device is the plugin itself, why do you need this in the first place? Do you have deferred processing you need to do after devices have changed?

joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177

Posted on
Mon Jun 22, 2020 11:51 am
jheddings offline
User avatar
Posts: 149
Joined: Dec 01, 2013
Location: Denver, CO

Re: Registering device events in a plugin

Yeah, that was a simple example just to demonstrate a trivial case, but doesn't model what my plugin is doing...

A better example would be:

Code: Select all
<!-- Devices.xml -->
    <Name>Master Controller</Name>
    <ConfigUI>
      <Field type="list" id="devices">
        <Label>Remote Devices:</Label>
        <List class="indigo.devices" filter="indigo.dimmer"/>
      </Field>
    </ConfigUI>


Code: Select all
# plugin.py
    def deviceStartComm(self, device):
        for remoteDevice in device.pluginProps['devices']:
            # set up event hook for device state changes
            remoteDevice.onStateChange += self.deviceStateChanged

    # custom event hook for device state changes
    def deviceStateChanged(device, stateName):
        self.logger.debug('State Change: %s[%s] => %s', device.name, stateName, device.states[stateName])


I'm still playing around with subscribeToChanges() to see if I can make it work for this case. In my case, each custom device is watching for only the external devices it cares about, not so much the devices created by the Plugin.

Posted on
Mon Jun 22, 2020 1:18 pm
jay (support) offline
Site Admin
User avatar
Posts: 18212
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Registering device events in a plugin

That's exactly what the Virtual Devices interface does for it's devices (and many of the other plugins that do that kind of thing). The plugin maintains a list of devices for which changes are important (built and maintained during deviceStartComm and deviceStopComm). It subscribes to changes, then in the deviceUpdated method looks at the device to see if it's one it cares about. If so, it does whatever work is necessary. If not, it just passes.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Mon Jun 22, 2020 11:58 pm
jheddings offline
User avatar
Posts: 149
Joined: Dec 01, 2013
Location: Denver, CO

Re: Registering device events in a plugin

Thanks for the help, gents. I've added basic support for device changes to my plugin framework and will use that going forward. I'd still like to improve it a bit for capturing specific events, but that may come at a later time :)

In case you are curious, here is the base I usually use for building plugins:
https://github.com/jheddings/indigo-iplug

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 2 guests