diff options
Diffstat (limited to 'daemon.py')
-rwxr-xr-x | daemon.py | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/daemon.py b/daemon.py new file mode 100755 index 0000000..a66c8c5 --- /dev/null +++ b/daemon.py @@ -0,0 +1,130 @@ +#!/usr/bin/python + +import serial +import mpd +import time +import sys + +class Config: + display_lines = 2 + display_width = 16 + display_length = display_lines * display_width + +class Daemon: + line = "" + playing = False + + def __init__(self): + self.ser = serial.Serial(sys.argv[1], 9600, timeout=1) + + # raise timeout to let arduino start up + self.ser.timeout = 15 + incoming = self.readline() + + # arduino sometimes has a dirty buffer + # and sends junk before the ready message + if not incoming.endswith("ready"): + sys.stderr.write("Got unexpected reply: "+incoming) + raise Exception("Wrong client greeting") + self.ser.timeout = 1 + + self.client = mpd.MPDClient() + self.client.connect("localhost", 6600) + + def readline(self): + return self.ser.readline().decode("ascii").strip() + + def update(self): + old_line = self.line + old_playing = self.playing + changed = False + + incoming = self.client.currentsong() + + self.line = incoming["artist"] + " - " + incoming["title"] + if self.line != old_line: + changed = True + + self.playing = self.client.status()["state"] == "play" + if self.playing != old_playing: + changed = True + + return changed + + def run(self): + self.update() + + last_display_update = 0.0 + last_song_update = 0.0 + now = 0.0 + time_diff = 0.0 + current_position = 0 + + while 1: + now = time.time() + + # check for incoming commands from arduino + if self.ser.inWaiting() > 0: + incoming = self.readline() + + functions = { + "next": self.client.next, + "previous": self.client.previous, + "pause": self.client.pause, + } + try: + func = functions[incoming] + func() + + # force redraw if anything changed + if self.update(): + last_display_update = 0 + current_position = 0 + + except KeyError: + pass + + # check if song changed + # TODO: use idle and poll (more often)? + time_diff = now - last_song_update + if time_diff > 2.5 or time_diff < -60.0: + last_song_update = now + if self.update(): + last_display_update = 0 + current_position = 0 + + # update arduino display + time_diff = now - last_display_update + if time_diff > 0.8 or time_diff < -60.0: + last_display_update = now + if self.playing: + i = current_position + + if i - 1 + Config.display_length == len(self.line): + i = 0 + + if i == 0: + # allow people to start reading + last_display_update += 2 + + if len(self.line) > Config.display_length: + buf = self.line[i:i+Config.display_length] + else: + buf = self.line.ljust(Config.display_length, " ") + + i += 1 + current_position = i + else: + buf = "-- PAUSED --".center(Config.display_width, " ").ljust(Config.display_length, " ") + + # always start at the beginning if we unpause + current_position = 0 + + print("'" + buf + "'") + self.ser.write(bytes(buf, "ascii", "replace")) + + time.sleep(0.05) + +if __name__ == '__main__': + d = Daemon() + d.run() |