Musik auf Dustcloud-befreiten Xiaomi-Staubsauger

Wenn das Surren des Staubsaugers zu eintönig wird kann man über den eingebauten Lautsprecher Musik abspielen. Es sorgt für gute Stimmung wenn der Staubsauger saugt und gleichzeitig z.B. chinesische Volksweisen trällert.

Auf dem Staubsauger läuft ein altes Ubuntu 14.04, der Sound läuft ganz normal über ALSA.

Xiaomi hat die Ubuntu-Installation extrem abgespeckt: “apt-get” fehlt, ebenso wie andere Tools wie “dpkg”. Was es auf dem Staubsauger gibt ist netcat, ebenso die ALSA-Library. Was es nicht gibt ist ein Programm zum Musik abspielen.

Das einfachste Audio-Abspielprogramm ist “aplay”, es benötigt bis auf die ALSA-Library keine weiteren Bibliotheken. Man kann also einfach das aplay-Binary auf den Staubsauger kopieren.
Mit netcat kann sich der Staubsauger also Musik über’s WLAN holen und die dann per aplay abspielen.

1. asound.conf

Der Soundchip des Staubsauger kann mehrere Audioströme nicht per Hardware zusammenmischen. Um während der Musikwiedergabe auch weiterhin die Sprachausgabe des Staubsaugers zu haben, muss ein dmix-Device angelegt werden. Dazu die Datei “/etc/asound.conf” anlegen:

# /etc/asound.conf
pcm.!default {
   type plug
   slave.pcm "dmixer"
 }
 pcm.dmixer  {
   type dmix
   ipc_key 1024
   slave {
     pcm "hw:0,0"
   }
 }

Dann den Staubsauger neu starten.

2. aplay installieren

  1. Auf dem Staubsauger das Verzeichnis “/mnt/data/local/bin” anlegen.
  2. Aus dem Archiv http://archive.debian.org/debian/pool/main/a/alsa-utils/alsa-utils_1.0.25-4_armhf.deb die Datei “aplay” auf den Staubsauger in das Verzeichnis “/mnt/data/local/bin” kopieren

3. netcat-Poll-Skript anlegen

Das netcat auf dem Staubsauger kann leider nicht auf eingehenden Verbindungen horchen, erst recht nicht auf Multicast-Adressen. Deswegen gehen wir den anderen Weg: Netcat auf dem Staubsauger soll regelmäßig versuchen, sich zu einem anderen Rechner zu verbinden. Wenn dieser anwortet soll netcat die empfangenen Daten an aplay weiterreichen.

Auf dem Staubsauger das Skript “/mnt/data/local/bin/nc-poller.sh” anlegen:

#!/bin/sh
while true; do
    (nc 192.168.3.1 15000 | /mnt/data/local/bin/aplay -c 1 -r 22050) 1>/dev/null 2>/dev/null
    sleep 1
done

192.168,3,1 ist bei mir der Recher, der später die Musik liefern soll. Bei Bedarf also anpassen!

Der Staubsauger kann nur Mono-Sound mit maximal 16 Bit und 22kHz. Aplay kümmert sich um Downsampling und Downmixing.

4. Musik abspielen:

Auf dem Staubsauger “/mnt/data/local/bin/nc-poller.sh” starten.

Dann auf dem Rechner, dessen IP-Adresse in “nc-poller.sh” angegeben ist:

ffmpeg -i tolleMusik.mp3 -filter:a "volume=-6dB" -f wav - | netcat -l 15000 -k

WIP – funktioniert noch nicht – Init-Skript: /etc/init/S12nc-poller:

Schön wäre es, wenn man das nc-poller-Skript nicht manuell starten müsste, sondern dass es direkt beim Starten des Staubsaugers mitgestartet wird.

Dazu auf dem Staubsauger die Datei “/etc/init/S12nc-poller” (siehe unten) anlegen und mit “chmod +x /etc/init/S12nc-poller” ausführbar machen

#!/bin/sh

load() {
    curtime=`cat /proc/uptime | awk -F ' ' '{print $1}'`
    echo "[$curtime] start nc-poller"
    start-stop-daemon -S -b -q -m -p /var/run/nc-poller.pid -x /mnt/data/local/bin/nc-poller.sh
}

unload() {
    echo "stopping nc-poller" >/dev/kmsg
    start-stop-daemon -K -q -p /var/run/nc-poller.pid
    while killall nc-listener.sh; do sleep 1; done
}

status() {
    if [ ! -f /var/run/nc-poller.pid -o -z "$(ps | grep `cat /var/run/nc-poller.pid` | grep -v grep)" ]; then
        echo "nc-poller seems stopped"
    else
        echo "nc-poller seems started"
    fi
}

case "$1" in
    start)
        load
        ;;
    stop)
        unload
        ;;
    restart)
        unload
        load
        ;;
    status)
        status
        ;;
    *)
        echo "$0 <start/stop/restart/status>"
        ;;
esac

Problem: Es kommt nur Gekreische aus dem Lautsprecher. Ohne init-Skript funktioniert’s wunderbar. Warum?