• IoT

RFIDタグでホテルのカードキーシステムを再現しよう(RFIDリーダRC522+Raspberry Pi)

こんにちは、デジタル技術部の原田です。
今回は非接触ICカード(RFIDカード)を使うことで、安価にホテルのカードキーシステムを再現してみます。

TL;DR ※まとめです

  • RFIDリーダRC522を用いてRFIDタグを非接触に読み込んだ
  • Raspberry Pi Zero WHを用いてFirebaseに関連させることで家電と連携、ホテルのカードキーシステムを再現した
  • 目立たないのも考えものである笑

はじめに

ほら、ビジネスホテルに行くとあるじゃないですか。
部屋に入ってカードキーを差し込めば、部屋の電源が供給される仕組みが。
あれが自宅でも出来たらいいなと原田は思ったわけです。
電源供給を制御するとなると大変ですが、帰宅をきっかけに家電が制御されると良いわけです。
ついでに、自宅だと家族の誰が帰ってきたかということも判断したくなります。
思ったらどうするか。作るわけですよ。
(○○すると思ったなら、その時スデに行動は終わっているんだッ!ってやつですよ。5部って最高ですよね。)
しかし、何でも高価な機材を買うわけにはいきませんし、今回は妻から注文もつけられています。
玄関の見える場所にセンサーなどを置かないで、とのこと。まぁ玄関ですし、メカメカしくなってもNGですよね。
よし、ではこれだ!
「RFIDリーダRC522とRaspberry Pi Zero WH」!
非接触ICカードで対処しましょう。

用意した機材

原田家では幸いなことに、下駄箱内に電源があったので、それを活用しています。
画像では写っていませんが、赤い靴の上の方に電源があります。
• Raspberry Pi Zero WH(画像右) 1814円(スイッチサイエンス) ※ 画像ではHATが付いていますが気にしないで
• RC522 RFIDリーダ(画像左)RFIDタグとセット、かつそれが2個セットで799円(Amazon)

Raspberry Pi Zero WHはこの技術ブログでも何度と無く登場しているので詳細説明は不要でしょう。
通常のLinux機と同様に扱えるシングルボードコンピュータです。OSは通常通りRaspbianを使っています。
WHはWireless機能(WiFi/Bluetooth), Header(GPIOピンヘッダ)が搭載されたモデル、という意味です。原田は自宅用に5個所持しています。
RC522はRFIDリーダー/ライターです。RFIDタグ(冒頭の青いタグや白いカード)に埋め込まれているID番号を読取ることができます。
動作周波数は13.56MHzというHF帯(High Frequency)に属するものです。
非接触ICカードの通信規格として最も多く採用されているmifare(マイフェア)のカードを読み取ることができます。
※ 日本においては、同周波数帯のFeliCaがあります。ただしRC522はFeliCaには非対応です。Suicaなどは読み取れません。
通信距離としては0-数cm程度です。なので駅の改札のように、意図的にタッチしにいく行為が必要です。
家族それぞれに別々のRFIDタグを渡しておき、出かける時や帰ってきたときにタッチする形をとります。
機材ではありませんが、Firebase(Firestore)も使っています。タッチの際の通知先として使います。

システム構成図

システム構成

※ 今回は玄関にあるラズパイを玄関ラズパイ、変更通知を受けてGoogleHomeに発話させるラズパイを居間ラズパイと呼びます。

RFIDリーダRC522にRFIDタグをタッチしたら、カード番号がFirebaseに届いてDBが変更される。DB変更通知を受けて家電が動く。
家電はいつものラズパイ+GoogleHomeでいいでしょう。「おかえりなさい、○○さん!」と喋ってくれます。○○のところはカード番号によって変える形です。
以下は主にFirebase以前の部分について解説をします。

セットアップ

セットアップは配線編と玄関ラズパイ内でのソフトウェア編に分けて記載します。

配線編

