M5Stackを使うと非常に安価にクラウド連携のタイムレコーダーを作成することができます。
今回は、RFIDユニットと非接触ICカードを組み合わせてカードをピッとすると打刻データがkintoneに即アップロードされる方式のタイムレコーダーを作成しました。
アップロードしたデータを使いkintone上で勤務簿作成や給与処理などの就業管理の自動化ができると思います。
非接触ICカードとは、日本ではSuicaやnanacoとして知られているものです。
下図はM5Stack直販で購入した際におまけとしていただいていたICカードで、よく知られているICカードとまったく同じ形状をしていることがわかります。
カードごとにユニークなIDが付与されており、これを社員マスタなどと関連付けることでカードだけで社員の特定ができるようになります。
フィールド名 |
データ型 |
フィールドコード |
打刻時刻 | 文字列(1行) | hms |
カードID | 文字列(1行) | card_id |
打刻モード | 文字列(1行) | mode |
※APIからアップロードする際に使用するのは、kintone上の「フィールド名」(設定画面一番上の項目)ではなく「フィールドコード」(設定画面一番下の項目)である点に注意が必要です。
from m5stack import * from m5ui import * from uiflow import * import urequests import wifiCfg import ntptime import time import unit setScreenColor(0x222222) rfid0 = unit.get(unit.RFID, unit.PORTA) x = None hms = None id2 = None mode = None API_URL = None xx = None API_TOKEN = None lastid = None APP_ID = None STATUS_TEXT = None wifiCfg.autoConnect(lcdShow=True) wifiCfg.reconnect() # Describe this function... def format2digits(x): global hms, id2, mode, API_URL, xx, API_TOKEN, lastid, APP_ID, STATUS_TEXT if x <= 9: xx = (str('0') + str(str(x))) else: xx = str(x) return xx # この関数の説明… def sendToKintone(hms, id2, mode): global x, API_URL, xx, API_TOKEN, lastid, APP_ID, STATUS_TEXT try: req = urequests.request(method='POST', url=API_URL,json={'app':APP_ID,'record':({'hms':({'value':hms}),'card_id':({'value':id2}),'mode':({'value':mode})})}, headers={'X-Cybozu-API-Token':API_TOKEN,'Content-Type':'application/json'}) speaker.tone(1200, 10) STATUS_TEXT = '' except: speaker.tone(400, 3000) STATUS_TEXT = 'エラー' def buttonA_wasPressed(): global hms, API_URL, xx, mode, id2, API_TOKEN, lastid, APP_ID, x, STATUS_TEXT setScreenColor(0x000066) mode = 0 lastid = '__timecard__' speaker.tone(1800, 200) pass btnA.wasPressed(buttonA_wasPressed) def buttonC_wasPressed(): global hms, API_URL, xx, mode, id2, API_TOKEN, lastid, APP_ID, x, STATUS_TEXT setScreenColor(0x663300) mode = 1 lastid = '__timecard__' speaker.tone(1800, 200) pass btnC.wasPressed(buttonC_wasPressed) @timerSch.event('rfid') def trfid(): global hms, API_URL, xx, mode, id2, API_TOKEN, lastid, APP_ID, x, STATUS_TEXT if rfid0.isCardOn(): id2 = rfid0.readUid() if id2 != '' and id2 != lastid: sendToKintone(hms, id2, mode) lastid = id2 else: pass pass @timerSch.event('clock') def tclock(): global hms, API_URL, xx, mode, id2, API_TOKEN, lastid, APP_ID, x, STATUS_TEXT hms = (str(str(format2digits(ntp.hour()))) + str(((str(':') + str(((str(str(format2digits(ntp.minute()))) + str(((str(':') + str(str(format2digits(ntp.second()))))))))))))) print(hms) lcd.clear() lcd.font(lcd.FONT_DejaVu72) lcd.print(str(hms), 0, 0, 0xffffff) lcd.font(lcd.FONT_DejaVu24) lcd.print(str(id2), 0, 80, 0xffffff) lcd.font(lcd.FONT_UNICODE) lcd.print(str(STATUS_TEXT), 0, 120, 0xffffff) lcd.font(lcd.FONT_UNICODE) if mode == 0: lcd.rect(10, 185, 105, 45, color=0xffff00) elif mode == 1: lcd.rect(200, 185, 105, 45, color=0xffff00) else: lcd.rect(10, 185, 105, 45, color=0xffffff) lcd.rect(200, 185, 105, 45, color=0xffffff) lcd.print('出勤', 40, 195, 0xffffff) lcd.print('退勤', 225, 195, 0xffffff) lcd.print('', 0, 200, 0xffffff) pass API_URL = 'YOUR_API_URL' API_TOKEN = 'YOUR_API_TOKEN' APP_ID = 'YOUR_APP_ID' while not (wifiCfg.wlan_sta.isconnected()): wait(1) setScreenColor(0x000000) ntp = ntptime.client(host='ntp.nict.jp', timezone=9) id2 = '' mode = 0 lastid = '__timecard__' STATUS_TEXT = '' setScreenColor(0x000066) timerSch.run('clock', 1000, 0x00) timerSch.run('rfid', 500, 0x00)
作成していて気づいたのですが、連続して打刻データを飛ばさないように同一ID、同一モードの時はkintoneにデータを送信しないように工夫したもののときどき変なデータがアップロードされてきました。
どうもIDの読み取りに失敗するとブランクや桁数に満たない変なデータが送られてしまう時があるようです。
本格的な運用の際には桁数チェックなどを入れるともよいかもしれません。
それにしても、今回作成した組み合わせではだいたい6000円くらいでクラウド連携のタイムレコーダーができてしまい驚きます。ICカードもM5Stackで5枚で2ドルと大変リーズナブルに入手できるので大量配布しても導入コストをかなり抑えたものができそうです。
[…] 前回『M5Stackを使い非常に安価なクラウド連携(kintone)タイムレコーダーを作…では、M5Stackを使ってタイムレコーダーを作ってみましたが、今回はRaspberry PiとICカードリーダ、kintoneを使ってクラウド連携のタイムレコーダーが作れるか実験してみました。Raspberry Piの場合、USB機器やHATを介してGROVE規格のセンサーやディスプレイ、制御装置などと連携し複雑な処理を行うことができるようになります。 […]