Twitter #hashtag to scroll pHAT

Hi all, heres my tweet to scroll pHAT project i thought you may like to see… it listens to the twitter api for a specified hashtag, currently #saintsfc (possibly the best football team in the world) and sends the tweet to the scrollpHAT.

it currently only gets the first tweet and scrolls it at the moment, but the goal is to display all the live tweets once and then continue to wait for new ones.

im a beginner and this is my first rpiZero project

inspired by the the blinkyStreamer project : blinkystreamer

and also uses the twython library : twitter python library

you just need to enter yout twitter apps details here:-
APP_KEY = ‘’
APP_SECRET = ‘’
OAUTH_TOKEN = ‘’
OAUTH_TOKEN_SECRET = ‘’


import scrollphat
import time
import RPi.GPIO as GPIO
from twython import TwythonStreamer

# clear scrollPHat leds
scrollphat.clear()
scrollphat.set_brightness(10)

# Search terms
TERMS = '#saintsfc'

# Twitter application authentication
APP_KEY = ''
APP_SECRET = ''
OAUTH_TOKEN = ''
OAUTH_TOKEN_SECRET = ''

# Setup callbacks from Twython Streamer
class BlinkyStreamer(TwythonStreamer):
        def on_success(self, data):
                if 'text' in data:
                        print data['text'].encode('utf-8')
                        print
                        scrollphat.write_string(data['text'].encode('utf-8'))
                        while True:
                                scrollphat.scroll()
                                time.sleep(0.1)


# Create streamer
try:
        stream = BlinkyStreamer(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
        stream.statuses.filter(track=TERMS)
except KeyboardInterrupt:
        GPIO.cleanup()
2 Likes

Great work. Looks really nice with the diffuser!

This might help you. Feel free to lift whatever bits of code you can…

1 Like

yeh the diffuser is superb! many thanks for the project link :)

hi sandy, thanks a lot you’ve really helped a lot and everything seems to be working great although it seems my code is casuing it to loop the same tweet continually and it doesnt step onto the next ones… have i missed something?

ive added a print to shell command so i can see the status and it seems static?
it seem to be stuck in the while loop

#!/usr/bin/env python

import time
import tweepy
import scrollphat

scrollphat.set_brightness(2)

class MyStreamListener(tweepy.StreamListener):
    def on_status(self, status):
        if not status.text.startswith('RT'):
            scroll_tweet(status)
    def on_error(self, status_code):
        if status_code == 420:
            return False

def scroll_tweet(status):
    status = '> > > > > >  @%s: %s    ' % (status.user.screen_name.upper(), status.text.upper())
    status = status.encode('ascii', 'ignore').decode('ascii') + '          '
    scrollphat.write_string(status)
    status_length = scrollphat.buffer_len()
    print status
    print
    print status_length
    print
    while scrollphat.buffer_len():
        scrollphat.scroll()
        time.sleep(0.1)
        status_length -= 1

consumer_key =''
consumer_secret =''

access_token = ''
access_token_secret = ''

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)

myStreamListener = MyStreamListener()
myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener)

myStream.filter(track=['#saintsfc', '@BBCSPort'], async=False)

this allows for the while loop to be jumped out of and the tweets now cycle…try this…

  while status_length >= 0:
        scrollphat.scroll()
        time.sleep(0.1)
        status_length -= 1
        #print status_length

for some reason the status_length var doesnt get updated with a new value upon gathering a new tweet… and just resets to the previous value set?

import time
import tweepy
import scrollphat

scrollphat.set_brightness(2)

class MyStreamListener(tweepy.StreamListener):
    def on_status(self, status):
        if not status.text.startswith('RT'):
            scroll_tweet(status)
    def on_error(self, status_code):
        if status_code == 420:
            return False

def scroll_tweet(status):
    status = '> > > > > >  @%s: %s    ' % (status.user.screen_name.upper(), status.text.upper())
    status = status.encode('ascii', 'ignore').decode('ascii') + '          '
    #status_string_length = len(status)
    scrollphat.write_string(status)
    status_length = scrollphat.buffer_len()
    print status
    print
    print status_length
    print
    while status_length >= 0:
        scrollphat.scroll()
        time.sleep(0.1)
        status_length -= 1
        #print status_length

