お久しぶりです。
今回はFelicaを使った勤退管理システムを作ってみたので、記事を書きます。
作ろうと思った理由
僕は今、大学院生なのですが、自分の研究室にはコアタイムなどはなく、
このままだと、だらけてしまいそうなので、研究時間が可視化できるようにしようと思いました。
Googleフォームなどで作ってマウスクリックでもよかったのですが、
マウスクリックだと飽きてやめてしまいそうなので、カードをタッチするだけでよい、
Felicaを使った管理システムを作ろうと考えました。
なので、勤退管理システムというよりは、自己管理するためのものといった感じです。
購入物
今回は、Felicaの読み取りを必要とするので、Felicaを読み取れるリーダーを購入しました。
僕が買ったものよりも新しいものもあるようですが、今回のような目的であれば、
古い方が安くてよいと思います。
買ったものは以下に貼っておくので、参考にしてください。
ドライバーのインストール
Felicaリーダーを購入したら、FelicaをPCのUSB端子に接続します。
その後、ドライバーをインストールします。
ドライバーは下記の場所からとって、実行して、インストールすればよいです。
Zadig - USB driver installation made easy
他の方の記事を読むと、libusbというものをインストールされている方が多いですが、
なくても動いたので、なくても良いのだと思います。
Pythonコード
今回は、Pythonで読み取りなどを実装します。
Felicaを扱うにあたって、nfcpyというライブラリをインストールします。
pip install nfcpy
nfcpyの使い方に関しては、公式のドキュメントを見ると大体わかるようになっています。
Getting started — nfcpy 1.0.3 documentation
今回は出勤と退勤時間をスプレッドシートに記録するような形での実装を目指して実装します。
まず、出勤用と退勤用のカードを用意して、それぞれのIDを調べます。
IDを調べるには、以下のようなコードを書けばよいです。
import nfc def on_connect(tag): print(tag.identifier) if __name__=="__main__": clf = nfc.ContactlessFrontend('usb') while clf.connect(rdwr={'on-connect': on_connect, 'targets': ['212F']}): print("connect") clf.close()
これで、自分のSuicaをタッチしてみると、以下のようなIDmであることが分かりました。
b'\x01\x14\x01\x14\xd4\x17:\x05'
これを基に出勤及び退勤用カードがタッチされた時の処理を書きます。
普通にif分とかで分岐しておけば良いです。
最終的には以下のようになりました。
スプレッドシートへの書き込みも行われていますが、その部分に関しては、
また今度記事を書きたいと思います。
import nfc from nfc.clf import RemoteTarget import datetime from oauth2client.service_account import ServiceAccountCredentials import gspread pre_connect_time1 = datetime.datetime.now() - datetime.timedelta(days=1) pre_connect_time2 = datetime.datetime.now() - datetime.timedelta(days=1) def on_connect(tag): global pre_connect_time1,pre_connect_time2 dt_now = datetime.datetime.now() dt1 = dt_now - pre_connect_time1 dt2 = dt_now - pre_connect_time2 if(tag.identifier==b'...自分のカードのIDmにすればよいです'): if(dt1.total_seconds()>60*30): pre_connect_time1 = dt_now print("出勤") write_spread_sheet(["出勤",dt_now.strftime('%Y-%m-%d %H:%M:%S')]) elif(tag.identifier==b'...自分のカードのIDmにすればよいです'): if (dt2.total_seconds() > 60 * 30): pre_connect_time2 = dt_now print("退勤") write_spread_sheet(["退勤", dt_now.strftime('%Y-%m-%d %H:%M:%S')]) else: print("カードが違います") def write_spread_sheet(str_contents): scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive'] credentials = ServiceAccountCredentials.from_json_keyfile_name('GCPのキーファイル', scope) gc = gspread.authorize(credentials) worksheet = gc.open_by_url( "スプレッドシートのURL").sheet1 worksheet.append_row(str_contents) if __name__=="__main__": clf = nfc.ContactlessFrontend('usb') while clf.connect(rdwr={'on-connect': on_connect, 'targets': ['212F']}): print("connect") clf.close()