Apr-25-2017, 08:49 PM
my question here
I have these two script working perfectly on my Raspberry pi and Arduino respectively.
I am trying to add in two features to the code at this point.
Thank you!
I have these two script working perfectly on my Raspberry pi and Arduino respectively.
I am trying to add in two features to the code at this point.
- Add a skip button that is tied to the Arduino and skips through the songs in the queue of the py code
- Add a "play series of mp3 clips while the RPI is in an idle or inactive state
Thank you!
#!/usr/bin/env python import glob import json import os import random import select import serial import socket import subprocess import sys import time import traceback SERIAL = (glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') + [''])[0] PORT = 55555 LETTERS = "ABCDEFGHJKLMNPQRSTUV" NUMBERS = range(1,9) CONFIG = '/var/jukebox/config.json' DevNull = open('/dev/null','rw') config = {} def readConfig(): global config config = { 'dup': False, 'rpt': False, 'rnd': False, 'lim': 0, } try: conf = json.loads(open(CONFIG).read()) for k,v in config.items(): config[k] = type(v)(conf[k]) except: pass readConfig() try: ser = serial.Serial(SERIAL) ser.setBaudrate(9600) except: ser = None traceback.print_exc() Q = [] p = None filename = None def play(filename): p = subprocess.Popen(('play', filename), stdout = DevNull, stdin = DevNull, stderr = DevNull) return p def playGlob(filenameGlob): filenames = glob.glob(filenameGlob) if (len(filenames) == 1): filename = filenames[0] return (filename, play(filename)) return None class AtomicFile(object): def __init__(self, filename, mode = 'w'): self.filename = filename self.new = filename + ".new" self.w = open(self.new, mode) def __enter__(self, *extra): #print(extra) return self.w def __exit__(self, *extra): #print(extra) self.w.close() os.rename(self.new, self.filename) def process(data, address): global p global Q if not data: return print(data, address) if (data == 'Stop'): if p: p.kill() return if (data == 'Flush'): Q = [] return if (data == 'Shutdown'): os.system("sudo /sbin/poweroff") return if (data == 'Play'): return try: data = data.split() if (len(data) != 2): return (letter, number) = data assert(letter in LETTERS) number = int(number) assert(number in NUMBERS) Q.append((letter, number, time.time(), address)) except: traceback.print_exc() def dump(data): with AtomicFile('/dev/shm/jukebox.json') as w: w.write(json.dumps(data, indent=4, sort_keys=1)) # Create a UDP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Bind the socket to the port sock.bind(('0.0.0.0', PORT)) if ser: rs = (sock, ser) else: rs = (sock,) while True: readConfig() print(config) if config['lim']: Q = Q[:config['lim']] if config['rnd']: random.shuffle(Q) (r,w,x) = select.select(rs,(),(),1) try: if sock in r: (data, address) = sock.recvfrom(4096) process(data, address) elif ser in r: try: data = ser.readline().strip() except: rs = (sock,) process(data, SERIAL) except: pass if p: if p.poll() is not None: print(p.wait()) p = None filename = None else: print(filename) if Q: if p: print(Q) else: (letter, number, epoch, address) = Q.pop(0) if config['rpt']: Q.append((letter, number, epoch, address)) if not config['dup']: while Q: (l, n, e, a) = Q[0] if (l == letter) and (n == number): Q.pop(0) else: break p = playGlob("/var/jukebox/%s/%d/*" % (letter, number)) if p: (filename, p) = p elif p: print(filename) else: print('.') dump({'current': filename, 'length' : len(Q), 'queue' : Q, })