jueves, 28 de noviembre de 2013

Pi + arduino + ifttt

source: http://dparkinson.blogspot.com/2013/05/using-raspberrypi-arduino-and-ifttt-to.html



With the particularly wet weather we’re having this summer, my garage has developed a flood.

 

There is what I believe to be a soakaway drain  which is used to drain the water from the garage roof when it’s raining.
Over the last few weeks, I’ve walked into the garage to see quite a flood around the drain without any indication of how it it is happening, even whilst it’s still raining and water is going into the drain, it’s not clear how it is flooding.
I have therefore decided to set up the Arduino as a water sensor and hooked that up to the Raspberry Pi to provide the notifications, since I don’t have a wireless shield for my Arduino. This way, I can hopefully get an early warning of the flood without having to keep checking every few minutes.
This post just outlines how I’ve achieved that. Most of this is quite convoluted and probably overkill for the requirement, but I have these items around and it's all pretty simple to do.

Overall Architecture

 

At a high level, the Arduino senses the flood and the raspberry pi sends me a tweet. In addition, since I wouldn’t necessarily see the tweet immediately, I’ve also set it up to email “If This Then That”  which will in turn send me a text message (sms) that I’ll get immediately.

Arduino as a Water Sensor

 

Strictly speaking, this isn’t really a sensor. I’m essentially using the water to complete a circuit between a couple of nails and when I get a circuit, I’m reading the analog input to determine whether there is a flood or not.
The analog input will give me a value of 1023 for a direct connection between the two nails and a value of 0 when no circuit is made. When water completes the circuit, it will provide a value of between 400 and 700 depending on how far apart the nails are.
The circuit and the code for this is therefore very simple, as outlined below.
 

int moistureSensor = 0; //analog 0
int ledPin = 9;
int moistureValue;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  moistureValue = analogRead(moistureSensor);
  if ((moistureValue < 700) && (moistureValue > 400)) {
    analogWrite(ledPin, 255); 
    Serial.println("Moisture Detected");
  } else {
    analogWrite(ledPin, 0);
  }
  delay(500);
 
}
This will also light an LED on pin 9 as a visual indication too.

Setting up a Twitter for notifications

To get the notifications, I’ve set up a twitter account for the house which can then tweet that a flood has occurred.
You could just use any twitter account, the important thing is to set up an “application” in twitter so that you can use Python on the Raspberry Pi to tweet.
Go to dev.twitter.com/apps  and log in with your account. Once logged in, you can click the “Create a new application” button and follow the steps.
 
Once you’ve created an application, you then need to get the consumer key, the consumer secret and an access token secret from the application details tab which you’ll need for the Python script coming up next. You create the access token by clicking the “Create my access token” button.
They have lots of rules too, so please make sure you follow them!

Setting up the Raspberry Pi

At this point, I’m assuming you already have a working Raspberry Pi, so I’ll just outline the main steps I performed to get up and running.
So that I could load the arduino sketches on from the Raspberry Pi, I installed the arduino package and added the pi user to the tty and dial out groups for access to the serial port:
sudo apt-get update
sudo apt-get install arduino
sudo usermod -a -G tty pi
sudo usermod -a -G dialout pi
Then I added the serial package for accessing the Arduino via serial port in the script:
sudo apt-get install python-serial python3-serial
To enable the twitter integration, I’m using the python-twitter  wrapper. To get this running I installed pip for the python package management:
sudo apt-get install python-setuptools 
sudo easy_install pip
Then installed the appropriate components:
sudo pip install simplejson
sudo pip install OAuth2
sudo pip install HTTPLib2
sudo pip install python-twitter
Then I created a short python script to read the serial port and detect the “Moisture Detected” string I’m outputting from the Arduino script. It probably isn’t that robust, but should serve the purpose for this.
def SendTweet():
    '''
    Method to send a tweet
    '''
    print "Water has been detected -- sending tweet"
    api = twitter.Api(consumer_key=my_consumer_key,
        consumer_secret=my_consumer_secret,
        access_token_key=my_access_token_key,
        access_token_secret=my_access_token_secret)
    statustext = 'Test Tweet : Water Detected on %s' % time.asctime()
    status = api.PostUpdate(statustext)
    print status.text

import serial
import time
import twitter

my_consumer_key = 'YOUR_CONSUMER_KEY'
my_consumer_secret = 'YOUR_CONSUMER_SECRET'
my_access_token_key = 'YOUR_ACCESS_TOKEN_KEY'
my_access_token_secret = 'YOUR_ACCESS_TOKEN_SECRET'

port = "/dev/ttyACM0"
ser = serial.Serial(port, 9600)
ser.flushInput()

print "Listening to arduino, waiting for detection..."
timer = time.time()
tweetdelay = 120 # in seconds

while True:
    if (ser.inWaiting() > 0):
        input = ser.readline()
        if "Moisture Detected" in input:
            if ((time.time() - timer) > tweetdelay):
               timer = time.time() #reset timer ready for next loop
               SendTweet()
        elif ((time.time() - timer) > tweetdelay):
            timer = time.time()

Adding SMS notifications

At the moment, IFTTT doesn’t have any triggers for Twitter, so in order to get an SMS notification, I can send an email from my google account to IFTTT which in turn will send me a text message.
To do this, I just added the following to the SendTweet method:
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username, password)
server.sendmail(fromaddr, toaddr, msg)
server.quit()
And the following to the main script: 
fromaddr = 'YOUR_GMAIL_ADDRESS_HERE'
toaddr = 'trigger@ifttt.com'
header = 'To:' + toaddr + '\n' + 'From: fromaddr' + '\n' + 'Subject:Garage is flooded. \n'
msg = header + 'Garage is flooded'
username = 'YOUR_GMAIL_ACCOUNT@gmail.com'
password = 'YOUR_GMAIL_PASSWORD'
Of note is that the email wasn't accepted without the "From:" in the header, which makes sense I guess as this is what IFTTT is checking for I suppose.

 
That's it.
Now, if the garage floods, I'll be able to get there immediately to see how on earth it's happening.  As a follow up, I could also incorporate the motion sensor that I've posted about before, along with a web cam in case I'm not in the house somewhere.

No hay comentarios:

Publicar un comentario