FileMakerエンジニア
Claris FileMaker(クラリス ファイルメーカー) と Claris Connect(クラリス コネクト)、そして Raspberry Pi(ラズベリーパイ) を使って、簡単な勤怠システムを開発してみました。
勤怠システムは、どの会社にとっても必要不可欠な仕組みです。
しかし、実際には、会社ごとに運用ルールが異なるため、カスタマイズが必要になるケースが多くあり柔軟に対応できるシステムは、意外と多くありません。
FileMakerは、会社の運用に合わせて自由にカスタマイズできる点が大きな強みです。
一方で、FileMakerの機能だけではICカードや打刻端末などの物理センサーとの連携となると、制約が出てしまうこともあります。
そこで今回は、Raspberry Pi に RFID を接続し、物理センサーを通じて取得した勤怠データを FileMaker に送信する仕組みを試してみたいと思います。
目次
Raspberry Piとは?
Raspberry Piは、イギリスで生まれた「手のひらサイズの小さなコンピュータ」です。
見た目は手のひらに乗るほどのサイズですが、中身は立派なパソコンになっており、テレビやモニターにつなぐと普通のパソコンのように操作でます。
また、Raspberry Piは、普通のパソコンのように使うだけでなく、「モノを動かす」「データを集める」といったIoTにも最適です。
今回使用するのはRaspberry Pi 2Wを使用いたします。
以前に「FileMaker×Claris Connect×Raspberry Piでつくる簡単IoT温度モニタリング」のブログで紹介しておりますので是非合わせて読んでみてください。
RFIDとは?
RFID とは、Radio Frequency Identification(無線周波数識別) の略で、電波を使ってICチップ内の情報を非接触で読み書きする技術です。
身近に使用されているものだと交通系ICカード(SuicaやICOCA)が最もわかりやすいと思います。
RFIDの種類にはざっくりと4種類あり
・低周波(LF)
・高周波(HF)
・超高周波(UHF)
・マイクロ波形
の4種類があり勤怠や社員証、交通系ICカードには主に高周波が使われます。
使用モジュール
今回使用する部品(モジュール)の紹介をしたいと思います。
Raspberry Pi Pico 2 W
Raspberry Pi Pico 2 W は、小型・低価格・無線通信対応の機械や電子部品を制御するための小さなコンピュータ基板です。
センサー制御やIoT試作、電子工作にとても向いているデバイスです。
前回使用したRaspberry Pi 2 Wになりますが他のモジュールも使用するためピンヘッダを半田付けしています。
また、ブレッドボードというモジュールどうしをはんだ付けせずに電子回路を組んで試せる実験用の基盤を使用します。
RFID-RC522
RFID-RC522 は、ICカードやタグをかざすだけでIDを読み取れるRFIDリーダーモジュールです。
今回の勤怠システムの重要な部分となります。
白いカードと青いキーがRFIDとなり、RFID-RC522にセットでついてきます。
また、カードとキーは別売りでもありますので必要枚数、個数分購入ができます。
HW-504
HW-504 は、上下・左右+押し込み操作ができるアナログジョイスティックモジュールです。
ゲームのコントローラと同じ感覚で、装置の操作入力に使えます。
今回は勤怠の条件分岐のために使用いたいます。
TMB12A05
TMB12A05 は、電圧をかけるだけで音が鳴る「アクティブブザー」の代表的な型番です。
電子工作・通知音・警告音によく使われます。
RFIDを読み込んだ際に音が鳴るようにしています。
準備
FileMaker
今回は、勤怠システム自体を開発するわけではないのでRFIDの情報を受け取るために社員マスタと勤務履歴を用意いたしました。
社員マスタには二件登録しRFIDのIDをあらかじめ登録しています。
Connect
ConnectではWebhookで勤務情報をFileMakerに連携させるために使用します。
Connectの設定は「FileMaker×Claris Connect×Raspberry Piでつくる簡単IoT温度モニタリング」のブログで紹介しており設定方法も同じですので割愛いたします。
Raspberry Pi
まずはRFIDをセットします。
画像のように配線を組むことでRFIDのLEDが点灯いたします。
次に、ジョイスティックを接続します。
最後に読み込んだ際に音が鳴るようにアクティブブザーをセットします。
これでRaspberry Piとモジュールの配線が完了いたしました。
ソースコード
from mfrc522 import MFRC522
from machine import Pin, ADC
import utime
import ujson
import network
import urequests
# ===== Wi-Fi 設定 =====
WIFI_SSID = ""
WIFI_PASS = ""
# ===== Webhook 設定 =====
WEBHOOK_URL = ""
# ===== type を ASCII に変換する辞書 =====
TYPE_MAP = {
"出勤": "IN",
"退勤": "OUT",
"休憩": "BREAK",
"戻り": "RETURN",
"修正": "FIX",
"モード未選択": "NO_MODE",
}
# ===== ブザー設定 =====
BUZZER_PIN = 14
buzzer = Pin(BUZZER_PIN, Pin.OUT)
buzzer.value(0)
# ===== ビープパターン =====
BEEP = {
"ok": [40],
"error": [40, 40, 40],
"warning": [100, 40],
}
def beep(ms=60):
buzzer.value(1)
utime.sleep_ms(ms)
buzzer.value(0)
utime.sleep_ms(ms)
def beep_pattern(pattern):
for ms in pattern:
beep(ms)
utime.sleep_ms(60)
# ===== 入力(スティック)設定 =====
X_PIN = 26
Y_PIN = 27
SW_PIN = 15
CENTER = 32768
DEAD = 6000
x = ADC(X_PIN)
y = ADC(Y_PIN)
sw = Pin(SW_PIN, Pin.IN, Pin.PULL_UP)
def get_mode():
xv = x.read_u16()
yv = y.read_u16()
pressed = (sw.value() == 0)
if pressed:
return "修正"
if yv < CENTER - DEAD:
return "出勤"
if yv > CENTER + DEAD:
return "退勤"
if xv < CENTER - DEAD:
return "休憩"
if xv > CENTER + DEAD:
return "戻り"
return None
# ===== Wi-Fi / Webhook =====
def connect_wifi(timeout_sec=20):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if wlan.isconnected():
print("Wi-Fi: すでに接続済み", wlan.ifconfig())
return wlan
print("Wi-Fi: 接続開始...")
wlan.connect(WIFI_SSID, WIFI_PASS)
start = utime.time()
while not wlan.isconnected():
if utime.time() - start > timeout_sec:
print("Wi-Fi: 接続タイムアウト")
return wlan
utime.sleep(1)
print("Wi-Fi: 接続OK", wlan.ifconfig())
return wlan
def ensure_wifi():
wlan = network.WLAN(network.STA_IF)
if not wlan.active():
wlan.active(True)
if not wlan.isconnected():
connect_wifi(timeout_sec=20)
def send_webhook(payload):
"""Webhook に JSON を POST(ASCIIのみで送信)"""
try:
ensure_wifi()
body = ujson.dumps(payload).encode("utf-8")
headers = {"Content-Type": "application/json", "Accept": "application/json"}
res = urequests.post(WEBHOOK_URL, data=body, headers=headers)
print("Webhook送信OK:", res.status_code)
print("Response:", res.text)
res.close()
except Exception as e:
print("Webhook送信エラー:", e)
# ===== RC522 初期化 =====
reader = MFRC522(
sck=6,
mosi=7,
miso=4,
rst=22,
cs=5
)
reader.init()
# ===== 起動処理 =====
connect_wifi(timeout_sec=30)
print("RC522 RFIDリーダー起動中...")
print("スティックを倒しながらカードをかざしてください")
# ===== メインループ =====
last_uid = None
def build_payload(mode_jp, cardno):
if mode_jp:
beep_pattern(BEEP["ok"])
print(f"{mode_jp} {cardno}")
type_ascii = TYPE_MAP.get(mode_jp, "UNKNOWN")
else:
beep_pattern(BEEP["error"])
print(f"モード未選択 {cardno}")
type_ascii = TYPE_MAP["モード未選択"]
payload = {"type": type_ascii, "id": cardno}
print("送信JSON:", ujson.dumps(payload))
return payload
while True:
mode_jp = get_mode()
status, _ = reader.request(reader.REQIDL)
if status == reader.OK:
status, uid = reader.SelectTagSN()
if status == reader.OK:
cardno = reader.tohexstring(uid)
if cardno != last_uid:
payload = build_payload(mode_jp, cardno)
send_webhook(payload)
last_uid = cardno
utime.sleep_ms(800)
else:
last_uid = None
utime.sleep_ms(50)
動作確認
それでは、実際の動作を動画で確認してみましょう。
まとめ
いかがでしたでしょうか。
物理センサーを組み合わせることで、業務の幅が大きく広がるのも、FileMakerの高いカスタマイズ性があってこそ実現できるものです。
さらに、 Claris Connect の登場によりAPIなどの専門的で難しい技術を意識することなく、外部サービスやデバイスとの連携を比較的簡単に構築できるようになりました。
この柔軟さと拡張性は、まさに Claris製品ならではの強みと言えるのではないでしょうか。
また、株式会社ブリエでは、FileMakerを活用したシステム開発や運用支援を行っています。
業務システムのセキュリティについてのご相談もお気軽にお問い合わせください。
多岐にわたる業種での経験を経て、現在はFileMakerを中心に活躍中のエンジニアです。ローコード開発を得意としながらも、Django、React、Flutterなどの技術にも挑戦し、幅広い開発スキルを習得。常に自分の技術を磨き、より良いソリューションを提供できるよう、継続的にスキルアップを図っています。多彩な技術を駆使して、クライアントのニーズに応える柔軟性と、迅速かつ効果的な開発力が強みです。









