導入
お店の会員証やオフィスの入退室管理などで、ICカードをリーダーにかざすシステムはおなじみですよね。実は、Raspberry Piと市販のNFCリーダーを使えば、このようなシステムを自分で作ることができます。
この記事では、私自身が実際に開発した「ICカード(FeliCa)を読み取ってAPIサーバーに情報を送信し、結果に応じて音や画面表示を変える」システムのPythonコードを元に、その仕組みと応用方法を詳しく解説します。
なぜ作ったのか? システムの全体像
このシステムの目的は、ICカードのID(FeliCa IDm)をキーとして、会員情報や出退勤時間をサーバーで管理することです。
システムの処理フロー:
- Raspberry Piに接続されたNFCリーダー(SONY PaSoRi)が、常時ICカードを待機。
- カードがタッチされると、Pythonスクリプトがカード固有のIDmを読み取る。
- IDm、端末情報、タイムスタンプなどをAPIサーバーに送信する。
- APIサーバーはIDmを元に会員情報を照会し、結果(OK/NGなど)をJSON形式で返す。
- 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プロジェクトの「ヒント」になれば幸いです。ぜひ、オリジナルのカードリーダーシステム作りに挑戦してみてください。
コメント