途中にブレッドボードも挟まなくてよいので配線図はいらないと思います。表の通り配線しましょう。

Name Pin # Pin Name
SDA 24 GPIO8
SCK 23 GPIO11
MOSI 19 GPIO10
MISO 21 GPIO9
IRQ 18 GPIO24
GND 20 GND
RST 22 GPIO25
3.3V 17 3.3V

表の通りに配線すると、玄関ラズパイ側にはちょうど画像のように2列の真ん中に8ピンが配置されると思います。

IMG_0727

IMG_0725

ソフトウェア編

配線が終わったのでソフトウェアの設定を行いましょう。
最初に登録すべきRFIDタグの番号を取得します。
次にFirebaseの設定をFirebaseコンソールから行います。
最後にFirebaseに書き込みに行くPythonコードを記載します。

RFIDタグの取得

玄関ラズパイの中で行います。
ラズパイ自体のOSセットアップ、WiFiネットワーク設定は省略します。raspi-configからSPIも使えるようにしておきましょう。
ライブラリmfrc522のライセンスはGPLv3です。取扱はその点注意ください。
使用するライブラリはmfrc522, firebase_adminです。
一旦RFIDタグをリーダーで読み取るところまでいきましょう。

pip3 install mfrc522 firebase_admin 
cd (任意のディレクトリ)
mkdir mfrc522
cd mfrc522
touch read.py
read.pyを以下の通りに編集
python3 read.py

Touch the card!と表示されたらかざしてみましょう。
カードのID番号が出力されます。この番号を使います。★1

# coding: utf-8
 
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
 
reader = SimpleMFRC522()
 
try:
  print('Touch the card!')
  id, text = reader.read()
  print(id)
  print(text)
  print('done.')
finally:
  GPIO.cleanup()

Firebaseの設定

Firebaseの設定をします。FirebaseコンソールからWeb画面を操作します。 Firebaseのプロジェクトを作成し、DBとなるFirestoreを準備。後にfirebase_adminから操作できるよう秘密鍵を作成します。 Firebaseのサイトからプロジェクトを追加しましょう。 プロジェクト名は何でも良いです。

firebase01

Databaseを選択すると、Cloud Firestoreの紹介が出ています。 データベースの作成をクリック(※テストモードにして作成しておきましょう)

firebase02

コレクション「touchedCards」を追加します。

firebase03

ドキュメントも画像の通り入力して追加しましょう。★1で取得したカード番号をドキュメントのID番号、cardIdに入れておきましょう。

firebase04

また、ドキュメントを追加した後にuserNameの項目でもいれておきましょう。
このあたりは習うより慣れろです。

firebase05

ここまででコレクションとドキュメントを作成できましたが、firebaseを外部から触るために認証鍵を取得します。
プロジェクト設定→サービスアカウントを選択、Pythonを選択し新しい秘密鍵の生成をクリックしましょう。
jsonファイルが取得できます。これは秘密鍵ファイルになるため、取扱には注意しましょう。★2

firebase06

Firebaseを更新するコードの記載

玄関ラズパイの中で操作を続けます。

cd mfrc522
ここに★2の秘密鍵のファイル(.json)を配置する
touch continuousRead.py
coutinuousRead.pyを以下の通りに編集
nohup python3 continuousRead.py > out.log &

起動してしばらくするとtouch the card!と出力されるため、それ以降タッチが可能となります。
continuousReadはその名の通り継続的にRFIDカードリーダーで読み取ります。
カード番号を読み取ったら、Firebaseの特定の値を上書き保存します。
一度読み込んだら重複読み取りを避けるために3秒間待機し、その後再び読み取り状態になります。

# coding: utf-8
 
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
 
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
 
import time
import datetime
 
# credential file
cred = credentials.Certificate('./XXXXXXXXXXXXXXXXX_credential.json')
firebase_admin.initialize_app(cred)
db = firestore.client()
reader = SimpleMFRC522()
 
