summaryrefslogtreecommitdiffstats
path: root/daemon.py
diff options
context:
space:
mode:
Diffstat (limited to 'daemon.py')
-rwxr-xr-xdaemon.py130
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()