-->

Saturday, January 25, 2020

RFID & Airtable

As mentioned in the previous post, one use case is to load a picture of the real engine from my online database when the model goes over the RFID reader. Here's the big plan:



In this post, I am focusing on the link between the RFID reader and the Airtable link to display a picture. I'm therefore not looking at the ampoule tag and I'm not yet using the Raspberry Pi, but rather my desktop.


Reading from the Arduino


It's actually very easy to read the RFID tag from PyCharm on my desktop. Here's the code:

import serial

prefix = 'Card UID: '

ser = serial.Serial('COM3', baudrate=9600, timeout=0.1)

while 1:
    data = ser.readline().decode('ascii')
    if data.startswith(prefix):
        tag_id = data.replace(prefix, '').strip()
        print(tag_id)

And the output is:

C:\Tools\python37env\Scripts\python.exe C:/Users/Olivier/dev/workspace/airtable/test/test_arduino.py
83 78 FF 20

Process finished with exit code -1


Airtable


Airtable is basically a smart spreadsheet in the cloud. For this test, I just want a simple table with a name, a picture, and a RFID tag. It looks like this:




Airtable APIs are easy to use.

import os
from pprint import pprint
from airtable import Airtable

base_key = 'appC0WNPsCWPblK9H'
table_name = 'Test'
airtable = Airtable(base_key, table_name, api_key=os.environ['AT_API_KEY'])

pages = airtable.search('RFID', '83 78 FF 20')

for page in pages:
      pprint(page)

And the output is:

C:\Tools\python37env\Scripts\python.exe C:/Users/Olivier/dev/workspace/airtable/test/test_connection.py
{'createdTime': '2020-01-31T01:37:03.000Z',
 'fields': {'Image': [{'filename': '25612dd9',
                       'id': 'attWjRFWBQNc8hR1M',
                       'size': 189794,
                       'thumbnails': {'full': {'height': 3000,
                                               'url': 'https://dl.airtable.com/.attachmentThumbnails/1725a5c5e29346176b5952ad854700fb/edc60ca7',
                                               'width': 3000},
                                      'large': {'height': 512,
                                                'url': 'https://dl.airtable.com/.attachmentThumbnails/22420833e058b905df01446d39546abe/6146ffea',
                                                'width': 785},
                                      'small': {'height': 36,
                                                'url': 'https://dl.airtable.com/.attachmentThumbnails/b153b0d6c4f532ca2c53f3c6f9405dc0/38dd801d',
                                                'width': 55}},
                       'type': 'image/jpeg',
                       'url': 'https://dl.airtable.com/.attachments/dd7cb8ee2ad8bf31e0926d7b4f882457/20e7d88d/25612dd9'}],
            'Nom': 'AM 08182',
            'RFID': '83 78 FF 20'},
 'id': 'recgQuOmkF3jJP8o0'}

Process finished with exit code 0


Putting everything together


I can now link both codes into this one:

import os
import requests
import serial
from airtable import Airtable
from pathlib import Path
from pprint import pprint

airtable_base_key = 'appC0WNPsCWPblK9H'
airtable_table_name = 'Test'
arduino_tag_prefix = 'Card UID: '
path_local_cache = 'images/'
use_local_cache = False


def get_local_filename_from_tagid(tag):
    return path_local_cache + tag.replace(' ', '_') + '.jpg'


def get_from_airtable(tag_id, file_name):
    pprint('Calling AirTable for {}'.format(tag_id))
    airtable = Airtable(airtable_base_key, airtable_table_name, api_key=os.environ['AT_API_KEY'])
    results = airtable.search('RFID', tag_id)

    if len(results) == 0:
        pprint('No results found for RFID Tag {}'.format(tag_id))
    else:
        if len(results) > 1:
            pprint('More than 1 result found for RFID Tag {}'.format(tag_id))
        url = results[0]['fields']['Image'][0]['url']
        f = open(file_name, 'wb')
        f.write(requests.get(url).content)
        f.close()


def display(tag):
    # get local filename and check local cache if required
    filename = get_local_filename_from_tagid(tag)

    if use_local_cache:
        pprint('Looking in local cache for {}'.format(tag_id))
        local_file = Path(filename)
        if not local_file.is_file():
            get_from_airtable(tag, filename)
    else:
        get_from_airtable(tag, filename)

    os.system('start {}'.format(filename))


ser = serial.Serial('COM3', baudrate=9600, timeout=0.1)
while 1:
    data = ser.readline().decode('ascii')
    if data.startswith(arduino_tag_prefix):
        tag_id = data.replace(arduino_tag_prefix, '').strip()
        display(tag_id)

And it is working as expected: