Monday, May 22, 2017

Tweeting Cat Door (now with Rasperry PI)

It is hard to believe, but it was over five years ago that we created a Tweeting CatDoor using the Electric Imp.  Basic hobby IoT was much harder back then.  The Electric Imp, being a commercial grade product, was rock solid.  It only needed to reboot twice during it's entire service.  That said, a lightening strike may have gotten the best of it.
Basic hobby IoT is easier today thanks to project sites like HackaDay, etc.

A look into our spare parts box prompted some changes:  The Electric Imp gets replaced by a Raspberry Pi ZERO and WiFi dongle (we didn't have a spare ZERO-W laying around).  The original magnetic reed switch implementation goes solid state and gets replaced with a A3144EUA Hall Effect Sensor.  The concept is still the same as the original; a magnet is placed on the door and when Zena or Kelso use the door a magnet swings past the stationary sensor triggering a GPIO event.

As shown in the wiring diagram above, the build is simple.  The python code straightforward.

For the python code below you will need you create your own Twitter App and establish:
      - Consumer Key (API Key) and Consumer Secret (API Secret)
      - Access Token and Access Token Secret
These Keys and Tokens are, of course, changed in the python code below for obvious reasons.  Also, to save space the 'database' of tweets listed in the code is reduced.
# May 2017 / WhiskeyTangoHotel.Com
# Raspberry PI ZERO for tweeting Cat Door activity
# MagSwitch is model A3144EUA Hall Effect sensor with magnet next to it
# Activate tweet loop whenever the Hall Effect Sensor changes state

import random
import time

# Set up Auth and token ID for the twitter API
from twython import Twython
# fill in your 4 keys in following variables
C_key = "ckckckckckblaghblagckckckckck"
C_secret = "cscscscscsblaghblaghblaghcscscscscs"
A_token = "atatatatatblaghblaghblagatatatatat"
A_secret = "asasasasasblaghblaghblagasasasasas"

localtime = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
Current_day = time.strftime("%d", time.localtime()) # what day of the month is it
New_day_dawned = Current_day # 1st run after midnight send status tweet to verify program is running


# Flood control (in seconds) for debounce and not sending to many tweets
Flood_control = 180 # seconds

# Really tweet (YES) or just test/debug (NO)?
Tweet = "YES"   # YES or NO in ALL UPPERCASE

# Track how many times the door has been triggered
Counter = 0

# Set up Hall Effect Sensor
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD) # to use Raspberry Pi board pin numbers
MagSwitch = 8  # Pin from signal of hall effect sensor
#Set pin to input and set pull-up resistor to hold the pin is high
GPIO.setup(MagSwitch, GPIO.IN, pull_up_down=GPIO.PUD_UP)
print ' '
print "Program starts with Flood control of " + str(Flood_control) + " seconds."
print "Tweet set to " + Tweet
print " "

localtime = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
print "RasPI started on " + localtime + ".  Begin the mission!!!"
MagSwitch_Current = GPIO.input(MagSwitch)
#print "MagSwitch value is: " + str(MagSwitch_Current)
print ' '
if (Tweet == "YES"):
    myTweet = Twython(C_key,C_secret,A_token,A_secret)
    localtime = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
    myTweet.update_status(status="RasPI started at " + localtime + ".  Begin the mission!!!")
time.sleep(1)  # Whew... let's rest a bit..    Why?  Dunno...

while True:    # program runs 'forever'
    # First check if this is a new day.  If yes, tweet program is still active
    localtime = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
    Current_day = time.strftime("%d", time.localtime())
    if Current_day != New_day_dawned:
        print "A new day has dawned. It is " + localtime + "."
        print ' '
        if (Tweet == "YES"):
            myTweet = Twython(C_key,C_secret,A_token,A_secret)
            localtime = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
            myTweet.update_status(status="Hello, Twitter. Let's make the best of " + localtime)
        New_day_dawned = Current_day
    # Now check to see if Sensor has changed state.  If so then Let's tweet
    if (GPIO.input(MagSwitch) != MagSwitch_Current):
        print ' '
        localtime = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
        print "Triggered at: " + localtime
        print '-------------------------------'
        Counter = Counter + 1
        # Load the CatQuotes; then Tweet it
        CatQuote = [
        "ZERO", #this is zero and should never be called.  just here to make counting easier 'cuz i'm stupid
        "Tweet Quote 1",
        "Tweet Quote 2",
        "Tweet Quote 3",
        "Tweet Quote 4",
        "Tweet Quote 5",
        "Tweet Quote etc...",        ]
        Number_of_quotes =  6 - 1
        random.seed() # seed off the CPU clock
        r = random.random()              
        r = int((r * Number_of_quotes) + 1)

        print str(Counter) + ": CatQuote("+str(r)+"): " + CatQuote[r]
        print "Flood control set to " + str(Flood_control) + " seconds."
        print "Tweet set to: " + Tweet
        if (Tweet == "YES"):
            myTweet = Twython(C_key,C_secret,A_token,A_secret)
        time.sleep(Flood_control)  # pause for debounce, re-read HE sensor, keeps from tweeting all the time.
        # Door etc has settled after the Flood Control.  Reset and wait for next toggle
        MagSwitch_Current = GPIO.input(MagSwitch)
        print "Flood Control PASSED."
        print " "
Good luck if you decide to build your own tweeting RasPI.