Developing a plug-in for a custom hardware solution

Posted on
Mon Mar 26, 2018 7:55 am
boisy offline
User avatar
Posts: 273
Joined: Jun 25, 2013

Developing a plug-in for a custom hardware solution

Hi everyone,

I'm taking a stab at developing an Indigo plug-in for an alarm system that I have setup using an Arduino.

The Arduino has an ethernet shield and monitors the state of a door. When the door state changes from open to close or vice versa, the Arduino will send the new state in a small JSON payload via multicast UDP.

I'm using (taken from the SDK examples that I downloaded). The way that I have things setup currently in plugin.py

1. deviceStartedComm() contains the code to setup the socket and multicast port
2. runConcurrentThread has been modified to call the sock.recv() function which blocks waiting for broadcast data to arrive.

My question: is it ok for the runConcurrentThread function to block waiting on data?

Posted on
Mon Mar 26, 2018 8:02 am
DaveL17 offline
User avatar
Posts: 6753
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Developing a plug-in for a custom hardware solution

A lot of us find that it's best to start an independent thread when doing stuff like this because it leaves the main plugin thread free to communicate with Indigo.

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Mon Mar 26, 2018 8:16 am
FlyingDiver offline
User avatar
Posts: 7213
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: Developing a plug-in for a custom hardware solution

boisy wrote:
My question: is it ok for the runConcurrentThread function to block waiting on data?


Short answer is no. If nothing else, you want to be able to shut down the plugin cleanly.

Rolling your own isn't too hard, or you can use a framework like Twisted.: http://twistedmatrix.com/trac/

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

Posted on
Mon Mar 26, 2018 8:54 am
jay (support) offline
Site Admin
User avatar
Posts: 18216
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Developing a plug-in for a custom hardware solution

Note that twisted is no longer included in macOS python (I have no idea why). But using the various threading classes directly in Python are quite easy.

You can also use socket.settimeout() which will timeout the recv attempt and give the plugin a chance to see if it's been told to shutdown. I think you can also use socket.select() in the runConcurrentThread method though I've personally never tried it. (short timeouts are best because longer ones will make Indigo think the plugin has hung up).

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Mon Mar 26, 2018 10:16 am
kw123 offline
User avatar
Posts: 8363
Joined: May 12, 2013
Location: Dallas, TX

Re: Developing a plug-in for a custom hardware solution

I had an arduino uno running for 3 years attached to my 25 year old alarm system Essentially reading the input voltages from he door/ window sensors sensors. And answering get http messsges Then reading the gpios every second through url/ Ethernet from indigo. It did not fail once in 3 years!!




Sent from my iPhone using Tapatalk

Posted on
Tue Mar 27, 2018 9:41 pm
boisy offline
User avatar
Posts: 273
Joined: Jun 25, 2013

Re: Developing a plug-in for a custom hardware solution

Thanks everyone. After some work, I've got my plug-in running! The only thing is that when stopping the plug-in, Indigo must still "force quit" it, even though I'm using select. I'm not sure why this is happening, as the call to recv() doesn't happen unless there is data from the select call. I'm not a python expert, but I would think that the select call, which waits up to 1 second if there is no data ready on the socket, wouldn't interfere with the attempt to stop the thread. Can anyone comment on my approach below?

Code: Select all
 
def runConcurrentThread(self):
                try:
                        while True:
#                               self.debugLog(u"waiting...")
                                ready = select.select([self.sock], [], [], 1)
                                if ready[0]:
                                        data = self.sock.recv(self.multicastPort)
#                                       self.debugLog(data)
                                        for dev in indigo.devices.iter("self"):
                                                if not dev.enabled or not dev.configured:
                                                        continue

                                                tag = dev.pluginProps.get("tag", "d")
                                                parsed_json = json.loads(data)
                                                self.processTag(dev, tag, parsed_json)

                except self.StopThread:
                        pass    # Optionally catch the StopThread exception and do any needed cleanup.

Posted on
Wed Mar 28, 2018 3:56 am
DaveL17 offline
User avatar
Posts: 6753
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Developing a plug-in for a custom hardware solution

Try sticking a self.sleep() in at the end ; even if it's just for a half second or second.

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Wed Mar 28, 2018 6:22 am
matt (support) offline
Site Admin
User avatar
Posts: 21416
Joined: Jan 27, 2003
Location: Texas

Re: Developing a plug-in for a custom hardware solution

Dave is right – add self.sleep() to the While loop and it will check to see if the plugin is trying to shutdown (which will cause it to throw the exception).

Image

Posted on
Wed Mar 28, 2018 7:22 am
boisy offline
User avatar
Posts: 273
Joined: Jun 25, 2013

Re: Developing a plug-in for a custom hardware solution

That did it! Thanks guys.

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 2 guests

cron