Pi Hacking #3

ETV Viewers Count

Published on . Takes less than 1 minute to read.

Just for fun and practice - wouldn't it be cool to have a 4-digit, 7-segment LED display that shows the number of online visitors to... something?

A nice candidate for the data provider was ETV, a national public television station that's viewable online. Its web interface refreshes the viewer count via HTTP queries to an internal JS API that suits our needs quite well.

Hooking up the LED display backpack was easy. Some quick Python code to do the parsing and display... and we have a nice physical, real-time counter to see how many people are watching the channel at the moment.

err.py
#!/usr/bin/python

# Show the number of viewers of ERR ETV online TV-channel on a 7-segment LCD
# Built for the Raspberry Pi
# 
# http://otse.err.ee/etv/
# https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_LEDBackpack/Adafruit_7Segment.py
# https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_LEDBackpack/Adafruit_LEDBackpack.py
# https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_I2C/Adafruit_I2C.py
# 
# Author Ando Roots <ando [at] sqroot [dot] eu> 2013

import time, urllib2
from Adafruit_7Segment import SevenSegment
import RPi.GPIO as GPIO

class ERROnline:
    
    # Refresh interval in seconds
    CHECK_INTERVAL = 10
    
    # ERR internal API endpoint, gives JS output
    API_URL = 'http://otse.err.ee/xml/live-etv.html'
    
    # 7-segment display (run i2cdetect -y 1 to get the addr)
    segment = SevenSegment(address=0x70)
    
    # Write a 4-digit number to the LCD
    def write_number(self, value):
        value = int(value)
        if value > 9999:
            print "Value %s is out of bounds, setting to 9999" % value
            value = 9999
        value = str(value).zfill(4)
        self.segment.writeDigit(0, int(value[0]))
        self.segment.writeDigit(1, int(value[1]))
        self.segment.writeDigit(3, int(value[2]))
        self.segment.writeDigit(4, int(value[3]))
        return self
    
    # Does an HTTP API query and returns the number of online viewers
    def get_online_count(self):
        js_response = urllib2.urlopen(self.API_URL).read()
        parts = js_response.split("$('#viewers').html('")
        return parts[1].split("');")[0]
    
    # Main loop
    def run(self):
        print "Running the program - press Ctrl + C to exit."
        time.sleep(2)
        
        previous_count = 0
        while True:
            self.segment.setColon(1)
            
            online_count = self.get_online_count()
            
            # Change LCD / stdout 
            if online_count != previous_count:
                check_time = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
                print "[%s] ETV Online: %s people watching." % (check_time, online_count)
                self.write_number(online_count)
                previous_count = online_count
                
            self.segment.setColon(0)
            time.sleep(self.CHECK_INTERVAL)
            
    # Cleanup on exit
    def __del__(self):
        self.segment.disp.clear()
        
# Run the program
monitor = ERROnline().run()

View gist on GitHub

Hardwarepythonapiraspberry pierretv