Last active
March 26, 2021 12:42
-
-
Save bikubi/21a1fa9553d96fadbb98e51741ae6e21 to your computer and use it in GitHub Desktop.
Control a web radio stream on a Raspi with GPIO, a button and an LED.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import subprocess as sp | |
import RPi.GPIO as g | |
import time | |
import os | |
# see http://cyfta.com/?p=8480 | |
# & listen to WFMU! http://wfmu.org | |
# "constants", change these. | |
# raspi pinout | |
pin_button = 4 | |
pin_led = 17 | |
# seconds before we accept another input | |
# (give mplayer time to terminate) | |
input_delay = 5 | |
# run 'id' to see these | |
user_name = 'pi' | |
user_id = 1000 | |
user_gid = 1000 | |
user_home_dir = '/home/pi' | |
# do not change the URL. | |
player_cmd = ["mplayer", "-quiet", "http://stream0.wfmu.org/freeform-high.aac"] | |
print "setting up pins..." | |
g.setmode(g.BCM) | |
g.setup(pin_button, g.IN) | |
g.setup(pin_led, g.OUT) | |
# run subprocess as different, non-root user | |
# https://stackoverflow.com/a/6037494 | |
def demote (): | |
def result (): | |
global user_name, user_id, user_gid | |
#os.setgid(1001) | |
# we need initgroups to set all groups, including 'audio' | |
os.initgroups(user_name, user_gid) | |
os.setuid(user_id) | |
print 'demoted %d %d' % (os.getgid(), os.getuid()) | |
return result | |
env = os.environ.copy() | |
env[ 'HOME' ] = user_home_dir | |
env[ 'LOGNAME' ] = user_name | |
env[ 'PWD' ] = user_home_dir | |
env[ 'USER' ] = user_name | |
p = None | |
blink = False | |
wait = 0 | |
def play (): | |
global p, blink, player_cmd, user_home_dir | |
if p is not None and p.poll() is None: | |
print "seems to be playing. terminating!" | |
p.terminate() | |
if p is None or p.poll() is not None: | |
print "play!" | |
p = sp.Popen( | |
player_cmd, | |
preexec_fn = demote(), | |
cwd = user_home_dir, | |
env = env | |
) | |
def stop (): | |
global p | |
print "terminating!" | |
p.terminate() | |
# let the led flutter! | |
def flutter (length, delay): | |
for x in range(0, length): | |
g.output(pin_led, g.LOW if x % 2 == 0 else g.HIGH) | |
time.sleep(delay) | |
flutter(6, 0.05) # hi! | |
print "starting polling..." | |
while True: | |
poll = p.poll() if p is not None else -1 | |
# we could do this using events... | |
if g.input(pin_button) == g.HIGH: | |
# if we are not blocked by a previous input... | |
if wait == 0: | |
flutter(6, 0.05) | |
wait = input_delay | |
if poll is None: | |
stop() | |
else: | |
play() | |
else: | |
# if we're blocked, give visual feedback | |
flutter(50, 0.02) | |
blink = not blink if poll is None else False | |
g.output(pin_led, g.LOW if blink else g.HIGH) | |
wait = wait - 1 if wait > 0 else 0 | |
time.sleep(1) # adjust this to poll for input faster |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment