【実践】Raspberry PiとNFCリーダー(PaSoRi)で勤怠・会員証システムを自作する

Raspberry Pi

導入

お店の会員証やオフィスの入退室管理などで、ICカードをリーダーにかざすシステムはおなじみですよね。実は、Raspberry Piと市販のNFCリーダーを使えば、このようなシステムを自分で作ることができます。

この記事では、私自身が実際に開発した「ICカード(FeliCa)を読み取ってAPIサーバーに情報を送信し、結果に応じて音や画面表示を変える」システムのPythonコードを元に、その仕組みと応用方法を詳しく解説します。


なぜ作ったのか? システムの全体像

このシステムの目的は、ICカードのID(FeliCa IDm)をキーとして、会員情報や出退勤時間をサーバーで管理することです。

システムの処理フロー:

  1. Raspberry Piに接続されたNFCリーダー(SONY PaSoRi)が、常時ICカードを待機。
  2. カードがタッチされると、Pythonスクリプトがカード固有のIDmを読み取る。
  3. IDm、端末情報、タイムスタンプなどをAPIサーバーに送信する。
  4. APIサーバーはIDmを元に会員情報を照会し、結果(OK/NGなど)をJSON形式で返す。
  5. Raspberry Piは結果に応じて、成功音やエラー音を鳴らしたり、接続されたモニターにメッセージを表示したりする。

このような仕組みにすることで、高価な専用端末を導入することなく、機能的でコストパフォーマンスの高い勤怠・会員証システムを自作できます。


中核を担うPythonコードの解説

このシステムは、nfcpyというライブラリを中心に構築されています。nfcpyは、PythonでNFCデバイスを簡単に扱うための定番ライブラリです。

1. NFCカードの読み取り

カードがタッチされたことを検知し、そのIDmを取得する部分です。nfc.ContactlessFrontendを使ってリーダーを初期化し、connect()メソッドでカードのタッチを待ち受けます。

import nfc
import binascii

def on_connect(tag):
    # カードのIDmを16進数の文字列として取得
    idm = binascii.hexlify(tag.idm)
    print(f"カードを検出しました: IDm = {idm}")

    # 読み取ったIDmを使って、後続のAPI通信処理などを呼び出す
    # self.get(idm)
    return True

# USB接続のNFCリーダーを初期化
clf = nfc.ContactlessFrontend('usb')
try:
    # on_connectコールバック関数を登録して待機
    clf.connect(rdwr={'on-connect': on_connect})
finally:
    clf.close()

on_connectは、カードが検知されたときに自動的に呼ばれるコールバック関数です。ここでIDmの取得や、後続の処理の呼び出しを行います。

2. APIサーバーへのデータ送信

requestsライブラリを使って、取得したIDmなどの情報をWeb APIに送信します。

import requests
from datetime import datetime

def get_mac_address(interface='wlan0'):
    # MACアドレスを取得して、端末固有のIDとして利用
    try:
        with open(f'/sys/class/net/{interface}/address') as f:
            mac = f.read().strip()
    except:
        mac = "00:00:00:00:00:00"
    return mac

def send_to_api(idm):
    # APIのエンドポイントURL
    api_url = 'https://example.com/api/attendance'

    # 送信するデータを作成
    payload = {
        'felica_idm': idm,
        'mac_address': get_mac_address(),
        'touch_datetime': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }

    try:
        # GETリクエストとしてAPIに送信し、結果をJSONで受け取る
        response = requests.get(api_url, params=payload)
        response.raise_for_status()  # エラーがあれば例外を発生

        # サーバーからの応答を処理
        result = response.json()
        print(f"サーバーからの応答: {result}")

    except requests.exceptions.RequestException as e:
        print(f"API通信エラー: {e}")

3. 結果に応じたフィードバック

APIからの応答(JSON)を解析し、結果に応じて音を鳴らしたり、画面にメッセージを表示します。

音の再生にはpygame、画面表示にはtkinterを使用するのが便利です。

音の再生:

import pygame.mixer

pygame.mixer.init()
# APIの応答が 'OK' だったら成功音を鳴らす
if result.get("return_msg") == 'OK':
    sound = pygame.mixer.Sound("/path/to/ok.wav")
    sound.play()
else:
    sound = pygame.mixer.Sound("/path/to/ng.wav")
    sound.play()

GUI画面表示:

import tkinter as tk

root = tk.Tk()
root.title("NFCリーダー")
root.geometry("800x600") # ウィンドウサイズ

# 表示するメッセージ
message = result.get("display_msg", "カードを読み取りました")

label = tk.Label(root, text=message, font=("Helvetica", 48))
label.pack(pady=200)

# 2秒後に自動でウィンドウを閉じる
root.after(2000, root.destroy)
root.mainloop()

このシステムの応用アイデア

この仕組みは、様々な用途に応用できます。

  • 小規模店舗の会員カードシステム: ポイントカードの代わりに、お客様のICカード(交通系ICなど)を登録してもらう。
  • イベントやセミナーの受付システム: 参加者に事前にIDを配布しておき、当日の受付をスムーズに行う。
  • 子どもの帰宅・外出通知システム: 子どもが家の鍵に付けたICタグをかざすと、親のスマホに通知が届く。

まとめ

今回は、Raspberry PiとNFCリーダー、そしてPythonを使って、実用的なカードリーダーシステムを自作する方法をご紹介しました。

一つ一つのライブラリの使い方はシンプルですが、これらを組み合わせることで、「人の役に立つ」価値あるシステムを低コストで実現できます。

この記事が、あなたの次のDIYプロジェクトの「ヒント」になれば幸いです。ぜひ、オリジナルのカードリーダーシステム作りに挑戦してみてください。

コメント

タイトルとURLをコピーしました