Raspberry Pi で スマホを使った勤怠管理1

大抵のスマホに標準装備な「felica」いわゆるオサイフケータイですね。

今回は、非接触ICカードリーダ(ライタ)を使用して、このfelicaをスキャン、日時とIDを取得してみます。

この「非接触カードリーダ(ライタ)」ですが、SONY製で、この時期(年度末)によく売れているようです。

理由は確定申告。「マイナンバーカード」を持っていれば、PCを使ってWEBで入力、マイナンバーカードをスキャンすることで確定申告が完了するのですが、この「スキャンする」際に使用します。

 

 

1. 機器の購入

  自分は引き出しに眠っていた古い機種を使用します。(RC-310Sという機種)

  いろいろな機種が発売されていますが、今回の目的であればどれでも使用できると思います。(試していませんので、断言できませんが)


 


 

 

2. 接続

  USB(Type-A)で差すだけ。
  Raspberry Pi Zero を使用している場合は変換が必要です。

 


 

 

3. ライブラリのインストール

  以前の記事で、その内容を紹介しています。

 

letraspberry.hatenablog.com

 

4. Pythonプログラミング

  基本的に、ライブラリインストール時のものと変わりません。

  変更したのは以下の仕様。

  ・定期的(約1秒毎)にスキャンしてみる

  ・スキャンできたら、その日時とIDを表示

  ・リーダにずっとかざしたままの状態ではスキャンしたとみなさない(一度話して、何もスキャンされていない状態にしないと、スキャンしたとみなさない)

  

  スキャンログとして、スキャンした(されていない)結果も表示しています。

  次回は、この内容を外部にファイル出力(CSV形式を想定)してみようと思います。

  Excelあたりでこのファイルを読込み、IDと氏名を紐づけして勤怠管理(出社、退社)をしてみようかと思います。

 

# -*- coding: utf-8 -*-
# 日本語コメントをエラーとしないように、UTF-8で保存

# 使用するライブラリのインポート
import datetime
from ctypes import *
from time import sleep

# 定数の定義
FELICA_POLLING_ANY = 0xffff
NONE_SCAN = '0000000000000000'

# ライブラリの読込
libpafe = cdll.LoadLibrary("/usr/local/lib/libpafe.so")

def scan_felica():
    """
    felicaのスキャン
    """
    # 初期化
    libpafe.pasori_open.restype = c_void_p
    pasori = libpafe.pasori_open()
    libpafe.pasori_init(pasori)
    libpafe.felica_polling.restype = c_void_p
    idm = c_ulonglong()
    # 読込
    felica = libpafe.felica_polling(pasori, FELICA_POLLING_ANY, 0, 0)
    libpafe.felica_get_idm.restype = c_void_p
    libpafe.felica_get_idm(felica, byref(idm))
    # 16進表記で取得
    fericaData = "%016X" % idm.value
    # 後始末
    libpafe.free(felica)
    libpafe.pasori_close(pasori)
    # スキャン結果を返す
    return fericaData

felicaID_old = NONE_SCAN
felicaID = NONE_SCAN

while True:
    # デバッグ用ログ
    print(f'{felicaID}, {felicaID_old}')
    # felicaスキャンする
    felicaID = scan_felica()

    if felicaID == NONE_SCAN:
        # スキャンされていない
        if felicaID_old != NONE_SCAN:
            # カードを離した
            felicaID_old = NONE_SCAN
            # 終わってしまえ
            # exit(0)
        else:
            # スキャンされていないのが続いている
            pass
    elif felicaID_old == felicaID:
        # 同じものがスキャンされ続けているので何もしない(カードを離してくれるのを待つ)
        pass
    else:
        # スキャンされた
        now = datetime.datetime.now()
        # 日時とIDの表示
        scan_info = f'SCAN,{now.strftime("%Y/%m/%d %H:%M:%S")},{felicaID}'
        print(scan_info)
        # 日時とIDのログ出力
        with open('log.txt', mode="a") as logfile:
            logfile.write(scan_info + '\r\n')
        # スキャンされたIDの更新
        felicaID_old = felicaID
    
    sleep(1)