1

I was making a python script for home automation using Adafruit IO as a conduit between IFTTT and the Raspi, and it works great for a while. But after a few hours, it just stops working. I have no monitor connected, as the raspi is mounted to my wall. Below is my code:

import time
import RPi.GPIO as GPIO
import os
from Adafruit_IO import *
from Adafruit_IO import MQTTClient

clear = "CLEAR"

ADAFRUIT_IO_USERNAME = "ADAFRUIT IO USERNAME"
ADAFRUIT_IO_KEY = "ADAFRUIT IO KEY"

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(18,GPIO.OUT)
GPIO.setup(17,GPIO.OUT)
GPIO.setup(23,GPIO.OUT)
GPIO.setup(24,GPIO.OUT)
GPIO.setup(25,GPIO.OUT)

def connected(client):
    client.subscribe('welcome-feed') #may need to change this feedname later
    print "Connected!"
    client.publish('welcome-feed', clear)
    client.publish('welcome-feed', clear)   
    time.sleep(1.5)

def disconnected(client):
    print 'Lost connection to server!'
def message(client, feed_id, payload):
    if payload == "LIGHT" :
        print "LIGHT command received from IFTTT."
        print "LIGHTS TOGGLED!"
        time.sleep(0.2)
        GPIO.output(17,GPIO.HIGH)
        time.sleep(0.1)
        GPIO.output(17,GPIO.LOW)
    elif payload == "FAN_LOW" :
        print "FAN SPEED SET TO LOW!"
        time.sleep(0.2)
        GPIO.output(18, GPIO.HIGH)
        time.sleep(0.1)
        GPIO.output(18, GPIO.LOW)

    elif payload == "FAN_MED" :
        print "FAN SPEED SET TO MEDIUM!"
        time.sleep(0.2)
        GPIO.output(23,GPIO.HIGH)
        time.sleep(0.1)
        GPIO.output(23,GPIO.LOW)
    elif payload == "FAN_HIGH" :
        print "FAN SPEED SET TO HIGH!"
        time.sleep(0.2)
        GPIO.output(24, GPIO.HIGH)
        time.sleep(0.1)
        GPIO.output(24, GPIO.LOW)

    elif payload == "FAN_OFF" :
        print "FAN IS OFF"
        time.sleep(0.2)
        GPIO.output(25, GPIO.HIGH)
        time.sleep(0.1)
        GPIO.output(25, GPIO.LOW)
    else:
        print"Message from IFTTT received: %s" % payload

client = MQTTClient (ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)

# Setup the callback functions defined above.
# English: If it connects, go to connected, if it gets a msg go to message

client.on_connect   = connected
client.on_message   = message
client.on_disconnect    = disconnected

print 'Attempting a connection to the server...'
client.connect()
client.loop_background() # loop in background


while 1 == 1:
    time.sleep(120)
    client.publish('welcome-feed', "PING")

Any ideas as to why it isn't working? I thought it might be a connection to the server timing out because of inactivity, so I set up a part of the code to post "PING" to the server every 2 minutes, but that didn't help. Thanks for your help!!! :D :D

4
  • Why do you call client.publish('welcome-feed', clear) twice? Commented Mar 31, 2017 at 8:44
  • 1
    Not a good idea to publish your ADAFRUIT_IO_USERNAME and ADAFRUIT_IO_KEY. You should edit/scrub them... Commented Mar 31, 2017 at 10:56
  • Kennet Runner, thank you for pointing that out! I can't beleive I forgot to delete that... hopefully everybody who saw it will do the right thing and, well, you know, not spam the hell out of my welcome feed... Commented Apr 2, 2017 at 2:24
  • Dmitry Grigoryev, I called it twice because for some reason if I don't, it will see the last called command and perform it. Its a remnant of v1 of my code before I started pinging ever 2 minutes, I just never removed it. Commented Apr 2, 2017 at 2:26

1 Answer 1

1

From the looks of this open github issue and this one that is closed but not yet merged the client disconnect functionality is not 100% yet.

Also, there's no error handling in your code, and even if you did get disconnected cleanly then your ping loop will continue trying to publish. Have a look at the exceptions types here and implement some error handling.

I would look at forgetting the client.loop_background() call and instead go for a forever loop like this

while 1 == 1:
    if client.connected() :
        # yay, we're still connected, so see if there are any messages
        client.loop(5)   # 5 second timeout waiting for a message
    else
        # we got disconnected somehow, so reconnect
        client.connect()
1
  • while True looks better than while 1 == 1 to me... Commented Sep 27, 2020 at 4:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.