2
0

RaspberryPiを使って入退室管理システム作ってみた!

Posted at

概要

私が所属している研究室は人が少ない!
これではきっと研究も余り進んでいないはずだ!!(偏見)
ということで、何かと便利な入退室管理システムを作ってみたら以外と面白かったのでそれについて触れていきたいと思います。

環境

  • Ubuntu 22.04 LTS
  • Raspberry Pi 4 Model B
  • RC-S380/S
  • Python 3.10.12

準備

  1. NFC/FeliCaリーダーをUSBでRasPiに接続

  2. 端末でlsusbを打ち込んで下記が出力されれば認識完了!

    Bus 001 Device 003: ID 054c:06c1 Sony Corp. RC-S380/S
    
  3. nfcpyをインストール

    $ pip install -U nfcpy
    

学生証を中身を見てみる

以下が学生証の中身を見るコードになります。

dump.py
import nfc

def on_connect(tag):
  print(tag)
  for i in tag.dump():
    print(i)
clf = nfc.ContactlessFrontend('usb')
clf.connect(rdwr={'on-connect': on_connect})

千葉工業大学の学生証だと以下のような出力が出ました。

Type3Tag 'FeliCa Standard (RC-SA00/1)' ID=01130300401E9A0A PMM=033242828247AAFF SYS=81E1
System 81E1 (unknown)
Area 0000--FFFE
  Random Service 64: write w/o key & read w/o key (0x1009 0x100B)
   0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
   *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
   0002: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  Random Service 68: write w/o key & read w/o key (0x1109 0x110B)
   0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
   *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
   0002: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  Random Service 72: write w/o key & read w/o key (0x1209 0x120B)
   0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
   *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
   000F: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  Random Service 76: write w/o key & read w/o key (0x1309 0x130B)
   0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
   0001: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  Area 2000--20FF
    Random Service 128: write with key & read w/o key (0x2008 0x200B)
     0000: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX |XXXXXXXXXXXXXXXX|
     0001: 30 33 33 31 30 30 30 30 31 20 20 20 20 20 20 20 |033100001       |
     0002: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 |                |
    Area 2100--21FF
    Random Service 132: write with key & read w/o key (0x2108 0x210B)
     0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
     *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
     0002: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
    Area 2200--22FF
    Random Service 136: write with key & read w/o key (0x2208 0x220B)
     0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
     *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
     0002: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
    Area 2300--23FF
    Random Service 140: write with key & read w/o key (0x2308 0x230B)
     0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
     *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
     0003: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
    Area 2400--24FF
    Random Service 144: write with key & read w/o key (0x2408 0x240B)
     0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
     *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
     0003: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
    Area 2500--25FF
    Random Service 148: write with key & read w/o key (0x2508 0x250B)
     0000: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX |XXXXXXXXXXXXXXXX|
     0001: 30 33 00 00 30 30 30 30 20 20 20 20 20 20 20 20 |03..0000        |
     0002: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 |                |
    Area 3000--30FF
    Random Service 192: write with key & read w/o key (0x3008 0x300B)
     0000: XX XX XX XX XX XX XX XX XX 00 00 00 00 00 00 00 |XXXXXXXXX.......|
     0001: 31 33 31 30 31 30 00 00 00 00 30 30 30 30 30 30 |131010....000000|
     0002: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000|
     0003: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX |XXXXXXXXXXXX....|
     0004: 00 00 00 00 00 00 00 00 00 00 00 00 31 20 20 20 |............1   |

(xxxの部分はプライバシーとして伏せ字という意味で使用しています。)
どこに学籍番号があるんじゃ!
っとなった方が多いかと思いますので解説して行きます。
まず、初めに下記のような項目でNFCカードの番号は決まっています。(この表はこちらの記事を参照して引用しました)

項目 意味
Type3Tag FeliCaで読み取れることを示す
RC-SA00/1 NFCカードのICチップの型番
技術情報対象製品一覧から確認することが可能
ID IDmのこと
NFCリーダー/ライターが通信相手のカードを識別するための製造ID
上位2byteが製造者コード、続く6byteがカード識別番号
PMM PMmのこと
NFCリーダー/ライターが通信相手のカードの種別と性能を識別するためのパラメータ
SYS システムコード
システムを識別するためのコード
System
Area
Service
Block
入れ子構造。Blockに書き込みや読み出しができる16byteの値が格納されている
Random Service read w/oで読み込み書き込み可を示す

入退室管理

研究室の同期が既にQRコードで入退室管理システムを作成していたのでそれと組み合わせたいと思います!
千葉工業大学の学生証ではServiceコードが128のBlockコードが0に学籍番号がASCIIコードの16進数で格納されていました。ちなみに、それ以外の番号はよくわかりませんでした!

main.py
class NFCReader:
    def __init__(self):
        self.data_num = None
    def connected(self, tag):
        idm, pmm = tag.polling(system_code=0x81e1)
        studentcard_pmm = bytearray(b'\x03\x32\x42\x82\x82\x47\xaa\xff')
        tag.idm, tag.pmm, tag.sys = idm, pmm, 0x81e1
        if studentcard_pmm = tag.pmm:
            sc = nfc.tag.tt3.ServiceCode(128, 0x0b)
            bc = nfc.tag.tt3.BlockCode(0, service = 0)
            data = tag.read_without_encryption([sc], [bc])
            self.data_num = data.decode('ASCII')
            self.data_num = self.data_num[2:9]

以上のコードはPMmを指定して千葉工業大学以外のカードは処理しないようにしています。その後、ServiceコードとBlockコードを指定してASCIIコードを取得、文字列に変換して一部切り取っています(欲しい学籍番号が7桁のでありそのままだと要らない値も受け取ってしまうため)。
以上の処理後に学籍番号のリスト内にself.data_numを探索し、あれば入室or退室とすれば、できたも同然である!

参考資料

この記事は以下の記事を参考にして書かせていただきました。

2
0
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
2
0