I’ve been using @adonno’s excellent tag-reader code to create a way to start music without getting the phone out of my pocket. Instead of using the credit sized cards that needs to be printed on as well, I thought it could be cool to use the vinyls I already have (which I rarely use TBH, just because it is so damn cumbersome).
So I’ve made a little shelf, and whenever I place one of my records on it, music starts playing from Deezer on my speakers.
To manage the tags, I’m just using the Tags menu in HA, and then I’m saving the “Deezer-id” of the album (e.g. 59853992 = Pink Floyd - Dark side of the moon) as the Tag ID, and then I have an automation forwards the ID to the speaker and start the music. This makes it very easy to add more records later.
Here is a video showing how it works:
Video
Here is how I add new tags:
Video
Here’s is the ESPHome config for an ESP32 Dev. board. The NFC reader is a pn532 and the LED used is a SK6812.
esphome:
name: $name
platform: ESP32
board: esp32dev
# Automatically add the mac address to the name
# so you can use a single firmware for all devices
name_add_mac_suffix: false
on_boot:
priority: -10
then:
- wait_until:
api.connected:
- logger.log: API is connected!
- light.turn_on:
id: led
brightness: 100%
green: 100%
red: 0%
blue: 0%
white: 0%
flash_length: 5000ms
improv_serial:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "tagreader_ap"
password: "12345678"
# Enable the captive portal for inital WiFi setup
captive_portal:
substitutions:
name: tagreader
friendly_name: TagReader
# Enable logging
logger:
# level: VERY_VERBOSE
# level: VERBOSE
# Enable Home Assistant API
api:
services:
- service: write_tag_random
then:
- lambda: |-
static const char alphanum[] = "0123456789abcdef";
std::string uri = "https://www.home-assistant.io/tag/";
for (int i = 0; i < 8; i++)
uri += alphanum[random_uint32() % (sizeof(alphanum) - 1)];
uri += "-";
for (int j = 0; j < 3; j++) {
for (int i = 0; i < 4; i++)
uri += alphanum[random_uint32() % (sizeof(alphanum) - 1)];
uri += "-";
}
for (int i = 0; i < 12; i++)
uri += alphanum[random_uint32() % (sizeof(alphanum) - 1)];
auto message = new nfc::NdefMessage();
message->add_uri_record(uri);
ESP_LOGD("tagreader", "Writing payload: %s", uri.c_str());
id(pn532_board).write_mode(message);
- service: write_tag_id
variables:
tag_id: string
then:
- lambda: |-
auto message = new nfc::NdefMessage();
std::string uri = "https://www.home-assistant.io/tag/";
uri += tag_id;
message->add_uri_record(uri);
id(pn532_board).write_mode(message);
- light.turn_on:
id: led
brightness: 100%
red: 100%
green: 0%
blue: 0%
white: 0%
flash_length: 3000ms
- wait_until:
not:
pn532.is_writing:
- service: clean_tag
then:
- lambda: 'id(pn532_board).clean_mode();'
- wait_until:
not:
pn532.is_writing:
- service: cancel_writing
then:
- lambda: 'id(pn532_board).read_mode();'
# Enable OTA upgrade
ota:
- platform: esphome
i2c:
scan: False
frequency: 400kHz
pn532_i2c:
update_interval: 350ms
id: pn532_board
on_tag:
then:
- homeassistant.tag_scanned: !lambda |
if (!tag.has_ndef_message()) {
ESP_LOGD("tagreader", "No NDEF");
return x;
}
auto message = tag.get_ndef_message();
auto records = message->get_records();
for (auto &record : records) {
std::string payload = record->get_payload();
size_t pos = payload.find("https://www.home-assistant.io/tag/");
if (pos != std::string::npos) {
return payload.substr(pos + 34);
}
}
ESP_LOGD("tagreader", "Bad NDEF, fallback to uid");
return x;
- light.turn_on:
id: led
brightness: 100%
red: 0%
green: 0%
blue: 0%
white: 100%
flash_length: 1500ms
binary_sensor:
- platform: status
name: "${friendly_name} Status"
entity_category: diagnostic
light:
- platform: neopixelbus
type: GRBW
variant: SK6812
pin: GPIO27
num_leds: 1
name: "${friendly_name} LED"
flash_transition_length: 500ms
id: led
restore_mode: ALWAYS_OFF
#
switch:
- platform: restart
name: "Living Room Restart"
And lastly, here is the austomation I use for my speaker (using the Bang & Olufsen integration):
alias: Mozart Deezer album tag reader
triggers:
- event_type: tag_scanned
trigger: event
conditions: []
actions:
- data:
media_content_type: deezer
media_content_id: album:{{ trigger.event.data.tag_id }}
target:
entity_id: media_player.beosound_theatre_12345678
action: media_player.play_media