RFID tag name from id in template

With node red sequence:

[{"id":"907645a9.63a318","type":"file in","z":"ebaa69a9.649708","name":"","filename":"/config/.storage/tag","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":370,"y":2240,"wires":[["8d13f7ee.92c858"]]},{"id":"ea6a6141.d6cb6","type":"inject","z":"ebaa69a9.649708","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":2240,"wires":[["907645a9.63a318"]]},{"id":"8d13f7ee.92c858","type":"json","z":"ebaa69a9.649708","name":"","property":"payload","action":"","pretty":false,"x":550,"y":2240,"wires":[["3c8f4821.07a408"]]},{"id":"3c8f4821.07a408","type":"function","z":"ebaa69a9.649708","name":"","func":"var arr = {};\n\nfor (let value of msg.payload.data.items) {\n    arr[value.tag_id] = value.name;\n}\nmsg.arr = arr;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":2240,"wires":[["c165a8fa.6281c8","87225d05cb08334e"]]},{"id":"c165a8fa.6281c8","type":"debug","z":"ebaa69a9.649708","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":910,"y":2300,"wires":[]},{"id":"87225d05cb08334e","type":"ha-entity","z":"ebaa69a9.649708","name":"","server":"4bbca37b.1700ec","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"RFID tags"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"","stateType":"date","attributes":[{"property":"tags","value":"arr","valueType":"msg"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":890,"y":2220,"wires":[[]]},{"id":"4bbca37b.1700ec","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]

I can get an entity in HA with all the tags:

Now in an automation I can use a template to get the name of the scanned tag.

alias: New Automation
description: ''
mode: single
trigger:
  - platform: event
    event_type: tag_scanned
condition: []
action:
  - service: notify.mobile_app_YOUR_PHONE
    data:
      message: '{{ state_attr(''sensor.rfid_tags'', ''tags'')[trigger.event.data.tag_id] }}'

The node red sequence does not run by itself, it would need to be either initiated by a file watcher that looks for changes on the file or something else, or just manual as it is now.

Ah, okay - that makes sense … I would think that the ‘tag_scanned’ event could initiate the nodeRed to search the file for the relevant tag, correct?

Either way, it seems to be a work-around that would work - so I will probably look into it, but as it stands I would seriously consider it a lack of foresight not to include the tag_name in the tag_scanned event :confused:

1 Like

Yes, can be done. But caching it in a entity as I did here probably makes more sense.

Perhaps a better solution is if the automation returns unknown or unavailable or whatever the failed automation returns, use that as the trigger to run the Node red sequence.
That way when you add new tags, you swipe a new tag again and everything will be updated.

Oh, okay - I seem to have misunderstood what you’re doing.

I thought I had it down to:
For everytime a tag is scanned, search the file for corresponding name, and then initiate an automation.

The way I see you’re doing it is:
Everytime the file is changed, update the entity containing all tags from file - which is the smarter way, meaning that most of the ‘instant logic’ is preserved in HA and not passed from HA to NodeRed and back to HA at the moment a tag is scanned.

Thanks for clarifying, now I think this option is a much better alternative than my original understanding. It’s still a missing feature, that it’s not in HA itself - but your solution seems more elegant than I understood at first!

Without any doubt, this is workaround and it can be written in Appdaemon, pyscript, maybe in native python script too, not only in node red, but still, this should be built in.

It pass long time and this feature request is not implemented.
In the mean time I use workaround, some kind of ‘reverse lookup’.
In automation, after tag is scanned, i use following python program runned as shell_command:

#!/usr/bin/env python3

# Usage:
#   tag_name_by_id tag_json_filename tag_id
#
#  Example:
#    /usr/local/bin/tag_name_by_id.py /home/homeassistant/.homeassistant/.storage/tag 9876543210-01234567890
import json
import sys
import requests


cfg = {}
cfg['url'] = 'https://myurl:8123'
cfg['token'] = 'permanent_token_value'

def get_data(fname = 'tag'):
	data = []
	try:
		# Opening JSON file
		f = open(fname)

		# returns JSON object as
		# a dictionary
		data = json.load(f)
	except:
		pass
	finally:
		try:
			# Closing file
			f.close()
		except:
			pass
	return data

def find_name(data = [], id = ''):
	name = ''
	if len(data) > 0:
		try:
			for d in data['data']['items']:
				#print(d['id'])
				if d['id'] == id:
					#print('Found');
					name = d['name']
					break
		except:
			pass
	#print('Name = ['+name+']');
	return name


status = 255
if (len(sys.argv)-1) > 1:
	data = get_data(str(sys.argv[1]))
	if len(data) > 0:
		name = find_name(data, str(sys.argv[2]))
		if len(name) > 0:
			target = "tag_{}_name".format(str(sys.argv[2])).replace("-", "_" )
			url = "{}/api/states/sensor.{}".format(cfg['url'], target)
			headers = {
				"Authorization": "Bearer {}".format(cfg['token']),
				"content-type": "application/json"
			}
			postdata = '{{ "state": "{}" }}'.format(name).encode("utf-8")
			requests.urllib3.disable_warnings()
			response = requests.post(url, headers=headers, data=postdata, verify=False)
			if (response.status_code == 200) or (response.status_code == 201):
				status = 0
			else:
				status = 1
		else:
			status = 2
	else:
		status = 3
else:
	status = 4

sys.exit(status)

If id of tag is found, and it have a name, new sensor is created with id tag_tag_id and value tag name.
All eventual dashes or spaces in original tag id are replaced with underscores.
After that, it is easy to check and get name of the tag in rest of automation.

Best regards,

Please forget all above. It looks like the name is implemented in event data and can be obtained refering: {{ trigger.event.data.name }}.

yes, this feature will be available starting in 2024.6

2024.6: Dipping our toes in the world of AI using LLMs :robot: - Home Assistant (home-assistant.io)