substitutions: name: "tagreader" friendly_name: "Tagreader" device_description: NFC/RFID Tag reader factory_reset_disabled: "true" log_level: "INFO" project_name: "thethomaas.tagreader" project_version: dev esphome: name: ${name} friendly_name: ${friendly_name} comment: "${device_description}" name_add_mac_suffix: true project: name: "${project_name}" version: "${project_version}" on_boot: priority: -10 then: - wait_until: api.connected: - rtttl.play: "success:d=24,o=5,b=100:c,g,b" esp32: variant: ESP32 framework: type: arduino dashboard_import: package_import_url: github://TheThomaas/esphome-device-configs/tagreader/tagreader.yaml@main import_full_config: false ota: - platform: esphome id: ota_esphome # - platform: http_request # id: ota_managed http_request: verify_ssl: true # update: # - platform: http_request # id: firmware_update # name: Firmware Update # source: https://apolloautomation.github.io/H-2/firmware/manifest.json wifi: ap: {} # This spawns an AP with the device name and mac address with no password. # Enable logging logger: level: ${log_level} captive_portal: api: services: - service: rfidreader_tag_ok then: - rtttl.play: "beep:d=16,o=5,b=100:b" - service: rfidreader_tag_ko then: - rtttl.play: "beep:d=8,o=5,b=100:b" - service: play_rtttl variables: song_str: string then: - rtttl.play: !lambda 'return song_str;' - 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); - rtttl.play: "write:d=24,o=5,b=100:b" - wait_until: not: pn532.is_writing: - rtttl.play: "write:d=24,o=5,b=100:b,b" - service: write_music_tag variables: music_url: string music_info: string then: - lambda: |- auto message = new nfc::NdefMessage(); std::string uri = ""; std::string text = ""; uri += music_url; text += music_info; if ( music_url != "" ) { message->add_uri_record(uri); } if ( music_info != "" ) { message->add_text_record(text); } id(pn532_board).write_mode(message); - rtttl.play: "write:d=24,o=5,b=100:b" - wait_until: not: pn532.is_writing: - rtttl.play: "write:d=24,o=5,b=100:b,b" button: - platform: restart id: restart_button name: "Restart" entity_category: config disabled_by_default: true icon: "mdi:restart" - platform: safe_mode internal: false name: Safe mode entity_category: config disabled_by_default: true - platform: factory_reset name: "Factory Reset" entity_category: diagnostic internal: true - platform: template name: Write Tag Random id: write_tag_random # Optional variables: icon: "mdi:pencil-box" on_press: 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); - rtttl.play: "write:d=24,o=5,b=100:b" - wait_until: not: pn532.is_writing: - rtttl.play: "write:d=24,o=5,b=100:b,b" - platform: template name: Clean Tag id: clean_tag icon: "mdi:nfc-variant-off" on_press: then: - lambda: 'id(pn532_board).clean_mode();' - rtttl.play: "write:d=24,o=5,b=100:b" - wait_until: not: pn532.is_writing: - rtttl.play: "write:d=24,o=5,b=100:b,b" - platform: template name: Cancel writing id: cancel_writing icon: "mdi:pencil-off" on_press: then: - lambda: 'id(pn532_board).read_mode();' - rtttl.play: "write:d=24,o=5,b=100:b,b" text_sensor: - platform: version hide_timestamp: true name: ESPHome Version entity_category: diagnostic - platform: wifi_info ip_address: name: IP Address entity_category: diagnostic ssid: name: Connected SSID entity_category: diagnostic mac_address: name: MAC Address entity_category: diagnostic # Define the buzzer output output: - platform: ledc pin: GPIO14 id: buzzer max_power: 50% # Define buzzer as output for RTTTL rtttl: id: rtttl_buzzer output: buzzer switch: - platform: factory_reset id: factory_reset_switch internal: true binary_sensor: - platform: status name: Status - platform: gpio pin: number: GPIO12 mode: input: true pullup: true inverted: true id: main_button name: Main button on_press: then: - rtttl.play: "star_wars:d=16,o=5,b=100:4e,4e,4e,8c,p,g,4e,8c,p,g,4e,4p,4b,4b,4b,8c6,p,g,4d#,8c,p,g,4e,8p" - platform: template name: "=Tag=" id: is_tag device_class: vibration entity_category: DIAGNOSTIC disabled_by_default: true - platform: template name: "=Reading=" id: txt_reading device_class: running entity_category: DIAGNOSTIC lambda: |- if ( !id(pn532_board).is_writing() ) { return true; } else { return false; } - platform: template name: "=Writing=" id: txt_writing device_class: running entity_category: DIAGNOSTIC lambda: |- if ( id(pn532_board).is_writing() ) { return true; } else { return false; } sensor: - platform: wifi_signal name: RSSI id: wifi_signal_db update_interval: 60s entity_category: diagnostic - platform: uptime name: Uptime id: sys_uptime update_interval: 60s i2c: id: bus_i2c sda: GPIO22 scl: GPIO21 # scan: False # frequency: 400kHz globals: - id: source type: std::string - id: url type: std::string - id: info type: std::string pn532_i2c: id: pn532_board on_tag: then: # - if: # condition: # switch.is_on: led_enabled # then: # - light.turn_on: # id: activity_led # brightness: 100% # red: 0% # green: 100% # blue: 0% # flash_length: 500ms - delay: 0.15s #to fix slow component - lambda: |- id(source)=""; id(url)=""; id(info)=""; if (tag.has_ndef_message()) { auto message = tag.get_ndef_message(); auto records = message->get_records(); for (auto &record : records) { std::string payload = record->get_payload(); std::string type = record->get_type(); size_t hass = payload.find("https://www.home-assistant.io/tag/"); size_t applemusic = payload.find("https://music.apple.com"); size_t spotify = payload.find("https://open.spotify.com"); size_t sonos = payload.find("sonos-2://"); size_t mass_deezer = payload.find("deezer://"); size_t mass_filesystem_local = payload.find("filesystem_local://"); size_t mass_filesystem_smb = payload.find("filesystem_smb://"); size_t mass_plex = payload.find("plex://"); size_t mass_qobuz = payload.find("qobuz://"); size_t mass_radiobrowser = payload.find("radiobrowser://"); size_t mass_soundcloud = payload.find("soundcloud://"); size_t mass_spotify = payload.find("spotify://"); size_t mass_tidal = payload.find("tidal://"); size_t mass_tunein = payload.find("tunein://"); size_t mass_ytmusic = payload.find("ytmusic://"); if (type == "U" and hass != std::string::npos ) { ESP_LOGD("tagreader", "Found Home Assistant tag NDEF"); id(source)="hass"; id(url)=payload; id(info)=payload.substr(hass + 34); } else if (type == "U" and applemusic != std::string::npos ) { ESP_LOGD("tagreader", "Found Apple Music tag NDEF"); id(source)="amusic"; id(url)=payload; } else if (type == "U" and spotify != std::string::npos ) { ESP_LOGD("tagreader", "Found Spotify tag NDEF"); id(source)="spotify"; id(url)=payload; } else if (type == "U" and sonos != std::string::npos ) { ESP_LOGD("tagreader", "Found Sonos app tag NDEF"); id(source)="sonos"; id(url)=payload; } else if (type == "U" && (mass_deezer != std::string::npos || mass_filesystem_local != std::string::npos || mass_filesystem_smb != std::string::npos || mass_plex != std::string::npos || mass_qobuz != std::string::npos || mass_radiobrowser != std::string::npos || mass_soundcloud != std::string::npos || mass_spotify != std::string::npos || mass_tidal != std::string::npos || mass_tunein != std::string::npos || mass_ytmusic != std::string::npos)) { ESP_LOGD("tagreader", "Found Music Assistant tag NDEF"); id(source) = "mass"; id(url) = payload; } else if (type == "T" ) { ESP_LOGD("tagreader", "Found music info tag NDEF"); id(info)=payload; } else if ( id(source)=="" ) { id(source)="uid"; } } } else { id(source)="uid"; } - if: condition: lambda: 'return ( id(source)=="uid" );' then: - homeassistant.tag_scanned: !lambda |- ESP_LOGD("tagreader", "No HA NDEF, using UID"); return x; else: - if: condition: lambda: 'return ( id(source)=="hass" );' then: - homeassistant.tag_scanned: !lambda 'return id(info);' else: - homeassistant.event: event: esphome.music_tag data: reader: !lambda |- return App.get_name().c_str(); source: !lambda |- return id(source); url: !lambda |- return id(url); info: !lambda |- return id(info); - rtttl.play: "success:d=24,o=5,b=100:c,g,b" on_tag_removed: then: - homeassistant.event: event: esphome.tag_removed # Sets up Bluetooth LE (Only on ESP32) to allow the user # to provision wifi credentials to the device. esp32_improv: authorizer: main_button # Sets up the improv via serial client for Wi-Fi provisioning improv_serial: