Projekt: PlayBox per RFID, MQTT, FHEM und Spotify

Mit ** gekennzeichnete Links auf dieser Seite sind Affiliatelinks.

Projekt: PlayBox per RFID, MQTT, FHEM und Spotify
Projekt: PlayBox per RFID, MQTT, FHEM und Spotify
  • Matthias Kleine
  • 16.12.2018
  • Projekt

Du kennst eventuell diese kleinen Lautsprecher für Kinder, auf welche Figuren aufgesteckt werden können und dann die damit verknüpfte Musik oder das Hörbuch abgespielt wird. Genau soetwas wollte ich gerne super günstig nachbauen. Ziel ist es, dass man RFID-Tags in Figuren versteckt, diese dann auf eine Box stellt und dann über Spotify die Geschichte dazu abspielt. Quelle der Audio-Dateien ist dabei ganz einfach Spotify. Dort gibt es unendlich viele Inhalte von Benjamin Blümchen bis Bibi Blocksberg. Als Ausgabegerät kann zum Beispiel ein Amazon Echo dienen. Angesteuert und verwaltet wird alles über FHEM.

Was Du brauchst?

  • Eine FHEM-Installation (inkl. Spotify-Integration) + MQTT-Broker
  • Eine NodeMCU
  • Einen RFID-Reader und ein paar Tags
  • Am besten einen 3D-Drucker

Video

Hausbau-Kurs

Produkte

AZDelivery NodeMCU Lolin V3 Module ESP8266 ESP-12F WiFi WiFi Development Board mit CH340 kompatibel mit Arduino inklusive E-Book! **

AZDelivery RFID Kit RC522 mit Reader, Chip und Card 13,56MHz SPI kompatibel mit Arduino und Raspberry Pi inklusive E-Book! **

Schaltplan

PlayBox

»PlayBox«

Befehle und Code

Die NodeMCU musst Du mit dem folgenden Programm bespielen. Vorher natürlich ein paar Punkte anpassen:

  • WLAN SSID und Passwort
  • MQTT Host, Benutzer und Passwort
  • ggf. MQTT-Topics

der Rest sollte genau so funktionieren. Natürlich brauchst Du diese beiden Libraries damit alles baut:

#include <Arduino.h>
#include <SPI.h>
#include <MFRC522.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>

#define SS_PIN D8
#define RST_PIN D1

MFRC522 mfrc522(SS_PIN, RST_PIN);
unsigned long cardId = 0;

WiFiClient net;
PubSubClient client(net);

const char* mqtt_server = "192.168.44.11";
const char* ssid = "...";
const char* password = "...";

void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();

  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);

  client.setServer(mqtt_server, 1883);
}

void reconnect() {
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
  }

  while (!client.connected()) {
    String clientId = "NodeMCUClient-";
    clientId += String(random(0xffff), HEX);

    if (!client.connect(clientId.c_str(), "sonoff", "...")) {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");

      delay(5000);
    }
  }
}

void loop() {
  reconnect();

  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  cardId = getCardId();

  Serial.print("New ");
  Serial.println(cardId);

  char buffer[10];
  sprintf(buffer, "%lu", cardId);
  client.publish("/SmartHome/Interface/PlayBox/Play", buffer);

  uint8_t control = 0x00;

  do {
    control = 0;
    for (int i = 0; i < 3; i++) {
      if (!mfrc522.PICC_IsNewCardPresent()) {
        if (mfrc522.PICC_ReadCardSerial()) {
          control |= 0x16;
        }

        if (mfrc522.PICC_ReadCardSerial()) {
          control |= 0x16;
        }

        control += 0x1;
      }

      control += 0x4;
    }

    delay(0);
  } while (control == 13 || control == 14);

  reconnect();

  Serial.println("Removed");
  client.publish("/SmartHome/Interface/PlayBox/Stop", "1");
  delay(500);

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

unsigned long getCardId() {
  byte readCard[4];
  for (int i = 0; i < 4; i++) {
    readCard[i] = mfrc522.uid.uidByte[i];
  }

  return (unsigned long)readCard[0] << 24
    | (unsigned long)readCard[1] << 16
    | (unsigned long)readCard[2] << 8
    | (unsigned long)readCard[3];
}

Weiter geht es in FHEM. Als erstes das Gerät, welches uns die Topics aus MQTT zu Readings macht.

define PlayBox MQTT_DEVICE
attr PlayBox userattr subscribeReading_play subscribeReading_stop
attr PlayBox IODev Mosquitto
attr PlayBox event-on-update-reading play,stop
attr PlayBox icon rc_VOLUP
attr PlayBox stateFormat play
attr PlayBox subscribeReading_play /SmartHome/Interface/PlayBox/Play
attr PlayBox subscribeReading_stop /SmartHome/Interface/PlayBox/Stop

Jetzt fehlt nur noch die Logik zum Abspielen und Pausieren. Wie immer: Erst das Gerät anlegen ohne Logik, dann auf DEF klicken und den Perl-Code einfügen.

define n_PlayBox notify PlayBox:play:.* {}
PlayBox:play:.* {

	my $spotifyTrack = ReadingsVal($NAME, 'card_' . $EVTPART1, 'undef');
	if ($spotifyTrack ne 'undef') {
		my $lastPlayedTrackURI = ReadingsVal($NAME, 'lastPlayedTrackURI', 'unknown');

		if ($lastPlayedTrackURI eq $spotifyTrack && ReadingsVal('Spotify', 'track_uri', '-') eq $lastPlayedTrackURI) {
			fhem("set Spotify resume");
		} else {
			fhem("set Spotify playTrackByURI " . $spotifyTrack);
			fhem("setreading $NAME lastPlayedTrackURI " . $spotifyTrack);
		}
	} else {
		fhem("setreading $NAME card_$EVTPART1 undef");
		# Nachricht, dass Song nicht gefunden
	}

}

Für Pause genau das gleiche:

defmod n_PlayBox_Stop notify PlayBox:stop:.* {}
PlayBox:stop:.* {
	fhem("set Spotify pause");
}

Danach die erste Karte auflegen. Dadurch wird ein Reading mit dem Namen card_XXXXXXXXX angelegt. Dieses wird nun ein Spotify-Track zugewiesen. Dazu einfach mit setreading direkt in fhem arbeiten.

setreading PlayBox card_XXXXXXXXX spotify:track:2QAdBcz5MeMal98m13bsTg

So dann mit allen Karten verfahren und fertig.

Nun entweder die Tags in Figuren packen, oder nur auf die Karten schreiben / drucken was genau gespielt wird. Da sind der Kreativität keine Grenzen gesetzt.

Du willst mehr?

Smart-Home-Trainings von A-Z

Steig noch tiefer in die Themen ein und meistere Deine Projekte! Über 13.000 Teilnehmer konnten sich schon von der Qualität der Online-Kurse überzeugen.

ioBroker-Master-Kurs

ioBroker-Master-Kurs

Mehr Infos
Hausbau-Kurs

Hausbau mit KNX

Mehr Infos
Lox-Kurs

Lox-Kurs

Mehr Infos
Node-RED-Master-Kurs

Node-RED-Master-Kurs

Mehr Infos