Here’s an updated version of my weather ticker – this one gives you the BBC news headlines too!
It uses a SenseHAT plug-in board atop a RaspberryPi – no soldering required, just install the SenseHAT and feedparser (‘sudo pip install feedparser’) Python libraries on your freshly-updated install of Raspbian, and you are good to go. Feedparser makes extracting useful information from the XML in RSS feeds a doddle.
It gives you 7 headlines (though you can easily have more or fewer), all colour-coded in rainbow colours so you can get a sense which story is most important without watching the whole feed – red comes first, followed by orange, yellow, green etc. You could also tweak the RSS feed to give you regional or subject-based news feeds.
Here’s the simple Python code. If you want to make it run at boot, scroll to the end:
import feedparser from sense_hat import SenseHat import re sense = SenseHat() colours = [[255,0,0],[255,165,0],[255,255,0],[0,255,0],[0,0,255],[75,0,130],[238,130,238]] def fetch_weather(): w = feedparser.parse('http://open.live.bbc.co.uk/weather/feeds/en/bs1/3dayforecast.rss') return(w) def fetch_news(): n = feedparser.parse('http://feeds.bbci.co.uk/news/rss.xml') return(n) d = fetch_weather() entries = int(len(d['entries'])) news = fetch_news() counter = 0 while True: counter = counter + 1 for y in range(7): headline = (news['entries'][y]['title']) displayhead = str(y+1)+'.'+headline+' |' sense.show_message(displayhead, text_colour=colours[y]) for x in range(entries): wx = (d['entries'][x]['title']) disp_wx = wx.replace(u"\u00B0",'') disp_wx = disp_wx.replace('Maximum Temperature','High') disp_wx = disp_wx.replace('Minimum Temperature','Low') disp_wx = re.sub(r'\([^)]*\)', '', disp_wx) sense.show_message(disp_wx, text_colour=colours[x]) if counter == 10: d = fetch_weather() news = fetch_news() entries = int(len(d['entries'])) sense.show_message('UPDATING', text_colour=[255,0,0]) counter = 0
So, you want your news & weather ticker to run automatically at boot? Here’s what to do. First run raspi-config, and under ‘boot options’, pick the option to get your Pi to autologin to the text console as the ‘pi’ user. Then reboot and type
sudo nano /etc/profile
at the command line. Add this line at the end and press ctrl-X to exit and save:
sudo python /home/pi/news.py
(assuming you called your script news.py and saved it in that folder). This should now run the script as soon as the ‘pi’ user logs in.
There’s a problem, though. Your script may run before your RaspberryPi has connected to the internet, especially over wifi. So here’s a new version of the script with a new function haz_internet() – this tests for internet access by talking to google.co.uk before continuing the script. (I should probably rejig it so it copes with losing internet access as well.)
Now as soon as your Pi gets power & internet, it will display headlines and weather. Be careful if you ssh in to your Pi, though – it will run another version of the program, making the display go nuts. Crash out of the second copy by pressing ctrl-C. Next step: a graceful shutdown and possibly IP address display using the joystick. Ah. The joystick…
import feedparser from sense_hat import SenseHat import re import socket # function to test for internet access REMOTE_SERVER = "www.google.co.uk" def haz_internet(): try: host = socket.gethostbyname(REMOTE_SERVER) s = socket.create_connection((host, 80), 2) return True except: pass return False sense = SenseHat() colours = [[255,0,0],[255,165,0],[255,255,0],[0,255,0],[0,0,255],[75,0,130],[238,130,238]] def fetch_weather(): w = feedparser.parse('http://open.live.bbc.co.uk/weather/feeds/en/bs1/3dayforecast.rss') return(w) def fetch_news(): n = feedparser.parse('http://feeds.bbci.co.uk/news/rss.xml') return(n) while not haz_internet(): sense.show_message('waiting for internet') d = fetch_weather() entries = int(len(d['entries'])) news = fetch_news() counter = 0 while True: counter = counter + 1 for y in range(7): headline = (news['entries'][y]['title']) displayhead = str(y+1)+'.'+headline+' |' sense.show_message(displayhead, text_colour=colours[y]) for x in range(entries): wx = (d['entries'][x]['title']) disp_wx = wx.replace(u"\u00B0",'') disp_wx = disp_wx.replace('Maximum Temperature','High') disp_wx = disp_wx.replace('Minimum Temperature','Low') disp_wx = re.sub(r'\([^)]*\)', '', disp_wx) sense.show_message(disp_wx, text_colour=colours[x]) if counter == 10: d = fetch_weather() news = fetch_news() entries = int(len(d['entries'])) sense.show_message('UPDATING', text_colour=[255,0,0]) counter = 0