consumer_key =''
consumer_secret =''

access_token = ''
access_token_secret = ''

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)

myStreamListener = MyStreamListener()
myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener)

myStream.filter(track=['#saintsfc', '@BBCSport'], async=False)

D’oh! Yeah, I had a couple of mistakes in there. I don’t have a Pi Zero to hand right now, but I think the corrections I’ve made should get it working. I’ll double check it tonight. Here’s the updated tutorial if you want to give it a shot.

it still appears that the status_length isnt being set correctly here as the value is being duplicated. see my shell prints below…

maybe we need to compare the status_length to status.len() ?

---> 677
>>>>>     @TOFFEENICK: HAHAHAHA IMAGINE COMPARING BONY TO LUKAKU HTTPS://T.CO/NA6ZJNWCG5     
---> 677
>>>>>     @BIGJEFFERY19: @BBCSPORT     
---> 677
>>>>>     @_THUMPINTUBS_: @BBCSPORT SCORES GOALS, IS YOUNG & WILL IMPROVE. BY TODAY'S MARKET THAT'S A BARGAIN.     
---> 677
>>>>>     @JAMIE_HUDSON_: @BBCSPORT IF THEY DON'T WANT TO SELL HIM THEN THEY ARE GOING TO ONLY REALLY ACCEPT A HIGH BID LIKE THAT AREN'T THEY!?     
---> 677
>>>>>     @ANDY_HULSE: @FOOTBALLMANAGER @BBCSPORT RUNE LANGE! SUPPOSED TO BE THE NEXT BIG THING BUT NEVER HEARD OF HIM IN REAL LIFE...     
---> 677
>>>>>     @BRADLEYS570: @BBCSPORT HE IS STILL YOUNG AND PREM PROVEN I WOULD LOVE HIM AT ARSENAL WOULD PAY UP TO 50-55 MILLION FOR HIM     
---> 677
>>>>>     @JCHAMBERLAIN94: @BBC5LIVE @BBCSPORT @JOEBRENCH     
---> 677



def scroll_tweet(status):
    status = '@%s: %s' % (status.user.screen_name.upper(), status.text.upper())
    status = '>>>>>     ' + status.encode('ascii', 'ignore').decode('ascii') + '     '
    scrollphat.write_string(status)
    status_length = scrollphat.buffer_len()
    print status
    print '--->',status_length
    while status_length > 0:
        scrollphat.scroll()
        time.sleep(0.1)
        status_length -= 1
        #print status_length

ok ive also found that with infrequent tweets the first 4 chevrons >>>> are stuck on the scrollpHAT until a new tweet comes in.

also something is certainly incorrect with the status_length var because its not returning the value of each tweeet… this could have something to do with new tweets bring buffered?

>>>>>     @CONNORARMSTRONG: #SAINTSFC MIDFIELDER GASTN RAMREZ IS BEING LINKED WITH A MOVE TO SWANSEA CITY: HTTPS://T.CO/JMFLW2PZQS     
---> 528
>>>>>     @CONNORARMSTRONG: #SAINTSFC MIDFIELDER GASTN RAMREZ IS BEING LINKED WITH A MOVE TO SWANSEA: HTTPS://T.CO/JMFLW2PZQS     
---> 528
>>>>>     @PHANTOMBOARDER: JUST FOUND OUT THAT IT'S THE BIRTHDAY OF THE INFAMOUS #SAINTSFC #MAVERICKSAMBAASSASIN TODAY... HAPPY BIRTHDAY GULY DO PRADO! WHERE'S HE NOW?     
---> 666
>>>>>     @CHRS00: BECAUSE THERE'S NO POSSIBLE WAY THAT'LL END BADLY. HTTPS://T.CO/DIHP99MIQ5     
---> 666
>>>>>     @DIAMONDBABYCAZ: YEY LOVE MAN U :D HTTPS://T.CO/GEHGYZNRTW     
---> 666
>>>>>     @C4MBRIDGE: I'M A BIG UNITED FAN AND THIS WOULD BE AMAZING!! :D HTTPS://T.CO/TPML6NGDIR     
---> 666
>>>>>     @PARSONS8: RECKON HE KNOWS THE OFFSIDE RULE YET? HTTPS://T.CO/1KYAB530WX     
---> 666
>>>>>     @UKBOOKIEBASH: FANCY EARNING 2000 MONTHLY ONLINE #BOOKIEBASHING? SEE MY PROFILE NOW #AFCB
#MCFC #MUFC #NCFC #NUFC #SAINTSFC #SCFC #SAFC #SWANS #WATFORDFC     
---> 687
>>>>>     @KERIBROOKS1: @DEXPRESS_SPORT #MUFCV#SAINTSFC WOULD LOVE TO WIN     
---> 687

I think that the scrollphat.buffer_length() isn’t being calculated quite correctly, but the code below works for me and fixes the problem with the scrolling continuing too long and looping back to the chevrons as you saw. Let me know how you get on with this.

import sys
import time
import tweepy
import scrollphat

scrollphat.clear()

while True:
    try:
        scrollphat.set_brightness(2)

        class MyStreamListener(tweepy.StreamListener):
            def on_status(self, status):
                if not status.text.startswith('RT'):
                    scroll_tweet(status)
            def on_error(self, status_code):
                if status_code == 420:
                    return False

        def scroll_tweet(status):
            status = '     >>>>>     @%s: %s     ' % (status.user.screen_name.upper(), status.text.upper())
            status = status.encode('ascii', 'ignore').decode('ascii')
            scrollphat.write_string(status)
            status_length = scrollphat.buffer_len()
            while status_length > 0:
                scrollphat.scroll()
                time.sleep(0.1)
                status_length -= 1

        consumer_key =''
        consumer_secret =''

        access_token = ''
        access_token_secret = ''

        auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)
        api = tweepy.API(auth)

        myStreamListener = MyStreamListener()
        myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener)

        myStream.filter(track=['#raspberrypi'], async=False)

    except KeyboardInterrupt:
        scrollphat.clear()
        sys.exit(-1)

I’ve updated the tutorial with those changes too.

@sandyjmacdonald what python version are you using? mine seems to print the same number repeated and it sometimes repeats the previous tweet?

 def scroll_tweet(status):
            status = '     >>>>>     @%s: %s     ' % (status.user.screen_name.upper(), status.text.upper())
            status = status.encode('ascii', 'ignore').decode('ascii')
            scrollphat.write_string(status)
            status_length = scrollphat.buffer_len()
            print status
            print status_length
            while status_length > 0:
                scrollphat.scroll()
                time.sleep(0.1)
                status_length -= 1

There’s more than one version of Python?! I know only of Python 2.7. :-)

1 Like

status_length only gets larger and never smaller

     >>>>>     @MIKEY8BHOY: @BBCSPORT NO YOU NEED TO STOP THE KLEEK CULTURE AT CLUBS WITH SO CALLED "COACHES" BEEN HAPPENING FOR YEARS AT CLUBS     
status length 565
     >>>>>     @AARON98CLARK: @BBCSPORT COULD IT F##K     
status length 565
     >>>>>     @BAINALAN05: @BBCSPORT CRAP! WHY IS SPORT SO ANTI FREEDOM? PLAYERS SHOULD BE ALLOWED TO JOIN THE CLUB THEY WANT TO IF THAT CLUB WANTS THEM.     
status length 609
     >>>>>     @KIYLETESH: @MATT_BRIGHTON94 @BBCSPORT AND WELL DESERVED TOO!     
status length 609
     >>>>>     @NICKL_1989: @BBCSPORT NO     
status length 609


        def scroll_tweet(status):
            status_length = 0
            status = '     >>>>>     @%s: %s     ' % (status.user.screen_name.upper(), status.text.upper())
            status = status.encode('ascii', 'ignore').decode('ascii')
            scrollphat.write_string(status)
            status_length = scrollphat.buffer_len()
            print status
            print 'status length',status_length
            while status_length > 0:
                scrollphat.scroll()
                time.sleep(0.1)
                status_length -= 1

