NFC - Near Field Communication

The nfc extension allows you to read and write nfc tags through the system. There are a variety of supported readers that you can use.

It is important that you pay attention to the type of tag and reader you are using. Not all readers work with all tags and not all readers have all the features of others.

To get a little more familiar with NFC it is suggested that you download an NFC app on your phone and try reading/writing to a tag. Most newer phones support NFC but usually it has to be enabled in settings.


Extension Configuration

Here are the settings to provide a NFC reader/writer connection that can communicate with tags.

OptionTypeRequiredDescription
key[String]YesUnique slug id for the component
address[String]YesAddress of NFC reader. i.e. usb:072f:2200 If no address is set MudPi will try to find a default using the model. If no address or model is set then an error will be raised.
name[String]NoFriendly display name of component. Useful for UI.
model[String]NoModel of the reader. Used if no address is set to attempt and find default address. See options here
beep_enabled[Boolean]NoSet to True if reader should beep when tag is scanned (if hardware supports it). Default: false
writing[Boolean]NoSet to true to enable writing to tags. Default: false
tracking[Boolean]NoSet to true to enable writing simple tracking data to tags. Default: false. You must have writing enabled to use tracking.
persist_records[Boolean]NoIf true any existing records will be kept on tag during and writes. Only tracking data will be updated. Default: true
tags[Dict]NoA dict of tags keyed by the tag serial to preregister to the system.
save_tags[Boolean]NoSet to true to save any scanned tags into tags in the config. Default: false
default_records[Array]NoA list of default records to write to each tag if writing is true.
store_logs[Boolean]NoLog a list of recent tag scans if set to true. Default false
log_length[Integer]NoWhen store_logs is enabled this is the max length of the log. Default: 100

Config

Here is the config of a complete NFC setup.

"nfc": {
    "key": "nfc_usb_reader",
    "address": "usb:072f:2200",
    "model": "ACR122U",
    "beep_enabled": false,
    "tracking": false,
    "persist_records": true,
    "save_tags": false,
    "writing": true,
    "default_records": [
        {
            "type": "text",
            "data": "MudPi",
            "position":0
        },
        {
            "type": "uri",
            "data": "https://mudpi.app/docs",
            "position":1
        }
    ]
}

Tag Events

Once you have configured a NFC reader in MudPi you can now scan tags / cards. Anytime you scan a tag MudPi will emit a NFCTagScanned event on the nfc topic. This event will contain data about the tag including and NDEF data found.

The tag will be considered new if if was not previously read and not found in the tags config dict. When a new tag is found a NFCNewTagScanned event is emitted with data about the tag including any NDEF data.

Another useful feature is that you may want to know when a tag was removed from the reader. This can be useful if you want to enable features only while a tag is present. To listen when a tag is removed you can check for a NFCTagRemoved event on the nfc topic when the tag is removed.

Writing to Tags

MudPi can also write to the tag as well if your hardware supports it. Be sure to verify the card type before writing to it and that your writer supports it. Writing to tags is disabled by default but if you wish to enable it you can set writing to true in you configs.

Default Tag Records

Data written to tags is in the form of NDEF. MudPi will write some basic data such as some text and a link to the nfc docs to the tag for you if writing is enabled. If you wish to disbale this default data you can set default_records to an empty list.

If you wish to provide your own default records then you can provide a list of dict objects with the following options:

OptionTypeRequiredDescription
data[String]YesData to write to card. If its a URI be sure to include any protocols or headers such as http://.
type[String]NoType of NDEF data to write. Options text and uri. Default is text.
position[Integer]NoPosition you want data inserted into records list. List is 0 based index. If no position is set the data is appended to end.

Tracking

Another useful feature with writing to tags is tracking. If enabled tracking provides some simple records that will be wrote the the tag to add additional use information. By default MudPi will only rememebr the tag serial number. This data is forgot on every reset if save_tags is not enabled as it is only stored in memory.

When you enable tracking MudPi will write two additional records to the tag including a count:# and a last_scan:{datetime}. The count is a simple counter that gets incremented everytime the card is scanned. This can be useful to track scan totals. The other data stored is a last scan datetime. This just informs us the last time the card was scanned.

Tag UID

Each tag comes with a unique serial number. This serial number is often the main way to track a tag and how MudPi tracks tag scans by default. As an added security measure when writing is enabled MudPi will generate a uuid for the card that will be stored. This uuid paired with the tag serial number allows MudPi to detect copies of cards of if data was altered outside of MudPi. In the event a mismatching uuid is found then MudPi will emit a warning you can hook into.

Preregister Tags

You may want to preregister tags in the system so that MudPi can perform additional operations. If you want to preregister a tag you can do so in the tags option of the configuration. The tags is a dict object keyed by the serial number of the tag and contains the tag data such as a tag_uid. If you wish to provide default_records specific for a tag then you can provide them here in the same format as described above. Put them under a key default_records for the tag you want them to be wrote to.

Here is an example of a preregistered tag with a serial of 123456789ABCD:

"nfc": {
    ...
    "tags": {
        '123456789ABCD': {
            "tag_uid": "123113-12313123-123123131-1331231",
            "default_records": [
                {
                    "type": "text",
                    "data": "Custom Default Record for Tag",
                    "position":0
                }
            ]
        }
    }
}

If you have save_tags set to true then MudPi will update this tags dict for you with new tags as they are scanned in the system.

Setting Up NFC on Raspberry Pi or Linux

There are a number of readers you can choose from, I personally found success with the usb readers. On most linux distributions the needed drivers will already be installed. You should visit the reader manufactures page to get any missing drivers if you get errors. The NFC reader has a default address you can use or you can look up the address by running the nfc module with the following command.

python3 -m nfc

This should output some information about any discovered readers and their address. It is likely that you will run into permission errors on your first run. This is because you need to add some rules and groups that will be suggested to you when running the command above.

On the raspberry pi I ran the following command to give proper permissions to the reader through a plugdev group:

sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"072f\", ATTRS{idProduct}==\"2200\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules' 

I than ran the next command and reattached the reader:

sudo udevadm control -R

You will also need to be sure the user account is a member of this plugdev group we just setup permissions for.

sudo adduser mudpi plugdev