OMG, so easy, works just fine.
I only checked github, and this awesome installer is not listed there (or have I not seen it?)
Thanks you so much for the quick help!
OMG, so easy, works just fine.
I only checked github, and this awesome installer is not listed there (or have I not seen it?)
Thanks you so much for the quick help!
I stumbled across this last night while trying (and failing) to do something similar with MAss and the Adonno reader, so it’s saving me a ton of work! I’ve now got it flashed and setup to use a HA Voice PE as the media player, which is itself connected to a regular hifi system via aux cable.
My question is: Can I flash the Voice PE firmware to get the media control functionality while keeping the reader part separate? My gut says yes but I’m not at all familiar with ESP32 development.
Also, would it be possible to add a thing to the blueprint for adding user-defined actions (similar to how this blueprint does it)? My goal is to add an IR blaster to the setup and have it turn on the hifi and switch it to the aux input when a tag is scanned.
Thanks for your work with this!
sure you can flash Voice PE to get media control without NFC. Flash it from ready made firmware or wait till I release 04 update (haven’t checked April version yet).
It will not work since TagTuner events are generated only when NFC reader has set tag presence flag.
But anyway, you can do whatever automation you want triggered by esphome.tagtuner events. Just set TagTuner blueprint automation and “take control” to see all the details needed. Then set your own automations triggered in parallel to TagTuner blueprint.
I’ve been trying to get this working with a ESP32 Wroom 32D, but i just cant get any reaction from the reader.
Ive had to alter some things, like the pins etc from the yamls.
But nothing happens when i place a card on the reader, it’s like the reader is dead. (light is ON on the NFC chip).
Also tried to do a TagReader with the same wroom, but same result, no reaction whatsoever.
Does anybody have any experience on using this on an ESP32 WROOM?
so probably your pins are not correct. Check the logs for pn532 component.
Hi,
I am testing my setup and I got some pandom Mifare 1k tags. I can scan the tag with valid NDEF only like 1 out of 10 tries. Could you please help be with logs what may be the reason?
Are these tags not suitable for reliable reading?
Typical errors:
I would like to know if the situation may get better with different type of tags, or how to make it work with these.
Thanks a lot!
Log:
[21:35:50][D][pn532:364]: Mifare classic
[21:35:51][E][pn532.mifare_classic:045]: Error reading block 9
[21:35:51][E][nfc.ndef_message:049]: Corrupt record encountered; NdefMessage constructor aborting
[21:35:51][D][binary_sensor:036]: '=Tag=': Sending state ON
[21:35:51][D][text_sensor:064]: 'Status': Sending state 'Tag 21-20-B8-FB'
[21:35:51][D][text_sensor:064]: 'Status': Sending state 'Plain UID tag'
[21:35:51][D][tagtuner:284]: No TagTuner NDEF, using UID
[21:35:51][D][pn532:200]: Found new tag '21-20-B8-FB'
[21:35:51][D][pn532:204]: NDEF formatted records:
[21:35:51][D][pn532:206]: T - TagTuner
[21:35:51][D][pn532:206]: T - artist/w
[21:35:51][D][pn532:206]: T - playlist/y
[21:35:51][D][pn532:379]: Waiting to read next tag
[21:35:51][W][component:239]: Component pn532 took a long time for an operation (307 ms).
[21:35:51][W][component:240]: Components should block for at most 30 ms.
[21:35:51][D][text:050]: 'Playlist URI' - Setting text value: Tag 21-20-B8-FB
[21:35:51][D][text:016]: 'Playlist URI': Sending state Tag 21-20-B8-FB
[21:35:51][D][text:050]: 'Playlist artist' - Setting text value: Shabaka
[21:35:51][D][text:016]: 'Playlist artist': Sending state Shabaka
[21:35:51][D][text:050]: 'Playlist name or album title' - Setting text value: We Out Here
[21:35:51][D][text:016]: 'Playlist name or album title': Sending state We Out Here
[21:35:51][D][rtttl:061]: Playing song beep_only
[21:35:51][D][rtttl:390]: State changed from STATE_STOPPED to STATE_RUNNING
[21:35:51][D][binary_sensor:036]: '=Tag=': Sending state OFF
[21:35:51][D][text_sensor:064]: 'Status': Sending state 'Tag removed'
[21:35:51][D][rtttl:390]: State changed from STATE_RUNNING to STATE_STOPPED
[21:35:51][D][rtttl:367]: Playback finished
[21:35:51][D][pn532:364]: Mifare classic
[21:35:51][E][pn532.mifare_classic:101]: Authentication failed - Block 0x04
[21:35:51][E][pn532.mifare_classic:038]: Error, Block authentication failed for 4
[21:35:51][E][pn532.mifare_classic:045]: Error reading block 4
[21:35:51][E][pn532.mifare_classic:045]: Error reading block 5
[21:35:51][E][pn532.mifare_classic:045]: Error reading block 6
[21:35:51][E][pn532.mifare_classic:101]: Authentication failed - Block 0x08
[21:35:52][E][pn532.mifare_classic:038]: Error, Block authentication failed for 8
[21:35:52][E][pn532.mifare_classic:045]: Error reading block 8
[21:35:52][E][pn532.mifare_classic:045]: Error reading block 9
[21:35:52][D][binary_sensor:036]: '=Tag=': Sending state ON
[21:35:52][D][text_sensor:064]: 'Status': Sending state 'Tag 21-20-B8-FB'
[21:35:52][D][text_sensor:064]: 'Status': Sending state 'Plain UID tag'
[21:35:52][D][tagtuner:284]: No TagTuner NDEF, using UID
[21:35:52][D][pn532:200]: Found new tag '21-20-B8-FB'
[21:35:52][D][pn532:379]: Waiting to read next tag
[21:35:52][W][component:239]: Component pn532 took a long time for an operation (589 ms).
[21:35:52][W][component:240]: Components should block for at most 30 ms.
[21:35:52][D][text:050]: 'Playlist URI' - Setting text value: Tag 21-20-B8-FB
[21:35:52][D][text:016]: 'Playlist URI': Sending state Tag 21-20-B8-FB
[21:35:52][D][text:050]: 'Playlist artist' - Setting text value: Shabaka
[21:35:52][D][text:016]: 'Playlist artist': Sending state Shabaka
[21:35:52][D][text:050]: 'Playlist name or album title' - Setting text value: We Out Here
[21:35:52][D][text:016]: 'Playlist name or album title': Sending state We Out Here
[21:35:52][D][rtttl:061]: Playing song beep_only
[21:35:52][D][rtttl:390]: State changed from STATE_STOPPED to STATE_RUNNING
[21:35:52][D][binary_sensor:036]: '=Tag=': Sending state OFF
[21:35:52][D][text_sensor:064]: 'Status': Sending state 'Tag removed'
[21:35:52][D][rtttl:390]: State changed from STATE_RUNNING to STATE_STOPPED
[21:35:52][D][rtttl:367]: Playback finished
[21:35:55][D][text_sensor:064]: 'Status': Sending state 'Waiting for input'
[21:35:56][D][pn532:364]: Mifare classic
[21:35:56][E][pn532.mifare_classic:101]: Authentication failed - Block 0x04
[21:35:56][D][binary_sensor:036]: '=Tag=': Sending state ON
[21:35:56][D][text_sensor:064]: 'Status': Sending state 'Tag 71-69-B5-FB'
[21:35:56][D][text_sensor:064]: 'Status': Sending state 'Plain UID tag'
[21:35:56][D][tagtuner:284]: No TagTuner NDEF, using UID
[21:35:56][D][pn532:200]: Found new tag '71-69-B5-FB'
[21:35:56][D][pn532:379]: Waiting to read next tag
[21:35:56][W][component:239]: Component pn532 took a long time for an operation (71 ms).
[21:35:56][W][component:240]: Components should block for at most 30 ms.
[21:35:56][D][text:050]: 'Playlist URI' - Setting text value: Tag 71-69-B5-FB
[21:35:56][D][text:016]: 'Playlist URI': Sending state Tag 71-69-B5-FB
[21:35:56][D][text:050]: 'Playlist artist' - Setting text value: Shabaka
[21:35:56][D][text:016]: 'Playlist artist': Sending state Shabaka
[21:35:56][D][rtttl:061]: Playing song beep_only
[21:35:56][D][rtttl:390]: State changed from STATE_STOPPED to STATE_RUNNING
[21:35:56][D][text:050]: 'Playlist name or album title' - Setting text value: We Out Here
[21:35:56][D][text:016]: 'Playlist name or album title': Sending state We Out Here
[21:35:57][D][rtttl:390]: State changed from STATE_RUNNING to STATE_STOPPED
[21:35:57][D][rtttl:367]: Playback finished
[21:35:57][D][binary_sensor:036]: '=Tag=': Sending state OFF
[21:35:57][D][text_sensor:064]: 'Status': Sending state 'Tag removed'
[21:35:58][D][pn532:364]: Mifare classic
[21:35:59][D][binary_sensor:036]: '=Tag=': Sending state ON
[21:35:59][D][text_sensor:064]: 'Status': Sending state 'Tag 71-69-B5-FB'
[21:35:59][D][text:050]: 'Playlist artist' - Setting text value: z
[21:35:59][D][text:016]: 'Playlist artist': Sending state z
[21:35:59][D][pn532:200]: Found new tag '71-69-B5-FB'
[21:35:59][D][pn532:204]: NDEF formatted records:
[21:35:59][D][pn532:206]: T - TagTuner
[21:35:59][D][pn532:206]: T - artist/z
[21:35:59][D][pn532:206]: T - playlist/je
[21:35:59][D][pn532:206]: U - library://track/1513
[21:35:59][D][pn532:379]: Waiting to read next tag
[21:35:59][W][component:239]: Component pn532 took a long time for an operation (322 ms).
[21:35:59][W][component:240]: Components should block for at most 30 ms.
[21:35:59][D][text:050]: 'Playlist name or album title' - Setting text value: je
[21:35:59][D][text:016]: 'Playlist name or album title': Sending state je
[21:35:59][D][tagtuner:060]: URI NDEF
[21:35:59][D][text:050]: 'Playlist URI' - Setting text value: library://track/1513
[21:35:59][D][text:016]: 'Playlist URI': Sending state library://track/1513
[21:35:59][D][rtttl:061]: Playing song scale_up
[21:35:59][D][rtttl:390]: State changed from STATE_STOPPED to STATE_RUNNING
[21:35:59][W][rtttl:038]: RTTTL Component is already playing: scale_up
[21:35:59][D][binary_sensor:036]: '=Tag=': Sending state OFF
[21:35:59][D][text_sensor:064]: 'Status': Sending state 'Tag removed'
[21:35:59][D][pn532:364]: Mifare classic
[21:35:59][E][pn532.mifare_classic:101]: Authentication failed - Block 0x04
[21:35:59][D][binary_sensor:036]: '=Tag=': Sending state ON
[21:35:59][D][text_sensor:064]: 'Status': Sending state 'Tag 71-69-B5-FB'
[21:35:59][D][text_sensor:064]: 'Status': Sending state 'Plain UID tag'
[21:35:59][D][tagtuner:284]: No TagTuner NDEF, using UID
[21:35:59][D][pn532:200]: Found new tag '71-69-B5-FB'
[21:35:59][D][pn532:379]: Waiting to read next tag
[21:35:59][W][component:239]: Component pn532 took a long time for an operation (129 ms).
[21:35:59][W][component:240]: Components should block for at most 30 ms.
[21:35:59][D][text:050]: 'Playlist URI' - Setting text value: Tag 71-69-B5-FB
[21:35:59][D][text:016]: 'Playlist URI': Sending state Tag 71-69-B5-FB
[21:35:59][D][text:050]: 'Playlist artist' - Setting text value: Zaz
[21:35:59][D][text:016]: 'Playlist artist': Sending state Zaz
[21:35:59][D][text:050]: 'Playlist name or album title' - Setting text value: Zaz
[21:35:59][D][text:016]: 'Playlist name or album title': Sending state Zaz
[21:35:59][W][rtttl:038]: RTTTL Component is already playing: scale_up
[21:35:59][D][rtttl:390]: State changed from STATE_RUNNING to STATE_STOPPED
[21:35:59][D][rtttl:367]: Playback finished
[21:36:00][D][binary_sensor:036]: '=Tag=': Sending state OFF
[21:36:00][D][text_sensor:064]: 'Status': Sending state 'Tag removed'
[21:36:03][D][text_sensor:064]: 'Status': Sending state 'Waiting for input'
[21:40:41][D][esp32_ble_tracker:282]: Starting scan...
I would resolder the pins first. Maybe replace the wires? Then I’d make the i2c bus slower.
And if that won’t make it, try another tags (read-only like Disney Infinity or Amiibo or Philips Sonicare or MoodBlocks) and then try another nfc reader.
Actual tag scanning seems to be reliable, but reading the data from the tag not. It often does not recognize the NDEF definition.
I tried slowing down the I2C and that didn’t help.
If you had any other ideas, please let me know.
I’ll try checking I2C signals with scope and adding some bypass capacitor for the nfc module.
Hi, has anyone got this reliably working with the Adonno Tag reader setup. I get it to read card values but it only works like 5% of the time. Some days I think it’s fixed but then it turns flakey all over again.
i have the same kind of issues, but using the standard tagtuner version, not tagreader setup.
when it works, it works fine. But more often than not I get different ‘bugs’:
I don’t have Adonno Tagreader but I’m running 8266 nodemcu version daily.
Have you tried this Tag Tuner light yaml version?
Which controller are you using? When not working, what logs do you see? Have you looked at automation trace? Any error there?
Now looking at the automation traces, I can see that upon placing a tag-card, it does recognize it and starts all the “tag-scanned” actions. But immediately after, within the same second, it reads “tag-removed” and starts all actions accordingly, thus pausing the player, and setting shuffle back to off. So maybe I have something setup wrong with the card reader? Or we should add some seconds after reading a tag before it can start a tag removed action.
I’m using a wroom32, that’s the only difference with your D1 setup, and had to only change that entry in your code.
Have you tried putting the tag flat on the Tag Tuner? Try playing with tag distance from the reader. You could also disable „stop on tag removed” in the automation but only if you stop the player any other way - I’m using Alexa for that on my 8266 reader. This is a really simple and cheap nfc reader, probably Chinese knockoff even so have some understanding and use your diy spirit! ![]()
Great project!!! I would love to try as I already have nfc tage reader/write but it’s RC522. Would this be working on RC522?
Yes, it will work with pn522 but without ndef support (as described here RC522 NFC/RFID — ESPHome). So TagTuner with pn522 will work like with read-only tags TagTuner music player | Powered by ESPHome and ESP Web Tools
I haven’t seen this light version before so I may wire up a 8266 again and try.
In the meantime I had a ESP32 WROOM dev lying around. Modified the adonno tagtuner code to work with this and it is flawless. I think it may no be worth recommending the adonno with 8266 unless someone can confirm it actually works reliably.
Tried this yesterday, but with modified adonno tagtuner code (as I had the buzzer and not a rotary encoder yet). Found it worked quite well. Make sure you the correct pins for the pn532 to work. i.e sda: GPIO21 scl: GPIO22.
I hope this helps.
edit: this was with an ESP-WROOM-32 dev board.
esp32 boards will work with TagTuner code easily (TagTuner/tagtuner-D1-custom1.yaml at 980c3545319d15eb3a98ceb4a086121fc2a8de3f · luka6000/TagTuner · GitHub) with passive bluetooth proxy as an extra addon and I fully recommend this kind of setup. And yes, you have to set i2c pins correctly since esp32 has more than one i2c controller.
Been struggling with code recent days…I wanted to add small display but on esp32-s3-dev board (incl. rotary encoder and with PN532 nfc board). Had to modify code a bit but now I’m having problem with writing tags. It seem write process can’t write to tag. I’m using ‘original’ fob provided with nfc module.
[17:31:24][D][button:010]: 'Write Tag' Pressed.
[17:31:24][D][light:036]: 'led1' Setting:
[17:31:24][D][light:047]: State: ON
[17:31:24][D][light:051]: Brightness: 70%
[17:31:24][D][light:059]: Red: 100%, Green: 0%, Blue: 0%
[17:31:24][D][light:109]: Effect: 'RedTagWriteEffect'
[17:31:24][D][ndef:538]: Writing payload: spotify://playlist/6UiFjIT31XYHqnwhlE8sj6
[17:31:24][D][pn532:392]: Waiting to write next tag
[17:31:24][D][text_sensor:064]: 'Status': Sending state 'Place tag'
[17:31:24][D][binary_sensor:036]: '=Reading=': Sending state OFF
[17:31:24][D][binary_sensor:036]: '=Writing=': Sending state ON
[17:31:26][D][pn532:224]: Tag writing...
[17:31:26][D][pn532:225]: Tag formatting...
[17:31:27][D][pn532:229]: Writing NDEF data
[17:31:27][E][pn532.mifare_ultralight:125]: Message length exceeds tag capacity 108 > 0
[17:31:27][E][pn532:231]: Failed to write message to tag
[17:31:27][D][pn532:233]: Finished writing NDEF data
[17:31:27][D][pn532:379]: Waiting to read next tag
[17:31:27][W][component:257]: Component pn532 took a long time for an operation (988 ms).
[17:31:27][W][component:258]: Components should block for at most 30 ms.
[17:31:27][D][text_sensor:064]: 'Status': Sending state 'Finished writing tag attempt'
[17:31:27][D][light:036]: 'led1' Setting:
[17:31:27][D][light:109]: Effect: 'GreenSuccessEffect'
[17:31:27][D][binary_sensor:036]: '=Reading=': Sending state ON
[17:31:27][D][binary_sensor:036]: '=Writing=': Sending state OFF
[17:31:27][D][text_sensor:064]: 'Status': Sending state 'Tag removed'
[17:31:27][D][light:036]: 'led1' Setting:
[17:31:27][D][light:109]: Effect: 'BlueConfirmEffect'
[17:31:28][D][light:036]: 'led1' Setting:
[17:31:28][D][light:047]: State: OFF
[17:31:28][D][light:109]: Effect: 'None'
[17:31:28][D][light:036]: 'led1' Setting:
[17:31:30][D][text_sensor:064]: 'Status': Sending state 'Waiting for input'
My yaml code in Esphome:
substitutions:
name: "tagtuner-s3"
friendly_name: "TagTuner S3"
media_player_entity_id: "media_player.louder_esp32s3_airplay"
magic: "250308"
globals:
- id: artist
type: std::string
initial_value: '""'
- id: playlist
type: std::string
initial_value: '""'
- id: uri
type: std::string
initial_value: '""'
text_sensor:
- platform: wifi_info
ip_address:
id: wifi_ip_address_sensor
name: "${friendly_name} IP Address"
entity_category: diagnostic
disabled_by_default: true
- platform: homeassistant
id: media_player_title
entity_id: ${media_player_entity_id}
attribute: media_title
internal: true
- platform: homeassistant
id: media_player_artist
entity_id: ${media_player_entity_id}
attribute: media_artist
internal: true
- platform: homeassistant
id: media_player_state_text
entity_id: ${media_player_entity_id}
internal: true
- platform: template
id: status
name: "Status"
icon: mdi:ladybug
entity_category: DIAGNOSTIC
on_value:
if:
condition:
lambda: 'return id(status).state != "Waiting for input";'
then:
- script.stop: wait_input
- script.execute: wait_input
binary_sensor:
- platform: gpio
id: toggle
pin:
number: GPIO12
inverted: true
mode:
input: true
pullup: true
on_multi_click:
- timing:
- ON for at most 1s
- OFF for at most 0.25s
- ON for at most 1s
- OFF for at most 0.25s
- ON for at most 1s
then:
- script.execute: led_blink
- text_sensor.template.publish:
id: status
state: "clickTriple"
- script.execute:
id: action_event
action: "clickTriple"
- timing:
- ON for at most 1s
- OFF for at most 0.25s
- ON for at most 1s
- OFF for at least 0.25s
then:
- script.execute: led_blink
- text_sensor.template.publish:
id: status
state: "clickDouble"
- script.execute:
id: action_event
action: "clickDouble"
- timing:
- ON for 0.5s to 2s
- OFF for at least 50ms
then:
- script.execute: led_blink
- text_sensor.template.publish:
id: status
state: "clickLong"
- script.execute:
id: action_event
action: "clickLong"
- timing:
- ON for at most 0.5s
- OFF for at least 260ms
then:
- script.execute: led_blink
- text_sensor.template.publish:
id: status
state: "clickSingle"
- script.execute:
id: tagtuner_event
action: "clickSingle"
uid: ""
uri: ""
artist: ""
playlist: ""
- 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: rotary_encoder
id: rotary
pin_a: GPIO10
pin_b: GPIO11
on_clockwise:
- {text_sensor.template.publish: {id: status, state: "Volume up"}}
- {script.execute: {id: tagtuner_event, action: "volumeUp", uid: "", uri: "", artist: "", playlist: ""}}
- {script.execute: led_blink}
on_anticlockwise:
- {text_sensor.template.publish: {id: status, state: "Volume down"}}
- {script.execute: {id: tagtuner_event, action: "volumeDown", uid: "", uri: "", artist: "", playlist: ""}}
- {script.execute: led_blink}
- platform: homeassistant
id: media_player_duration
entity_id: ${media_player_entity_id}
attribute: media_duration
internal: true
- platform: homeassistant
id: media_player_position
entity_id: ${media_player_entity_id}
attribute: media_position
internal: true
text:
- platform: template
id: playlist_artist
name: "Playlist artist"
icon: mdi:account-music
entity_category: CONFIG
optimistic: true
min_length: 0
max_length: 50
mode: text
initial_value: " "
- platform: template
id: playlist_info
name: "Playlist name or album title"
icon: mdi:playlist-music
entity_category: CONFIG
optimistic: true
min_length: 0
max_length: 100
mode: text
initial_value: " "
- platform: template
id: playlist_uri
name: "Playlist URI"
icon: mdi:link-variant
entity_category: CONFIG
optimistic: true
min_length: 0
max_length: 255
mode: text
initial_value: " "
light:
- platform: esp32_rmt_led_strip
id: led1
pin: GPIO48
chipset: ws2812
num_leds: 1
rgb_order: GRB
rmt_channel: 0
restore_mode: ALWAYS_OFF
default_transition_length: 0s
effects:
- addressable_rainbow:
name: RainbowBootEffect
speed: 50
width: 20
- strobe:
name: BlueConfirmEffect
colors:
- red: 0%
green: 0%
blue: 100%
brightness: 100%
state: true
duration: 100ms
- state: false
duration: 100ms
- strobe:
name: GreenOkEffect
colors:
- red: 0%
green: 100%
blue: 0%
brightness: 100%
state: true
duration: 150ms
- state: false
duration: 150ms
- strobe:
name: GreenSuccessEffect
colors:
- red: 0%
green: 100%
blue: 0%
brightness: 100%
state: true
duration: 150ms
- state: false
duration: 150ms
- red: 0%
green: 100%
blue: 0%
brightness: 100%
state: true
duration: 150ms
- state: false
duration: 150ms
- red: 0%
green: 100%
blue: 0%
brightness: 100%
state: true
duration: 150ms
- state: false
duration: 150ms
- addressable_scan:
name: RedTagWriteEffect
move_interval: 80ms
scan_width: 1
script:
- id: led_boot_sequence
then:
- light.turn_on: {id: led1, effect: RainbowBootEffect}
- delay: 2000ms
- light.turn_off: led1
- id: led_blink
then:
- light.turn_on: {id: led1, effect: BlueConfirmEffect}
- delay: 250ms
- light.turn_off: led1
- id: led_ok
then:
- light.turn_on: {id: led1, effect: GreenOkEffect}
- delay: 350ms
- light.turn_off: led1
- id: led_success
then:
- light.turn_on: {id: led1, effect: GreenSuccessEffect}
- delay: 950ms
- light.turn_off: led1
- id: led_tagwrite
then:
- light.turn_on:
id: led1
effect: RedTagWriteEffect
red: 1.0
green: 0.0
blue: 0.0
brightness: 0.7
- id: wait_input
then:
- delay: 3s
- text_sensor.template.publish: {id: status, state: "Waiting for input"}
- id: set_tag
then:
- text.set: {id: playlist_artist, value: !lambda "return id(artist);"} # POPRAVEK: Odstranjen .get_state()
- delay: 10ms
- text.set: {id: playlist_info, value: !lambda "return id(playlist);"} # POPRAVEK: Odstranjen .get_state()
- delay: 10ms
- text.set: {id: playlist_uri, value: !lambda "ESP_LOGD(\"tagtuner_script\", \"Setting URI from global: %s\", id(uri).c_str()); return id(uri);"} # POPRAVEK: Odstranjen .get_state(), uporabljen .c_str() za ESP_LOGD
- id: action_event
parameters: {action: string}
mode: queued
max_runs: 3
then:
- homeassistant.event:
event: esphome.tagtuner
data: {magic: "${magic}", action: !lambda "return action;"}
- id: tagtuner_event
parameters: {action: string, uid: string, uri: string, artist: string, playlist: string}
mode: queued
max_runs: 3
then:
- homeassistant.event:
event: esphome.tagtuner
data: {magic: "${magic}", action: !lambda "return action;", uid: !lambda "return uid;", uri: !lambda "return uri;", artist: !lambda "return artist;", playlist: !lambda "return playlist;"}
esphome:
min_version: 2025.2.0
name: "${name}"
friendly_name: ${friendly_name}
name_add_mac_suffix: true
project:
name: LukaGra.${friendly_name}
version: dev
on_boot:
priority: -100
then:
- wait_until:
condition:
api.connected
timeout: 20s
- text_sensor.template.publish:
id: status
state: "Ready"
api:
encryption:
key: "ASFaaMAAhGyeSVXF7xb/YlQitEV/RjDM5YLUjN2jSC0="
ota:
- platform: esphome
password: "ee34dbbf1eeceee5dd23d21c85842557"
wifi:
id: wifi_state # <<< SPREMENJEN ID, DA SE IZOGNEMO KONFLIKTU Z INTEGRACIJO 'wifi'
networks:
- ssid: !secret wifi_ext
password: !secret wifipassext
- ssid: !secret wifi_ssid_ap
password: !secret wifi_password
- ssid: !secret wifi_ssid
password: !secret wifi_pass
- ssid: !secret wifi_ssid_ap2
password: !secret wifi_pass
- ssid: !secret wifi_ssid_ap3
password: !secret wifi_pass
manual_ip:
static_ip: 192.168.31.223
gateway: 192.168.31.1
subnet: 255.255.255.0
ap:
ssid: "Nfc-Esp32-S3-1 Fallback Hotspot"
password: "IbtQaxMvMz48"
captive_portal:
esp32:
board: esp32-s3-devkitc-1
framework:
type: arduino
logger:
level: DEBUG
logs:
pn532: DEBUG
i2c:
id: bus_i2c
sda: GPIO8
scl: GPIO9
scan: true
frequency: 100kHz
pn532_i2c:
id: pn532_board
i2c_id: bus_i2c
update_interval: 350ms
on_tag:
- lambda: |-
id(playlist)="";
id(artist)="";
id(uri)="";
if (tag.has_ndef_message()) {
ESP_LOGD("on_tag", "Tag has NDEF message. Records: %d", tag.get_ndef_message()->get_records().size());
for (auto &record : tag.get_ndef_message()->get_records() ) {
std::string payload_str = record->get_payload();
std::string type_str = record->get_type();
ESP_LOGD("on_tag", "Record type: %s, payload: %s", type_str.c_str(), payload_str.c_str());
if ( payload_str.rfind("artist/", 0) == 0 ) {
id(artist)=payload_str.substr(7);
}
else if ( payload_str.rfind("playlist/", 0) == 0 ) {
id(playlist)=payload_str.substr(9);
}
else if (type_str == "U"
&& (payload_str.length() < 20 || payload_str.substr(0, 20) != "https://mb.senic.com")
&& (payload_str.length() < 23 || payload_str.substr(0, 23) != "https://www.philips.com")
) {
id(uri)=payload_str;
}
}
} else {
ESP_LOGD("on_tag", "Tag does not have an NDEF message.");
}
- binary_sensor.template.publish:
id: is_tag
state: true
- text_sensor.template.publish:
id: status
state: !lambda 'return "Tag "+x;'
- if:
condition:
lambda: 'return id(uri) == "";' # POPRAVEK: Odstranjen .get_state()
then:
- text_sensor.template.publish:
id: status
state: "Plain UID tag"
- homeassistant.tag_scanned: !lambda |-
ESP_LOGD("tagtuner_event", "No TagTuner NDEF, using UID: %s", x.c_str());
return x;
else:
- script.execute:
id: tagtuner_event
action: "tagScanned"
uid: !lambda 'return x;'
uri: !lambda 'return id(uri);' # POPRAVEK: Odstranjen .get_state()
artist: !lambda 'return id(artist);' # POPRAVEK: Odstranjen .get_state()
playlist: !lambda 'return id(playlist);' # POPRAVEK: Odstranjen .get_state()
- script.execute: set_tag
- script.execute: led_ok
on_tag_removed:
- binary_sensor.template.publish:
id: is_tag
state: false
- text_sensor.template.publish:
id: status
state: "Tag removed"
- script.execute:
id: tagtuner_event
action: "tagRemoved"
uid: !lambda 'return x;'
uri: ""
artist: ""
playlist: ""
- script.execute: led_blink
button:
- platform: restart
name: "Restart"
id: btn_restart
entity_category: DIAGNOSTIC
- platform: template
name: Cancel writing
id: btn_cancel_writing
icon: "mdi:broadcast-off"
entity_category: CONFIG
on_press:
then:
- text_sensor.template.publish: {id: status, state: "Cancel writing (manual tag removal needed)"}
- script.execute: led_ok
- platform: template
name: Erase Tag
id: btn_erase_tag
icon: "mdi:nfc-search-variant"
entity_category: CONFIG
on_press:
then:
- script.execute: led_tagwrite
- text.set: {id: playlist_artist, value: ''}
- text.set: {id: playlist_info, value: ''}
- text.set: {id: playlist_uri, value: ''}
- lambda: |-
auto message = new nfc::NdefMessage();
ESP_LOGD("ndef", "Attempting to erase tag by writing an empty NDEF message.");
id(pn532_board).write_mode(message);
- text_sensor.template.publish: {id: status, state: "Place tag to erase"}
- wait_until:
timeout: 30s
condition: {not: {pn532.is_writing: null}}
- text_sensor.template.publish: {id: status, state: "Finished erasing tag attempt"}
- script.execute: led_success
- platform: template
name: Write Tag
id: btn_write_tag
icon: "mdi:cast-audio-variant"
entity_category: CONFIG
on_press:
then:
- script.execute: led_tagwrite
- lambda: |-
auto message = new nfc::NdefMessage();
message->add_text_record("TagTuner");
std::string uri_val = id(playlist_uri).state; // .state je pravilen za text entitete
std::string artist_val_full = "artist/" + id(playlist_artist).state; // .state je pravilen za text entitete
std::string playlist_val_full = "playlist/" + id(playlist_info).state; // .state je pravilen za text entitete
if (id(playlist_artist).state.length() > 0 && id(playlist_artist).state != " ") {
message->add_text_record(artist_val_full);
}
if (id(playlist_info).state.length() > 0 && id(playlist_info).state != " ") {
message->add_text_record(playlist_val_full);
}
if (uri_val.length() > 0 && uri_val != " ") {
message->add_uri_record(uri_val);
}
ESP_LOGD("ndef", "Writing payload: %s", uri_val.c_str());
id(pn532_board).write_mode(message);
- text_sensor.template.publish: {id: status, state: "Place tag"}
- wait_until:
timeout: 30s
condition: {not: {pn532.is_writing: null}}
- text_sensor.template.publish: {id: status, state: "Finished writing tag attempt"}
- script.execute: led_success
font:
- file: "gfonts://Roboto"
id: font_small
size: 12
glyphs: "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ °абвгдежзийклмнопрстуфхцчшщъыьэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯČŠŽčšž"
- file: "gfonts://Roboto"
id: font_medium
size: 16
glyphs: "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ °абвгдежзийклмнопрстуфхцчшщъыьэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯČŠŽčšž"
display:
- platform: ssd1306_i2c
id: oled_display
model: "SSD1306 128x64"
address: 0x3C
i2c_id: bus_i2c
rotation: 0
update_interval: 1s
lambda: |-
it.clear();
auto mp_state = id(media_player_state_text).state;
auto mp_title = id(media_player_title).state;
auto mp_artist = id(media_player_artist).state;
if ( !mp_title.empty() && (mp_state == "playing" || mp_state == "paused" || mp_state == "on") ) {
if (!mp_artist.empty()) {
std::string artist_str = mp_artist;
if (artist_str.length() > 18) artist_str = artist_str.substr(0, 16) + "..";
it.printf(0, 0, id(font_medium), "%s", artist_str.c_str());
} else {
it.print(0, 0, id(font_medium), App.get_friendly_name().c_str());
}
std::string title_str = mp_title;
if (title_str.length() > 40) {
it.printf(0, 18, id(font_small), "%.20s", title_str.c_str());
it.printf(0, 30, id(font_small), "%.20s", title_str.substr(20).c_str());
} else if (title_str.length() > 20) {
it.printf(0, 18, id(font_small), "%.20s", title_str.c_str());
it.printf(0, 30, id(font_small), "%s", title_str.substr(20).c_str());
} else {
it.printf(0, 18, id(font_small), "%s", title_str.c_str());
}
if (mp_state == "playing") {
it.printf(55, 48, id(font_medium), ">");
} else if (mp_state == "paused") {
it.printf(55, 48, id(font_medium), "||");
} else if (mp_state == "on") {
it.printf(50, 48, id(font_small), "Ready");
}
} else {
it.print(0, 0, id(font_medium), App.get_friendly_name().c_str());
std::string current_status = id(status).state;
if (current_status.length() > 20) current_status = current_status.substr(0, 18) + "..";
it.printf(0, 18, id(font_small), "S: %s", current_status.c_str());
if (id(is_tag).state) {
std::string p_uri = id(playlist_uri).state; // .state je pravilen za text entitete
if (p_uri.length() > 20) p_uri = p_uri.substr(0, 18) + "..";
it.printf(0, 32, id(font_small), "U: %s", p_uri.c_str());
std::string p_info_combined;
std::string artist_str_tag = id(playlist_artist).state; // .state je pravilen za text entitete
std::string playlist_str_tag = id(playlist_info).state; // .state je pravilen za text entitete
if (artist_str_tag.length() > 1 && artist_str_tag != " ") {
p_info_combined += artist_str_tag.substr(0,8);
}
if (playlist_str_tag.length() > 1 && playlist_str_tag != " ") {
if (!p_info_combined.empty()) p_info_combined += "-";
p_info_combined += playlist_str_tag.substr(0,10);
}
if (p_info_combined.length() > 20) p_info_combined = p_info_combined.substr(0, 18) + "..";
it.printf(0, 46, id(font_small), "P: %s", p_info_combined.c_str());
} else if (id(wifi_state).is_connected()) {
it.printf(0, 32, id(font_small), "IP: %s", id(wifi_ip_address_sensor).state.c_str());
it.print(0, 46, id(font_small), "TagTuner Ready");
} else {
it.print(0, 32, id(font_small), "WiFi: N/A");
it.print(0, 46, id(font_small), "TagTuner Offline");
}
}
The code is from @luka6000 but is modified to fir on esp32 s3 and with display.
Any idea why write process is not successful? Any hint would be very useful since I’m banging my head to this already for few days… Thanks!