3
8

RFIDを使った管理システム

Last updated at Posted at 2023-11-22

RFIDを使った出席管理システムの構築

RFID技術を活用して、出席管理を自動化する方法をご紹介します。この記事では、SonyのRC-S380/S NFCリーダーを使用して、出席データを収集し、MongoDBに記録するシステムの作り方を説明します。

必要な機材とソフトウェア

  • Sony RC-S380/S NFCリーダー
  • NFCタグ(Suica)
  • Python 3.9
  • MongoDB

システム概要

このシステムは、以下の2つの主要コンポーネントから構成されます。

  1. RFID読み取りプログラム (rfid.py): NFCリーダーでタグを読み取り、MongoDBに記録します。
  2. Webインターフェース (web.py): Flaskで構築したWebアプリケーションで、記録された出席データを表示します。

環境設定

MongoDBのインストールと設定

MongoDBはNoSQLデータベースで、以下の公式ウェブサイトからダウンロードしてください。

# MongoDBのセットアップ
mongo
use attendance
db.createCollection("records")

RFID読み取りプログラム (rfid.py)

RFIDタグの情報を読み取り、MongoDBに記録するためのプログラム

import nfc
import pymongo
import datetime

# MongoDBのセットアップ
client = pymongo.MongoClient("mongodb://111.1.1.1:11111/") #自分のアドレスを設定
db = client["attendance"]
collection = db["records"]

# NFCリーダーの初期化
clf = nfc.ContactlessFrontend('usb')

try:
    while True:
        # NFCタグの読み取り
        tag = clf.connect(rdwr={'on-connect': lambda tag: False})
        if tag:
            tag_id = tag.identifier.hex()
            print(f"Detected NFC Tag with ID: {tag_id}")

            # 現在のタイムスタンプ
            timestamp = datetime.datetime.now()

            # データベースに保存
            collection.insert_one({"tag_id": tag_id, "timestamp": timestamp})
            print("Data saved to MongoDB")

except KeyboardInterrupt:
    # ユーザーがプログラムを中断するまでループ
    pass
finally:
    clf.close()
    print("NFC reader closed")

Webインターフェース (web.py)

Flaskを使って構築したWebアプリケーションのコード

from flask import Flask, render_template
import pymongo
import csv

def read_csv_file(filename):
    with open(filename, mode='r', encoding='utf-8') as file:
        reader = csv.DictReader(file)
        return list(reader)


app = Flask(__name__)

# MongoDBのセットアップ
client = pymongo.MongoClient("mongodb://111.1.1.1:11111/") #自分のアドレスを設定
db = client["attendance"]
collection = db["records"]

@app.route('/')
def index():
    # MongoDBから出席記録を取得
    attendance_records = list(collection.find())

    # CSVから学生情報を読み込む
    students_data = read_csv_file('./info.csv')

    # TagIDをキーとして学生情報と出席記録を結合
    for record in attendance_records:
        student_info = next((item for item in students_data if item["TagID"] == record["tag_id"]), None)
        if student_info:
            record.update(student_info)
        else:
            record.update({'name': '-', 'number': '登録なし'})
        

            

    # データをテンプレートに渡す
    return render_template('index.html', data=attendance_records)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Attendance Records</title>
    <style>
        table {
            border-collapse: collapse; /* セルの境界を結合 */
            width: 100%; /* テーブルを親要素の幅いっぱいに広げる */
        }
    
        th, td {
            padding: 8px; /* セル内の余白を設定 */
            text-align: left; /* テキストを左寄せにする */
        }
    
        tr:nth-child(even) {
            background-color: #f2f2f2; /* 偶数行の背景色を設定 */
        }
    </style>
    
</head>
<body>
    <h1>Attendance Records</h1>
    <table border="1">
        <tr>
            <th>number</th>
            <th>name</th>
            <th>tag_id</th>
            <th>Timestamp</th>
            
        </tr>
        {% for record in data %}
        <tr>
            <td>{{ record.number }}</td>
            <td>{{ record.name }}</td>
            <td>{{ record.tag_id }}</td>
            <td>{{ record.timestamp }}</td>
        </tr>
        {% endfor %}
    </table>
</body>
</html>

以下のinfo.csvファイルでこのようなデータ(仮)を作成する.

name number TagID
山田太郎 123456 0000000
鈴木花子 234567 123456789
佐藤一郎 345678 abcdefg

実際のWebページの表示

以下は、Webインターフェースを通じて表示される記録のスクリーンショット
site.png

3
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
8