PDA

View Full Version : rssrds - RSS feeds via RDS


cmantito
2011-01-11, 11:55
Hey folks,

I've written a Python script that monitors the first item of an RSS feed at a set interval, and when it changes, it scrolls it across the display of your radio over RDS. This is part of my New Year's resolution to reasonably familiarise myself with Python and DBus. :P

The script takes three parameters: the rss refresh time, the rds update time and the URL of an RSS feed. The former two parameters are both in seconds, and will happily accept floats (e.g. 1.5 or 0.75).

Things of note:

First, the phone will vibrate (PatternIncomingMessage) as it outputs the data to the radio. I wanted it to play a sound notification, but I haven't made this work yet. (Open to suggestions though! :) ) So far I've tried using both pygame and gstreamer to play a wav file. pygame didn't work at all, for me. gstreamer did, but only when the Media Player WASN'T playing anything. (Which is unfortunate; if you're using the FM transmitter (and therefore RDS), it probably is.) I used a DBus call to try to pause the media player, play my alert and resume playing, but this didn't work either. I think I've come to the conclusion that, for some reason, it's only working when the media player is *stopped*. I'm not sure why, and am open to advice :) I was also marginally disappointed to find that this implementation of freedesktop.Notification doesn't support the sound-file hint for alerts...

This requires python-feedparser, which I found with 'apt-get install python-feedparser'.

If you end the application by pressing Ctrl+C, press it once, and give it a second. It may display an error, but it will exit after a cycle of rdsRefresh, and return your RDS display to normal.

On the topic of RDS, this scrolls it across as the station name (rds_ps) rather than using the text. This is because my car doesn't support the 64-character text portion, just the 8-character station name. Some radios seem to have trouble updating the display frequently with the scrolling text. They don't update the characters in order and look garbled. If this happens, try a slower rdsRefresh value (2.5-4 perhaps? a bit slow for scrolling, but still...). My car is quite good at it (Peugeot 206 with stock Clarion RD3 radio), and works very nicely with an rdsRefresh between 0.9-1.25.

Lastly, the disclaimer: It's not necessarily safe to read RSS feeds while driving. It's not my fault if you do and Bad Stuff happens. Be careful with it. Personally, I use it with a feed that almost never updates, and when it does, it's pertinent to my driving: the UK Highways Agency traffic alerts feed (http://www.highways.gov.uk/traffic/11278.aspx). That's originally what I intended to use this for, but I decided to expand it to work with any RSS feed, really. I also thought about a similar Twitter client, but I think that's probably going into the realm of too distracting.

So, the script (rssrds.py):

#!/usr/bin/python

import feedparser
import dbus
import time
import sys

# These must be 8 chars:
headerAlert = "********"
newItemAlert = "NEW ITEM"
waitingAlert = "Nokia "

try:
rssRefresh = float(sys.argv[1])
rdsRefresh = float(sys.argv[2])
url = sys.argv[3]
except:
print "Usage: rssrds.py [RSS refresh in sec] [RDS update in sec] [rss feed url]"
sys.exit(1)

system_bus = dbus.SystemBus()
fmtx = system_bus.get_object('com.nokia.FMTx', '/com/nokia/fmtx/default', False)
fmtx_iface = dbus.Interface(fmtx, dbus_interface='org.freedesktop.DBus.Properties')

mce = system_bus.get_object('com.nokia.mce', '/com/nokia/mce/request', False)

try:

scrollRun = 0
lastItem = ''
while 1 == 1:
time.sleep(rssRefresh)
rss = feedparser.parse(url)

if rss['entries'][0]['title'] != lastItem:
lastItem = rss['entries'][0]['title']
itemTitle = lastItem

mce.req_vibrator_pattern_activate(u'PatternIncomin gMessage')

fmtx_iface.Set("com.nokia.FMTx.Device", "rds_ps", dbus.String(u'%s' % headerAlert, variant_level=1))
print headerAlert
time.sleep(rdsRefresh)

fmtx_iface.Set("com.nokia.FMTx.Device", "rds_ps", dbus.String(u'%s' % newItemAlert, variant_level=1))
print newItemAlert
time.sleep(rdsRefresh)

mce.req_vibrator_pattern_deactivate(u'PatternIncom ingMessage')

if len(itemTitle) > 8:
scrollCount = 7
while scrollCount <= len(itemTitle):
nowPart = itemTitle[(scrollCount - 7):scrollCount]
fmtx_iface.Set("com.nokia.FMTx.Device", "rds_ps", dbus.String(u'%s' % nowPart, variant_level=1))
print nowPart
time.sleep(rdsRefresh)
scrollCount = scrollCount + 1

elif len(itemTitle) == 8:
fmtx_iface.Set("com.nokia.FMTx.Device", "rds_ps", dbus.String(u'%s' % itemTitle, variant_level=1))
print itemTitle
time.sleep(rdsRefresh)

elif len(itemTitle) < 8:
padding = 8-len(itemTitle);
while padding > 0:
itemTitle = itemTitle + " "
padding = padding - 1

fmtx_iface.Set("com.nokia.FMTx.Device", "rds_ps", dbus.String(u'%s' % itemTitle, variant_level=1))
print itemTitle
time.sleep(rdsRefresh)

fmtx_iface.Set("com.nokia.FMTx.Device", "rds_ps", dbus.String(u'%s' % waitingAlert, variant_level=1))
print waitingAlert

except:
mce.req_vibrator_pattern_deactivate(u'PatternIncom ingMessage')
fmtx_iface.Set("com.nokia.FMTx.Device", "rds_ps", dbus.String(u"ERROR ", variant_level=1))
print "Error: Invalid feed or could not fetch URL."
time.sleep(4)
fmtx_iface.Set("com.nokia.FMTx.Device", "rds_ps", dbus.String(u'%s' % waitingAlert, variant_level=1))
sys.exit(2)

# END

As I slowly move into another part of my New Year's resolution, learning PyQt, I may add a Qt config panel to this and try packaging it up. We'll see how things go. Still needs a lot of work, I know. Suggestions welcome.

Additionally, thanks mirakels; I referenced this post (http://forums.internettablettalk.com/showpost.php?p=605823&postcount=12) a bit in dealing with the RDS DBus API in python.

gazza_d
2011-01-11, 12:04
Cool, this is quite a nice little script. Pity I have just upgraded to a car Stereo with bluetooth!

As an aside, I actually found that in my part of the world the highways agency rss feed (North East England) contains all of Yorkshire as well, and is too large an area with the vast bulk of the alerts being in Yorkshire.

The BBC local radio traffic RSS feeds may be a better alternative, they are for me, and my local one already has a twitter feed @tynesideroads.

cmantito
2011-01-11, 12:11
The BBC local radio traffic RSS feeds may be a better alternative, they are for me, and my local one already has a twitter feed @tynesideroads.

Thanks, I'll look into that. The Highways Agency one updates a bit slow for my liking anyway - half the time they update it after I've already driven through the issue! :P