User Tools

Site Tools


tweet_my_door

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

tweet_my_door [2017/01/03 21:29] (current)
admin created
Line 1: Line 1:
 +===== Introduction =====
 +This project was inspired by [[http://​spectrum.ieee.org/​geek-life/​hands-on/​send-a-tweet-to-your-office-door|this]] article, where the author explains how to fetch your status message from Twitter to an Arduino and show it on a LCD placed at your office door. At the end, a few improvements are mentioned and the complete implementation can be found [[http://​www.instructables.com/​id/​Use-twitter-and-weather-to-post-notes-and-temperat/​|here]]. I wanted do basically the same, but did not have the Arduino Ethernet Shield. Instead, I used an embedded system that was in our lab doing nothing.
  
 +===== Hardware and software =====
 +==== Hardware ====
 +TS-7260 running Debian Etch -> $179 [[http://​www.embeddedarm.com/​products/​board-detail.php?​product=TS-7260#​]]
 +
 +16x2 LCD -> $13.95 [[http://​www.sparkfun.com/​products/​255]]
 +
 +==== Software ====
 +[[http://​code.google.com/​p/​twitcurl/​|Twitcurl]],​ library for Twitter API's.
 +
 +[[http://​curl.haxx.se/​libcurl/​|Libcurl]],​ Libcurl dependency.
 +
 +[[http://​www.perl.org/​|Perl]],​ for the main script.
 +
 +Perl module: [[http://​search.cpan.org/​~grantm/​XML-Simple-2.18/​lib/​XML/​Simple.pm XML::​Simple]],​ so you can parse the XML file.
 +
 +=== Installing the software ===
 +Libcurl:
 +
 +<​code>​
 +cd
 +
 +mkdir scr
 +
 +cd scr/
 +
 +wget http://​curl.haxx.se/​download/​curl-7.21.7.tar.gz
 +
 +tar xvfz curl-7.21.7.tar.gz
 +
 +cd curl-7.21.7
 +
 +./configure --prefix=/​usr
 +
 +make
 +
 +make install
 +</​code>​
 +
 +Twitcurl:
 +
 +<​code>​
 +cd ../../
 +
 +mkdir twitcurl
 +
 +cd twitcurl/
 +
 +apt-get install g++
 +
 +apt-get install subversion
 +
 +svn co http://​twitcurl.googlecode.com/​svn/​branches/​libtwitcurl
 +
 +cd libtwitcurl/​
 +
 +make
 +
 +cp twitcurl.h oauthlib.h /​usr/​include/​
 +
 +cp libtwitcurl.so.1.0 /usr/lib/
 +
 +ln -sf /​usr/​lib/​libtwitcurl.so.1.0 /​usr/​lib/​libtwitcurl.so.1
 +
 +ln -sf /​usr/​lib/​libtwitcurl.so.1.0 /​usr/​lib/​libtwitcurl.so
 +</​code>​
 +
 +Perl (I tried to use ''​cpan'',​ but the system kept getting out of memory):
 +
 +<​code>​
 +cd ../../
 +
 +mkdir perlModules
 +
 +cd perlModules/​
 +
 +wget http://​search.cpan.org/​CPAN/​authors/​id/​M/​MS/​MSCHWERN/​ExtUtils-MakeMaker-6.58.tar.gz
 +
 +tar xvfz ExtUtils-MakeMaker-6.58.tar.gz
 +
 +cd ExtUtils-MakeMaker-6.58
 +
 +perl Makefile.PL
 +
 +make
 +
 +make install
 +
 +
 +cd ..
 +
 +wget http://​search.cpan.org/​CPAN/​authors/​id/​P/​PE/​PERIGRIN/​XML-NamespaceSupport-1.11.tar.gz
 +
 +tar xvfz XML-NamespaceSupport-1.11.tar.gz
 +
 +cd XML-NamespaceSupport-1.11
 +
 +perl Makefile.PL
 +
 +make 
 +
 +make install
 +
 +
 +cd ..
 +
 +wget http://​search.cpan.org/​CPAN/​authors/​id/​G/​GR/​GRANTM/​XML-SAX-0.96.tar.gz
 +
 +tar xvfz XML-SAX-0.96.tar.gz
 +
 +cd XML-SAX-0.96
 +
 +perl Makefile.PL
 +
 +make
 +
 +make install
 +
 +
 +cd ..
 +
 +wget http://​search.cpan.org/​CPAN/​authors/​id/​G/​GR/​GRANTM/​XML-Simple-2.18.tar.gz
 +
 +tar xvfz XML-Simple-2.18.tar.gz
 +
 +cd XML-Simple-2.18
 +
 +perl Makefile.PL
 +
 +make 
 +
 +make install
 +</​code>​
 +
 +LCD:
 +
 +<​code>​
 +cd ../../
 +
 +mkdir lcd
 +
 +cd lcd
 +
 +wget ftp://​ftp.embeddedarm.com/​ts-arm-sbc/​ts-7260-linux/​samples/​lcdmesg.c
 +
 +gcc -o lcdmesg lcdmesg.c
 +</​code>​
 +
 +=== Creating application ===
 +
 +== Validating your application in Twitter ==
 +Sign in to your Twitter account. Go to settings -> applications -> developers -> create new application. Complete the information screen, copy the consumer key and consumer secret. You'll need it next.
 +
 +== Status reader ==
 +Create the application that's going to fetch the status and display it on the LCD:
 +
 +<​code>​
 +cd /home/src/
 +
 +mkdir twitterReader
 +</​code>​
 +
 +Here's the code for twitterReader.h:​
 +
 +<code cpp>
 +#include <​cstdio>​
 +#include <​iostream>​
 +#include <​fstream>​
 +#include "​twitcurl.h"​
 +</​code>​
 +
 +The code for twitterReader.cpp is this one (update myConsumerKey and myConsumerSecret with data from last step):
 +
 +<code cpp>
 +#include "​twitterReader.h"​
 +
 +void printUsage()
 +{
 +    printf( "​\nUsage:​\ntwitterClient -u username -p password\n"​ );
 +}
 +
 +int main( int argc, char* argv[] )
 +{
 +    std::string userName( ""​ );
 +    std::string passWord( ""​ );
 +    if( argc > 4 )
 +    {
 +        for( int i = 1; i < argc; i += 2 )
 +        {
 +            if( 0 == strncmp( argv[i], "​-u",​ strlen("​-u"​) ) )
 +            {
 +                userName = argv[i+1];
 +            }
 +            else if( 0 == strncmp( argv[i], "​-p",​ strlen("​-p"​) ) )
 +            {
 +                passWord = argv[i+1];
 +            }
 +        }
 +        if( ( 0 == userName.length() ) || ( 0 == passWord.length() ) )
 +        {
 +            printUsage();​
 +            return 0;
 +        }
 +    }
 +    else
 +    {
 +        printUsage();​
 +        return 0;
 +    }
 +
 +    twitCurl twitterObj;
 +    std::string tmpStr( ""​ );
 +    std::string replyMsg( ""​ );
 +
 +    /* OAuth flow begins */
 +    /* Step 0: Set OAuth related params. These are got by registering your app at twitter.com */
 +    twitterObj.getOAuth().setConsumerKey( std::​string( "​myConsumerKey"​ ) );
 +    twitterObj.getOAuth().setConsumerSecret( std::​string( "​myConsumerSecret"​ ) );
 +
 +    /* Step 1: Check if we alredy have OAuth access token from a previous run */
 +    char szKey[1024];​
 +    std::string myOAuthAccessTokenKey(""​);​
 +    std::string myOAuthAccessTokenSecret(""​);​
 +    std::​ifstream oAuthTokenKeyIn;​
 +    std::​ifstream oAuthTokenSecretIn;​
 +
 +    oAuthTokenKeyIn.open( "​twitterReader_token_key.txt"​ );
 +    oAuthTokenSecretIn.open( "​twitterReader_token_secret.txt"​ );
 +
 +    memset( szKey, 0, 1024 );
 +    oAuthTokenKeyIn >> szKey;
 +    myOAuthAccessTokenKey = szKey;
 +
 +    memset( szKey, 0, 1024 );
 +    oAuthTokenSecretIn >> szKey;
 +    myOAuthAccessTokenSecret = szKey;
 +
 +    oAuthTokenKeyIn.close();​
 +    oAuthTokenSecretIn.close();​
 +    ​
 +    if( myOAuthAccessTokenKey.size() && myOAuthAccessTokenSecret.size() )
 +    {
 +        /* If we already have these keys, then no need to go through auth again */
 +        printf( "​\nUsing:​\nKey:​ %s\nSecret: %s\n\n",​ myOAuthAccessTokenKey.c_str(),​ myOAuthAccessTokenSecret.c_str() );
 +
 +        twitterObj.getOAuth().setOAuthTokenKey( myOAuthAccessTokenKey );
 +        twitterObj.getOAuth().setOAuthTokenSecret( myOAuthAccessTokenSecret );
 +    }
 +    else
 +    {
 +        /* Step 2: Get request token key and secret */
 +        twitterObj.oAuthRequestToken( tmpStr );
 +
 +        /* Step 3: Ask user to visit web link and get PIN */
 +        char szOAuthVerifierPin[1024];​
 +        memset( szOAuthVerifierPin,​ 0, 1024 );
 +        printf( "​\nPlease visit this link in web browser and authorize this application:​\n%s",​ tmpStr.c_str() );
 +        printf( "​\nEnter the PIN provided by twitter: " );
 +        gets( szOAuthVerifierPin );
 +        tmpStr = szOAuthVerifierPin;​
 +        twitterObj.getOAuth().setOAuthPin( tmpStr );
 +
 +        /* Step 4: Exchange request token with access token */
 +        twitterObj.oAuthAccessToken();​
 +
 +        /* Step 5: Now, save this access token key and secret for future use without PIN */
 +        twitterObj.getOAuth().getOAuthTokenKey( myOAuthAccessTokenKey );
 +        twitterObj.getOAuth().getOAuthTokenSecret( myOAuthAccessTokenSecret );
 +
 +        /* Step 6: Save these keys in a file or wherever */
 + std::​ofstream oAuthTokenKeyOut;​
 + std::​ofstream oAuthTokenSecretOut;​
 +
 +        oAuthTokenKeyOut.open( "​twitterReader_token_key.txt"​ );
 +        oAuthTokenSecretOut.open( "​twitterReader_token_secret.txt"​ );
 +
 +        oAuthTokenKeyOut.clear();​
 +        oAuthTokenSecretOut.clear();​
 +
 +        oAuthTokenKeyOut << myOAuthAccessTokenKey.c_str();​
 +        oAuthTokenSecretOut << myOAuthAccessTokenSecret.c_str();​
 +
 +        oAuthTokenKeyOut.close();​
 +        oAuthTokenSecretOut.close();​
 +    }
 +    /* OAuth flow ends */
 +
 +    /* Set twitter username and password */
 +    twitterObj.setTwitterUsername( userName );
 +    twitterObj.setTwitterPassword( passWord );
 +
 +    /* Read status */
 +
 +    if( twitterObj.timelineUserGet( userName, false ) )
 +    {
 +        twitterObj.getLastWebResponse( replyMsg );
 +        ​
 + /* Save response from twitter in a file or wherever */
 + std::​ofstream replyMsgOut;​
 + replyMsgOut.open( "​twitterReader_reply_message.xml"​ );
 + replyMsgOut.clear();​
 + replyMsgOut << replyMsg.c_str();​
 + replyMsgOut.close();​
 +
 +        //printf( "​\ntwitterClient::​ twitCurl::​statusUpdate web response:​\n%s\n",​ replyMsg.c_str() );
 +        printf("​\nWeb response saved!\n"​);​
 +    }
 +    else
 +    {
 +        twitterObj.getLastCurlError( replyMsg );
 +        printf( "​\ntwitterClient::​ twitCurl::​statusUpdate error:​\n%s\n",​ replyMsg.c_str() );
 +    }
 + 
 +    return 0;
 +}
 +</​code>​
 +
 +This will download a XML file with the response from Twitter.
 +
 +Save and compile:
 +
 +<​code>​
 +g++ -ltwitcurl -o statusReader twitterReader.cpp
 +</​code>​
 +
 +=== Testing ===
 +
 +<​code>​
 +./​statusReader -u username -p password
 +</​code>​
 +
 +Visit the website and copy the PIN. Check the XML file saved to see the response from Twitter.
 +
 +=== Main program ===
 +Create a folder for the application:​
 +
 +<​code>​
 +cd ../../
 +
 +mkdir tweetMyDoor
 +
 +cd tweetMyDoor/​
 +</​code>​
 +
 +Copy the statusReader and lcdmesg programs:
 +
 +<​code>​
 +cp ../​src/​twitterReader/​statusReader ./
 +
 +cp ../​src/​lcd/​lcdmesg ./
 +</​code>​
 +
 +Create the main application:​
 +
 +<​code>​
 +nano tweetMyDoor.pl
 +</​code>​
 +
 +Here's the code:
 +
 +<code perl>
 +#​!/​usr/​bin/​perl
 +
 +# use modules
 +use strict;
 +use warnings;
 +use XML::​Simple;​
 +use Data::​Dumper;​
 +
 +# create object
 +my $xml = new XML::Simple (ForceArray => 1);
 +#my $xml = new XML::​Simple;​
 +
 +while (1) {
 +
 +# first call twitterReader to get timeline from twitter
 +my $status = system("​./​statusReader -u username -p password"​);​
 +
 +# read XML file
 +my $data = $xml->​XMLin("​twitterReader_reply_message.xml"​);​
 +#open (MYFILE, '>>​data.txt'​);​
 +#print MYFILE Dumper($data);​
 +#close (MYFILE);
 +
 +# access XML data
 +print "Last tweet: $data->​{'​status'​}->​[0]->​{'​text'​}->​[0]\n";​
 +#print "Tweet 2: data->​{'​status'​}->​[1]->​{'​text'​}->​[0]\n";​
 +
 +# update LCD
 +system("​echo $data->​{'​status'​}->​[0]->​{'​text'​}->​[0] | ./​lcdmesg"​);​
 +
 +sleep(180);
 +
 +}
 +</​code>​
 +
 +Run it (repeat steps for PIN):
 +
 +<​code>​
 +perl tweetMyDoor.pl
 +</​code>​
tweet_my_door.txt ยท Last modified: 2017/01/03 21:29 by admin