Last Updated or created 2024-05-01
In the past I posted about my genre selector for Spotify using a cube.
UPDATE: 20240501 below – using esphome
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];
}
ESPHOME Config same as above
esphome:
name: rfidtag
friendly_name: rfidtag
esp8266:
board: d1_mini
mqtt:
broker: 192.168.1.1
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "xxxxxxxxxxxxxxx="
ota:
password: "xxxxxxxxxxxxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Rfidtag Fallback Hotspot"
password: "xxxxxxxxxxx"
captive_portal:
spi:
clk_pin: D5
miso_pin: D6
mosi_pin: D7
rc522_spi:
cs_pin: D8
update_interval: 1s
on_tag:
then:
- mqtt.publish:
topic: spotify/rfid/id
payload: !lambda 'return x;'
on_tag_removed:
then:
- mqtt.publish:
topic: spotify/rfid/idremoved
payload: !lambda 'return x;'



