User Tools

Site Tools

A PCRE internal error occured. This might be caused by a faulty plugin

===== Introduction ===== This project was inspired by [[|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 [[|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 [[]] 16x2 LCD -> $13.95 [[]] ==== Software ==== [[|Twitcurl]], library for Twitter API's. [[|Libcurl]], Libcurl dependency. [[|Perl]], for the main script. Perl module: [[ XML::Simple]], so you can parse the XML file. === Installing the software === Libcurl: <code> cd mkdir scr cd scr/ wget 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 cd libtwitcurl/ make cp twitcurl.h oauthlib.h /usr/include/ cp /usr/lib/ ln -sf /usr/lib/ /usr/lib/ ln -sf /usr/lib/ /usr/lib/ </code> Perl (I tried to use ''cpan'', but the system kept getting out of memory): <code> cd ../../ mkdir perlModules cd perlModules/ wget tar xvfz ExtUtils-MakeMaker-6.58.tar.gz cd ExtUtils-MakeMaker-6.58 perl Makefile.PL make make install cd .. wget tar xvfz XML-NamespaceSupport-1.11.tar.gz cd XML-NamespaceSupport-1.11 perl Makefile.PL make make install cd .. wget tar xvfz XML-SAX-0.96.tar.gz cd XML-SAX-0.96 perl Makefile.PL make make install cd .. wget 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 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 */ 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; "twitterReader_token_key.txt" ); "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; "twitterReader_token_key.txt" ); "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; "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 </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 </code>

tweet_my_door.txt · Last modified: 2017/01/03 21:29 by admin