Formatting ndef.message

Asked by Jeremy Pena on 2015-02-12

Hello guys! I hope this is the correct place to ask for help. I just installed nfcpy. I am wondering if there is a way to get just the "text" from the NDEF message? Here is just some example code I have.

import nfc
print 'Awaiting tag.'
with nfc.ContactlessFrontend('tty:AMA0:pn53x') as clf:
     tag = clf.connect(rdwr={'on-connect': None})
     s = tag.ndef.message
     print s if tag.ndef else "Sorry, no NDEF"

here is the output:

pi@CoffeeTable:~/pythonprogs/nfcpy$ python poop.py
Awaiting tag.
Ă‘TenHeather Marks
pi@CoffeeTable:~/pythonprogs/nfcpy$

is there anyway to format "Ă‘TenHeather Marks" to just read "Heather Marks"? I tried standard python formatting s[3:] but that returns "[]". I am assuming it's because its formatted to some kind of record type. I appreciate any help you guys can give me.

Question information

Language:
English Edit question
Status:
Solved
For:
nfcpy Edit question
Assignee:
No assignee Edit question
Solved by:
Stephen Tiedemann
Solved:
2015-02-13
Last query:
2015-02-13
Last reply:
2015-02-13

The type of tag.ndef.message is an nfc.ndef.Message object, which is basically a list of nfc.ndef.Records. You can easily see this structure with print(tag.ndef.message.pretty()). In your case there is most likely just a single record contained, thus record=tag.ndef.message[0] would retrieve that. Each record has a type attribute, if it is an NDEF Text Record then "record.type=="urn:nfc:wkt:T" should be True. The record can then be converted to print the text print(nfc.ndef.TextRecord(record).text).

See https://nfcpy.readthedocs.org/en/latest/modules/ndef.html for documentation of NDEF record and message classes and https://nfcpy.readthedocs.org/en/latest/topics/ndef.html for an overview of NDEF handling in nfcpy.

Last but not least, you should check tag.ndef before accessing the message attribute. If the tag is not NDEF formatted the tag.ndef attribute will be None and accessing None.message will raise an exception.

Jeremy Pena (krillik08) said : #2

Thank you so much Stephen! I am new to python in general but I was able to understand what you wrote and make it work for me. I would like to post my updated code for anyone else who might have this problem. I am sure this is not the best code, but it works! Thanks!

#!/usr/bin/python2.7
import nfc
import time
import logging
import kodi_parser

while True:
 print 'Awaiting tag.'
 with nfc.ContactlessFrontend('tty:AMA0:pn53x') as clf:
  tag = clf.connect(rdwr={'on-connect': None})
  if tag.ndef is not None:
   record = tag.ndef.message[0]
   if not record:
    s = nfc.ndef.TextRecord(record).text
    kodi_parser.Kodi_Exec(s)
   else:
    print('Empty record')
  else:
   print('Sorry, no NDEF')
 time.sleep(10)

Jeremy Pena (krillik08) said : #3

Thanks Stephen Tiedemann, that solved my question.

The nfc.ndef.Record class has no distinction of False or True, a boolean evaluation does always produce False. The cleanest way would be to check the record type:

if record.type == "urn:nfc:wkt:T":
    print(nfc.ndef.TextRecord(record).text)
else:
    print("Not a text record")

An alternative would be to just catch the ValueError exception that would happen when record is not a TextRecord:

try:
    print(nfc.ndef.TextRecord(record).text)
except Value Error as error:
    print("conversion failed:" + error.message)