try:
  while True:
    print('Touch the card!')
     
    # readで読み取り中になります。以下が呼ばれた状態でRFIDタグをかざしましょう
    id, text = reader.read()
 
    print(id)
    print(text)
     
    data = {'cardId': id, 'touchedDate': datetime.datetime.utcnow()}
    docId = 'touchedCards/' + id + '/'
     
    # 事前にcreateでdocumentを作っておく必要があります。
    # 以下のコメントアウトされたコマンドを実行するか、FirebaseWebコンソールから入力して作成しておいてください
    # db.document(docId).create({'cardId': id,'touchedDate': datetime.utcnow(),'userName': 'けいじ'})
     
    # updateで更新します。dataに含まれていない項目(userName)はそのまま変更なしです。
    db.document(docId).update(data)
 
    print('done.')
    time.sleep(3)
finally:
  GPIO.cleanup()

ふう。お疲れ様でした。

これで、下駄箱の扉部分にICカードをかざすと、FirebaseのDBを更新します。
連動して最終的にはGoogleHomeがおかえりなさいけいじさん!と言ってくれます。

余談1 RFIDタグの選定と用途について

周波数帯によって通信距離が異なることから、適切な周波数帯をもつタグを選定しないといけません。
ただ、タグ側にそもそも電源を必要としないため、例えば在庫管理などの業務を劇的に省力化できる可能性があります。
現状実世界でもユニクロの値札タグにはRFIDタグが埋め込まれています。
このタグをレジにあるRFIDリーダーで複数一度に読み取っているため、合計金額の提示までの時間が短縮されているわけですね。

ユニクロの値札タグ。透かすとRFIDタグの存在が見て取れます。

生鮮食品などには当然RFIDタグは使えないでしょう。
しかし書籍などではどうでしょうか。書棚を撮影してそれを機械学習によって文字認識して蔵書管理するという例もありますが、
精度を考慮すると、RFIDタグを貼ったほうが適切だと考えられます。
タグを貼っても影響がないもの、在庫管理されるもの、認識の精度に甘さを出したくないもの そういうものに扱われるべき技術ですね。

余談2 Firestoreのリアルタイム監視について

firestoreをリアルタイムに監視する手段は限られています。Swift, Objective-C, Android, Java, Node.jsは対応していますが、
Python、Go、PHPクライアントライブラリではまだサポートされていません。(2019/05/17現在)
ということでリアルタイム監視をラズパイ側で行うとなると、Pythonでは書けません。別途Node.jsなどでサービスを立てておきましょう。

最後に

タッチして認証する仕組みは上記のような機材を用いることで、安価に仕上げることができます。
駅や決済シーンなどでICカードは広く使われていると思いますが、気軽に自宅で使うことも可能であることを示せたかと思います。
電源の要らないRFIDタグをどう使いたいか、そのユースケースを自由に考えるのも面白そうですね。
ここまで読んでいただきありがとうございました

オチ

作り終えた後、妻と娘に使い方を説明し、RFIDタグを渡しました。
しかし後日、妻が外出先から帰ってきた際、タッチを行っていませんでした。
そのことを尋ねると妻から会心の一撃を喰らいました。

 妻 「目立たないから忘れてた」
 私 「」

代替をもう少し考えるかな。BLE?
おしまい。

関連記事

  1. M5Stack(マイコン)+絶対圧センサーで応援してくれるエクササイズ…

  2. 観葉植物とお話しよう!(Wio NodeとGrove土壌水分センサ)

  3. 金曜日に届いたFitbit Inspire HRで週末2つアプリを作っ…

  4. ランニングコストゼロで作るスマートホームコントロール(ラズパイとNod…

  5. RPAによるゲームの自動化 ~とあるギルドマスターの挑戦

  6. SORACOM LTE-M Buttonで飲み会に行くことを妻に通知す…

  7. コンテナに入れてみる

  8. IoT x 料理(Raspberry Pi+Groveリレー+1wir…

PAGE TOP