i set up another print to the shell and here are my results.
print ‘status length’,status_length reports the same number each time… this doesnt seem to change… it only adjusts when the value is larger then the previous one…

   status length 10
    buffer_len 585
    status length 9
    buffer_len 585
    status length 8
    buffer_len 585
    status length 7
    buffer_len 585
    status length 6
    buffer_len 585
    status length 5
    buffer_len 585
    status length 4
    buffer_len 585
    status length 3
    buffer_len 585
    status length 2
    buffer_len 585
    status length 1
    buffer_len 585
         >>>>>     @SAINTSFOOTBALLC: MANCHESTER UNITED V SOUTHAMPTON HTTPS://T.CO/HL66WNVWXX (BBC) #SAINTSFC     
    status length 585
    status length 585
    status length 585
    buffer_len 585
    status length 584
    buffer_len 585
    status length 583
    buffer_len 585
    status length 582
    buffer_len 585
    status length 581
    buffer_len 585
    status length 580
    buffer_len 585
    status length 579



    def scroll_tweet(status):
                status_length = 0
                status = '     >>>>>     @%s: %s     ' % (status.user.screen_name.upper(), status.text.upper())
                status = status.encode('ascii', 'ignore').decode('ascii')
                scrollphat.write_string(status)
                status_length = scrollphat.buffer_len()
                print status
                print 'status length',status_length
                print 'status length',scrollphat.buffer_len()
                while status_length > 0:
                    print 'status length',status_length
                    print 'buffer_len',scrollphat.buffer_len()
                    scrollphat.scroll()
                    time.sleep(0.08)
                    status_length -= 1

cant quite crack it yet, but something is up with scrollphat.buffer_len() the length seems to never fall!

It’s behaving as it should. The scrollphat.buffer_len() will remain the same until you call scrollphat.write_string() again. That’s why we have the status_length variable that we decrement by 1 on each pass of the while loop, which makes sure we only scroll for the length of the tweet. Is my code above still not working for you? Are you doing this with a fresh install of the Scoll pHAT library? Can you post the whole script that you’re using, so that I can check it, please?

hi sandy, yeh ive updated the library. thanks for checking :)

import sys
import time
import tweepy
import scrollphat

scrollphat.clear()

while True:
    try:
        scrollphat.set_brightness(2)

        class MyStreamListener(tweepy.StreamListener):
            def on_status(self, status):
                if not status.text.startswith('RT'):
                    scroll_tweet(status)
            def on_error(self, status_code):
                if status_code == 420:
                    return False

        def scroll_tweet(status):
            status = '     >>>>>     @%s: %s     ' % (status.user.screen_name.upper(), status.text.upper())
            status = status.encode('ascii', 'ignore').decode('ascii')            
            scrollphat.write_string(status)
            status_length = scrollphat.buffer_len()
            print status
            print 'status length --->',status_length
            print 'buffer_len --->',scrollphat.buffer_len()
            while status_length > 0:
                #print 'status length',status_length
                #print 'buffer_len',scrollphat.buffer_len()
                scrollphat.scroll()
                time.sleep(0.06)
                status_length -= 1
                
        consumer_key =''
        consumer_secret =''

        access_token = ''
        access_token_secret = ''

        auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)
        api = tweepy.API(auth)

        myStreamListener = MyStreamListener()
        myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener)

        myStream.filter(track=['#saintsfc','@BBCSport'], async=False)
        
    except KeyboardInterrupt:
        scrollphat.clear()
        sys.exit(-1)

The reason that status_length isn’t decreasing is because it isn’t inside the while loop! That’s where it gets decremented so, to see it change, you need the print status_length inside the while loop. Is it working ok otherwise?

1 Like

status_length is here at the bottom of the while loop? its being decreased by the -= 1. its the total thats not getting smaller

example…
there is a tweet with a length of 200 the status_length var falls to 0 from 200
a longer 250 tweet then comes in and the status_length var falls to 0 again from 250
a shorter 150 tweet comes in and the status_length var falls to 0 from 250
a tweet with a length of 200 the status_length var falls to 0 from 250

try running the above code for some minutes and watch the shell print numbers?