Install phatbeatd as a daemon.

This commit is contained in:
piradio 2019-05-22 20:44:29 +02:00
parent 3cfbef44ac
commit 003e319699
4 changed files with 344 additions and 0 deletions

View File

@ -10,3 +10,5 @@ install -v -m 755 files/vlcd "${ROOTFS_DIR}/etc/init.d/"
install -v -m 755 files/bin/vlcd "${ROOTFS_DIR}/usr/bin/"
mkdir "${ROOTFS_DIR}/etc/vlcd"
install -v -m 644 files/default.m3u "${ROOTFS_DIR}/etc/vlcd/"
install -v -m 755 files/phatbeatd "${ROOTFS_DIR}/etc/init.d/"
install -v -m 755 files/bin/phatbeatd "${ROOTFS_DIR}/usr/bin/"

View File

@ -9,3 +9,4 @@ autoconf && automake --add-missing
make install
systemctl daemon-reload
systemctl enable vlcd
systemctl enable phatbeatd

View File

@ -0,0 +1,231 @@
#!/usr/bin/env python
import atexit
import re
import socket
import subprocess
import time
import os
import signal
import sys
from datetime import datetime
VLC_HOST = "127.0.0.1"
VLC_PORT = 9294
LOG_LEVEL = 0
PIDFILE = "/var/run/phatbeatd.pid"
LOGFILE = "/var/log/phatbeatd.log"
ERRFILE = "/var/log/phatbeatd.err"
SHUTDOWN_HOLD_TIME = 3
LOG_INFO = 0
LOG_WARN = 1
LOG_FAIL = 2
LOG_DEBUG = 3
def log(msg, level=LOG_INFO):
if level < LOG_LEVEL: return
sys.stdout.write(str(datetime.now()))
sys.stdout.write(": ")
sys.stdout.write(msg)
sys.stdout.write("\n")
sys.stdout.flush()
class VLC():
def __init__(self, host="127.0.0.1", port=9294):
self.host = host
self.port = port
self.current_stream = None
self.current_state = None
self.connecting = False
self.socket = None
def send(self, command):
if self.connecting:
return False
log("Sending command: {}".format(command), level=LOG_INFO)
command_string = command + "\n"
if sys.version_info[0] >= 3:
command_string = command_string.encode("utf-8")
try:
self.socket.send(command_string)
except socket.error:
log("Failed to send command to VLC", level=LOG_WARN)
if self.connect():
self.send(command)
def recv(self, length):
value = self.socket.recv(8192)
if sys.version_info[0] >= 3:
value = value.decode("utf-8")
return value
def communicate(self, command, response_length=8192):
self.send(command)
return self.recv(response_length)
def get_current_stream(self):
self.send("status")
status = self.recv(8192)
result = re.search("input:\ (.*)\ ", status)
state = re.search("state\ (.*)\ ", status)
if state is not None:
self.current_state = state.group(1)
if result is not None:
self.current_stream = result.group(1)
else:
self.current_stream = None
return self.current_stream
def connect(self):
if self.connecting:
return
self.connecting = True
if self.socket is not None:
self.socket.close()
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
for attempt in range(10):
try:
log("Attempting to connect to VLC on {host}:{port}".format(host=self.host, port=self.port))
self.socket.connect((self.host, self.port))
log("Connection successful!", level=LOG_INFO)
self.connecting = False
return True
except socket.error:
time.sleep(1)
log("Connection failed!", level=LOG_FAIL)
self.connecting = False
return False
if __name__ == "__main__":
stdin = None
stdout = None
stderr = None
fpid = None
daemonize = True
pid = None
def _signal_handler(signal, frame):
_cleanup()
sys.exit(0)
def _cleanup():
log("Exiting cleanly")
try:
os.remove(PIDFILE)
except OSError:
pass
if stdin is not None: stdin.close()
if stdout is not None: stdout.close()
if stderr is not None: stderr.close()
if daemonize:
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
log("Fork #1 failed: {} ({})".format(e.errno, e.strerror))
sys.exit(1)
os.chdir("/")
os.setsid()
os.umask(0)
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
log("Fork #2 failed: {} ({})".format(e.errno, e.strerror))
sys.exit(1)
pid = os.getpid()
fpid = open(PIDFILE, 'w')
fpid.write(str(pid))
fpid.close()
log("PHAT BEAT {} running with PID: {}".format("daemon" if daemonize else "process",pid))
stdin = file("/dev/null", 'r')
stdout = file(LOGFILE, 'a+')
stderr = file(ERRFILE, 'a+')
os.dup2(stdin.fileno(), sys.stdin.fileno())
os.dup2(stdout.fileno(), sys.stdout.fileno())
os.dup2(stderr.fileno(), sys.stderr.fileno())
vlc = VLC(host=VLC_HOST, port=VLC_PORT)
if vlc.connect():
import phatbeat
phatbeat.set_all(0,128,0,0.1)
phatbeat.show()
time.sleep(1)
phatbeat.clear()
phatbeat.show()
@phatbeat.on(phatbeat.BTN_VOLDN)
def pb_volume_down(pin):
log(vlc.communicate("voldown"))
@phatbeat.on(phatbeat.BTN_VOLUP)
def pb_volume_up(pin):
log(vlc.communicate("volup"))
@phatbeat.on(phatbeat.BTN_PLAYPAUSE)
def pb_play_pause(pin):
log(vlc.communicate("pause"))
time.sleep(0.1)
phatbeat.clear()
phatbeat.show()
@phatbeat.on(phatbeat.BTN_FASTFWD)
def pb_fast_forward(pin):
log(vlc.communicate("next"))
@phatbeat.on(phatbeat.BTN_REWIND)
def pb_rewind(pin):
log(vlc.communicate("prev"))
@phatbeat.on(phatbeat.BTN_ONOFF)
def perform_shutdown(pin):
log(vlc.communicate("pause"))
os.system("sudo shutdown -h now")
signal.signal(signal.SIGINT, _signal_handler)
signal.signal(signal.SIGTERM, _signal_handler)
signal.pause()
_cleanup()
sys.exit(0)
else:
_cleanup()
sys.exit(1)

View File

@ -0,0 +1,110 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: phatbeatd
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts PHAT BEAT VLC control daemon at boot time
# Description: Manages the PHAT BEAT VLC control daemon
### END INIT INFO
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Picade HAT Daemon"
NAME=phatbeatd
DAEMON=/usr/bin/$NAME
PIDFILE=/var/run/$NAME.pid
LOGFILE=/var/log/$NAME.log
ERRFILE=/var/log/$NAME.err
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then
echo 'Service already running' >&2
return 1
fi
echo 'Starting...' >&2
su -c "$DAEMON" root
}
#
# Function that stops the daemon/service
#
do_stop()
{
if [ ! -f "$PIDFILE" ] || ! kill -0 $(cat "$PIDFILE"); then
echo 'Service not running' >&2
return 1
fi
echo 'Stopping...' >&2
kill $(cat "$PIDFILE")
echo 'Service stopped!' >&2
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
: