Revisiting the Spotify Cube

Last Updated or created 2024-03-06

In the past I posted about my genre selector for Spotify using a cube.

Most was done using NodeRed and a python script.

Now, I’ve moved it to Home Assistant using a single automation.
(Maybe the Arduino sketch can be made with Esphome also.
But I don’t have time for that)
It still uses the Arduino sketch as before, which uses Mqtt to post the RFID code to Mosquitto.

My new Home Assistant automation

alias: SpotifyCube
description: ""
trigger:
  - platform: mqtt
    topic: spotify/rfid/id
condition:
  - condition: template
    value_template: "{{ trigger.payload in playlistkeys.keys() }}"
action:
  - service: media_player.play_media
    target:
      entity_id: media_player.spotify_fash
    data:
      media_content_type: playlist
      media_content_id: spotify:user:spotify:playlist:{{ playlistkeys.get(trigger.payload) }}
variables:
  playlistkeys:
    "70539770": 2KeRLMmGMxI5UgzE7m0iCx
    "70277626": 37i9dQZF1EQmK1rjZuPGDx
    "69229050": 0SOay3RkjojjevrF5lHMOx
    "70015482": 37i9dQZF1DX9HwI3Crikcx
    "69753338": 0bJvpsn0TDZwIDUjz4d75x
    "69491194": 5f8w3UHlD9Ozz6Y4VHs6kx

Some notes about above script:

  • The MQTT topic is configured in the sketch below
  • The playlist keys are at the bottom
    “RFIDID”: playliststring as can be found in web spotify

Pasted link

Arduino Code

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

#define SS_PIN 15
#define RST_PIN 0

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

WiFiClient net;
PubSubClient client(net);
const char* mqtt_server = "IPMQTTBROKER";
const char* ssid = "MYSSID";
const char* password = "MYWIFIPASSWORD";

void setup() {

  Serial.begin(115200);
  SPI.begin();
  mfrc522.PCD_Init();
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);

  client.setServer(mqtt_server, 1883);
     delay(100);
    client.setCallback(callback);
      delay(100);
    client.subscribe("spotify/rfid/in/#");
}

void reconnect() {
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
  }

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

    if (!client.connect(clientId.c_str(), "rfidclient", "...")) {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      delay(5000);
    }

  }
  client.subscribe("spotify/rfid/in/#");
}

void callback(char* topic, byte* payload, unsigned int length) {
    String topicStr = topic;
      byte value = atoi((char*)payload);
}

void loop() {
    if (!client.connected()) {
    reconnect();
  }
  client.loop();

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

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

  cardId = getCardId();
  char buffer[10];
  sprintf(buffer, "%lu", cardId);
  client.publish("spotify/rfid/id", 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();
  client.publish("spotify/rfid/id", "0");
  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];
}

Leave a Reply

Your email address will not be published. Required fields are marked *