RasPi + RFID + Sonos http API

Dieses kleine Projekt ist aus der Not entstanden, dass ich für meine Kinder nicht dauernd den Hörspiel-Jockey spielen wollte. Was gibt es da naheliegenderes als einen alten RasPi zu mobilisieren, einen RFID Kartenleser drauf zu bauen und über die Sonos API dann im Kinderzimmer (oder wo auch immer) das entsprechende Hörspiel oder Lied abzuspielen.

Folgend die Aubauschritte:

  • RasPi + RFID zum Laufen bekommen
  • Über RFID Token ein Gerät auswählen
  • Über RFID Token eine Playlist starten auf dem zuvor gewählten Gerät
  • Über den selben RFID Token in der Playliste (bei Hörspielen) mehrere Songs weiter springen zur nächsten Folge
  • Über RFID Token eine Gerätegruppe zusammenfügen oder auflösen

Dafür klaube ich mir Informationen von mehreren Entwicklern zusammen und verarbeite sie in den Projekt:

  • [1] Als Grundlage für RFID:
    https://tutorials-raspberrypi.de/raspberry-pi-rfid-rc522-tueroeffner-nfc/
  • [2] Die Steuerung der Sonos:
    https://github.com/jishi/node-sonos-http-api

Die Sonos API läuft schon auf einem anderen PI (v4) und die habe ich nach der Anleitung [2] eingerichtet. Kurz umrissen:

  • Installiert nodeJS > v6
  • Klont das node-sonos-http-api Repository lokal (bei mir in /home/pi/sonos_api/node-sonos-http-api)
  • in dem Verzeichnis des Repos: npm install -production
  • npm start

Zur Kontrolle könnt ihr jetzt auf dem PI jetzt http://localhost:5005/ aufrufen und erhaltet eine einfache Oberfläche mit vielen Möglichkeiten.

Um die API automatisch zu starten (bei Systemstart) habe ich sie als systemd eingebunden:

Erstellt die Datei /etc/systemd/system/sonosAPI.service mit folgendem Inhalt:

[Unit]
Description=SonosAPI
After=network.target

[Service]
ExecStart=/home/pi/.config/nvm/versions/node/v15.6.0/bin/node /home/pi/sonos_api/node-sonos-http-api/server.js
WorkingDirectory=/home/pi/sonos_api/node-sonos-http-api
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi

[Install]
WantedBy=multi-user.target

Die beschreibt wie der Dienst heißt und wie er gestartet wird. Um ihn jetzt im System einzubinden muss man noch die Daemons neu laden, starten und für in den Boot einreihen:

sudo systemctl daemon-reload
sudo service sonosAPI start
sudo systemctl enable sonosAPI

Jetzt könnt ihr zum Test einmal den PI neu starten und schauen, ob ihr wieder http://localhost:5005 erreicht.


Ich verwende erstmal einen RasPi 1B v1.0 um RFID einzurichten. Ich würde nur auf neuere Hardware gehen, wenn der leistungstechnisch nicht aussreicht. Momentan ist Buster die aktuelle Version des Raspi Betriebssystems.

Mit der gelinkten Anleitung kam ich schon nah ran, brauchte aber noch einige Versuche, bis ich merkte, was anders ist. Die GPIO PIN-Belegung war soweit okay, nur der Reset hat wahrscheinlich gestört.

Ich habe die manuellen Anpassungen der /boot/config.txt auch rückgängig gemacht. Folglich ergeben sich die Schritte:

1. Anschließen des RFID Moduls

RF522 ModulRaspberry Pi
SDAPin 24 / GPIO8 (CE0)
SCKPin 23 / GPIO11 (SCKL)
MOSIPin 19 / GPIO10 (MOSI)
MISOPin 21 / GPIO9 (MISO)
IRQ
GNDPin 6 / GND
RST
3.3VPin 1 (3V3)
Pinbelegung zwischen RasPi und RF522

2. Aktiviere die SPI Schnittstelle

Starte auf einem Terminal oder per ssh den Raspberry Pi Konfigurator

sudo raspi-config

Aktiviere SPI über „Interface Options“ > „P4 SPI“ > „Yes“
und starte den Pi neu.

sudo reboot

Wenn man in /dev jetzt die Geräte spidev0.0 und spidev0.1 findet ist alles soweit bereit.

$ ls -la /dev/spi*
crw-rw---- 1 root spi 153, 0 Jul 4 20:21 /dev/spidev0.0
crw-rw---- 1 root spi 153, 1 Jul 4 20:21 /dev/spidev0.1

3. Nun brauchen wir eine SPI-Python Implementierung, da habe ich auch eine neue gesucht, weil ich nicht wusste, woran es lag, dass ich Erkennungsprobleme hatte. Da fand ich diese, die auch die modernere bcm2835 erwähnt. Das war mir sympatisch genug und es gibt einen branch mit modefix dafür. So geht’s weiter (im Home vom pi user auf dem RasPi):

git clone https://github.com/pelwell/SPI-Py.git
cd SPI-Py
git checkout modefix
sudo python setup.py install

4. Und dann brauchen wir die MFRC522-python Implementierung um einen Ansatz zu haben und einen Check zu machen, ob die Konfiguration so funktioniert. Dazu habe ich mich ein bisschen durch die Forks gesucht und bin letztendlich bei diesem gelandet, weil er mir am aktuellsten scheint https://github.com/mahotd/MFRC522-python-7bytecompatible.git . So geht’s weiter (im Home vom pi user auf dem RasPi):

git clone https://github.com/mahotd/MFRC522-python-7bytecompatible.git
cd MFRC522-python-7bytecompatible
sudo python3 Read.py

Und das ganze funktioniert mit den mitgelieferten Tags ganz gut, scheint aber etwas instabil. Nach einer unbestimmt langen Zeit erkennt das Programm die Tags nicht mehr und reagiert nicht mehr. Dann muss man es abbrechen und wieder versuchen.

5. Trotzdem möchte ich auf dem Fork starten und meine Applikation darauf testen. Also machte ich davon meinen eigenen Fork und benannte ihn um zu https://github.com/chechirecat/MFRC522-python-sonos-control

Auf dem werde ich also meine Änderungen bringen und so hoffentlich die gewünschte Steuerungen und Ideen implementieren.

Um jetzt die Sonos API ansprechen zu können braucht man ein weiteres Python Modul „requests“ (das bei mir schon installiert war) . Um auch zu hektische Steuerung zu verhindern habe ich noch einen Timeout von 5 Sekunden implementiert, damit z.B. den play / stop toggle nicht im maximal möglichen Intervall ausführt.

Mit diesen beiden Erweiterungen und ein paar UID Abfragen hatte ich dann schon meinen Toggle auf einem der Lautsprecher implementiert und konnte eine Playlist (leider keine einzelnen Lieder) starten und pauschal habe ich ein Lautstärke eingestellt.

Bisheriges Fazit: Proof of Concept ist abgeschlossen und die Idee umsetzbar. Mal schauen wann es weiter geht mit mehr Details.