プロデルでFeliCaカードを使った入退室記録ツールを作る

FeliCaは、Suica,ICOCAなどの交通系ICカード、WAONやedyなどの電子マネーで使われている非接触型のデータ通信技術です。

NFC対応のUSBリーダーや、PCに内蔵されたFeliCaポートを使ってPCからFeliCa対応のICカードの情報を取得できます。

プロデルでは、FeliCaプラグインを使うことで、FeliCaポートに置いたFeliCaカードの情報を取得できます。

FeliCaプラグイン

プロデルのFeliCaプラグインは、次のアドレスからダウンロードできます。FeliCaプラグインは、「プロデルデザイナ(32ビット環境)」、実行可能ファイルは「常に32ビットで起動する(WoW64)」で利用できます。
https://produ.irelang.jp/downloads/plugins.html#felica

64ビット環境では、PC/SCプラグインを利用して下さい。
PC/SCプラグインを公開しました

使えるFeliCaカード

FeliCaカードは、SuicaやICOCAなどの交通系ICカードや、EdyやWAON, nanacoなどの電子マネーです。おサイフケータイもFeliCaカードとして扱えます。出欠席管理ツールでは、カードの固有番号(IDm)を読み取るのみですので、使用中のICカードや使い古したICカードで遊べます。なお、運転免許証やマイナンバーカードは、FeliCaではありませんので今回のプログラムでは使えません。

事前準備

FeliCaリーダを利用するために「NFCポートソフトウェア」をインストールして下さい。

IDmを取得する

SuicaやWAONなどFeliCaカードには、カードを識別するIDm(製造ID)とカードの状態を表すPMm(製造パラメータ)が保存されています。IDmは、FeliCaカード一枚一枚に割り当たられた固有の番号で、番号が重複しないように割り当てられています。このIDmを使うことで、カードを区別することができます。プロデルでは、IDmを取得できます。

※以下のサンプルは32ビット環境のFeliCaプラグイン専用です。64ビット環境のPC/SCプラグインを利用する場合は、こちらを参考にしてプログラムを書き換えてください。

「Produire.Felica.dll」を利用する
フェリカポートで受け付けしてカードとする
カードからIDmをテキストで取得して結果とする
結果を報告する

カードからPMmをテキストで取得して結果とする
結果を報告する

FeliCaポートにFeliCaカードを置いた状態で実行すると、IDmとPMmが取得できます。「フェリカポート」種類の「受け付ける」手順を実行すると、FeliCaポートにカードがある場合に「フェリカカード」種類のオブジェクトを返します。一方カードがポートに置かれていない時は「フェリカポートで受け付け」た結果が「無」になります。

カードが置かれたことを判定する

「フェリカポート」種類の「受け付ける」手順を使うことで、カードの有無が判定できます。これを利用して一定時間ごとにFeliCaポートのカードの有無を調べて、もしカードが置かれた場合にはIDmを表示して、カードが無くなった時には「カードが取られました」と表示するプログラムを作ります。

ポイントは、置かれたカードのIDmを「カードIDm」変数に記憶しておいて、同じカードが置かれ続けている場合には、IDmを表示しないようにしてIDmが何度も表示されないように工夫している点です。

※以下のサンプルは32ビット環境のFeliCaプラグイン専用です。64ビット環境のPC/SCプラグインを利用する場合は、こちらを参考にしてプログラムを書き換えてください。

「Produire.Felica.dll」を利用する
カードIDmは、「」
繰り返す
  フェリカポートで受け付けしてカードとする
  もしカードが無でなければ
    カードからIDmをテキストで取得して読み取り結果とする
    もしカードIDmが読み取り結果でなければ
      カードIDmは、読み取り結果
      読み取り結果を報告する
    もし終わり
  そうでなければ
    もしカードIDmが「」でなければ
      「カードが取られました」を報告する
    もし終わり
    カードIDmは、「」
  もし終わり
繰り返し終わり

カードごとに名前を表示する

今度は、カードごとに名前を付けておき、そのカードが置かれたときに画面に対応する名前を表示させてみます。IDmはカード固有の番号ですので、この番号と名前など情報とを紐付けることで、カードを置いたときに名前を表示させるようにします。

まず予めFeliCaカードのIDmを調べておきます。「名簿」変数に、IDmをキーに、名前を値にして、カードと名前の対応表を「辞書」として作っておきます。カードが置かれたときには、名簿から該当するIDmの名前を表示させます。

※以下のサンプルは32ビット環境のFeliCaプラグイン専用です。64ビット環境のPC/SCプラグインを利用する場合は、こちらを参考にしてプログラムを書き換えてください。

「Produire.Felica.dll」を利用する
名簿は、{
 「01xxxxxxxxxxxx18」=「山田花子」,
 「01xxxxxxxxxxxx1E」=「平沢真一」,
 「01xxxxxxxxxxxx19」=「秋山洋子」
}
カードIDmは、「」
繰り返す
 フェリカポートで受け付けしてカードとする
 もしカードが無でなければ
  カードからIDmをテキストで取得して読み取り結果とする
  もし読み取り結果が無なら
 他でもしカードIDmが読み取り結果でなければ
   カードIDmは、読み取り結果
   名前は、名簿(カードIDm)
   「こんにちは。[名前]さん」を報告する
  もし終わり
 そうでなければ
  カードIDmは、「」
 もし終わり
繰り返し終わり

なお、FeliCaカードの種類によっては、カードに情報そのものを書き込むことも可能です。ただ自由に情報を書き込める領域があるカードは限られ、また書き込める場合でも多くの情報を記憶することが出来ないため、今回のようにIDmをキーにパソコン側に情報を格納しておく方法が簡単です。

入退室を記録する

さらに応用して、入室時間と退室時間をカードごとに記録するようにしてみます。最初にFeliCaポートにカードを置いた時には入室時刻が記録され、一度カードを離した上で、再度置くと、退出時刻を記録します。これらの情報をCSVファイルに記録することで日々の入退室を管理します。またついでに、名前とIDmの名簿もCSVファイルから読み込むように修正してみます。

入室と退室を区別するには

今回のツールでは、最初にカードを触れたときには、「入室」として、再度カードに触れた時は「退室」として記録するようにしたいと思います。

「入室リスト」という辞書を用意しておき、最初にカードを触れた時に「入室リスト」へキーをIDmにした値を記録しておきます。その後は触れた際にIDmをキーとする値が「入室リスト」に存在するかどうかをチェックして、キーが存在しなければ「入室」、キーが存在すれば「退室」として扱うようにします。ここで退室となった場合には「入室リスト」から触れたカードのIDmを削除します。

このように辞書を使ってIDmをキーにして管理することで、入退室を区別できます。

名簿をCSVファイルから読み込む

次には、すでに辞書で指定してある名前とIDmの名簿をCSVファイルから読み込むように改良します。データ表へCSVファイルの内容を読み込むには、「読み込む」手順を使います。このとき、CSVファイルが存在しない場合はエラーメッセージが表示されるようにしておきます。

データ表は、「一覧」設定項目を使うことで内容を配列として主付くできます。「それぞれ繰り返す」文で、1レコードずつ名簿にIDmと名前の関係を登録していきます。

名簿データというデータ表を作る
名簿データcsvは、「名簿.csv」
もし名簿データcsvというファイルが存在しないなら、「名簿が見つかりません。」を表示する。終了する。
名簿データへ名簿データcsvから読み込む

名簿は、空の辞書
名簿データの一覧のすべてのレコードについてそれぞれ繰り返す
 名簿(レコード(1))=レコード(2)
繰り返し終わり

名簿.csvの内容は次のような内容でメモ帳などを使って保存しておきます。

"01xxxxxxxxxxxx18","山田花子"
"01xxxxxxxxxxxx1E","平沢真一"
"01xxxxxxxxxxxx19","秋山洋子"

CSVファイルへ記録する

CSVファイルの読み書きには、「データ表」種類を使います。データ表を使うことで、CSV形式のファイルを簡単に取り扱えます。

ここでは、付け加える部分だけを取り上げます。「入退室記録」には入退室の時間と名前、入室か退室かを順番に記録していきます。データ表に記録を追加するには、「加える」手順を使います。

また、記録をCSVファイルへ書き込むには、「保存」手順を使います。次回起動した際の記録を引き継ぐために、「入退室記録.csv」が存在する場合には、そのファイルの内容を上書きしてしまわないように記録を読み込んでおきます。

入退室記録というデータ表を作る
入退室記録csvは、「入退室記録.csv」
もし入退室記録csvというファイルが存在するなら、入退室記録へ入退室記録csvから読み込む
//・・・
もし入室リストに読み取り結果が存在するなら
//・・・
 入退室記録に{「[日付] [時刻]」、「[名前]」、「退室」}を加える
そうでなければ
//・・・
 入退室記録に{「[日付] [時刻]」、「[名前]」、「入室」}を加える
もし終わり
入退室記録を入退室記録csvへ保存する

画面の作成

プロデルデザイナの「情報ウィンドウ」で表示されるだけでは格好悪いので、ウィンドウを表示するようにします。ウィンドウの設計画面でメイン画面を作ります。

メイン画面とは
  ウィンドウを継承する
  はじめの手順
    初期化する
    ーー貼り付けた部品に対する操作をここに書きます
  終わり
  初期化する手順
  ーー自動生成された手順です。ここにプログラムを書き加えても消える場合があります
  この内部領域大きさを{459,101}に変える
  この種類を「ダイアログ」に変える
  この最大化ボタンを×に変える
  この最小化ボタンを×に変える
  この初期位置を「中央」に変える
  この内容を「入退室管理」に変える
  ラベル1というラベルを作る
    その位置と大きさを{12,28,279,34}に変える
    その内容を「カードを置いてください」に変える
    そのフォントを「Yu Gothic,18,太字」に変える
    そのドラッグドロップを×に変える
  終わり
終わり

完成したプログラム

上記のようなCSVファイルの読み書きのプログラムを追加することで、入退室記録をファイルへ保存できるようになります。

2021/1/3更新 実行可能ファイルの場合、読み取り確認の間隔が早くてGUIが描画されない現象が起こるため「休憩する」手順を追記しました。

※以下のサンプルは32ビット環境のFeliCaプラグイン専用です。64ビット環境のPC/SCプラグインを利用する場合は、こちらを参考にしてプログラムを書き換えてください。

「Produire.Felica.dll」を利用する
名簿データというデータ表を作る
名簿データcsvは、「名簿.csv」
もし名簿データcsvというファイルが存在するなら、名簿データへ名簿データcsvから読み込む

名簿は、空の辞書
名簿データの一覧のすべてのレコードについてそれぞれ繰り返す
  名簿(レコード(1))=レコード(2)
繰り返し終わり

入退室記録というデータ表を作る
入退室記録csvは、「入退室記録.csv」
もし入退室記録csvというファイルが存在するなら、入退室記録へ入退室記録csvから読み込む

メイン画面を表示する

入室リストは、空の辞書
カードIDmは、「」
繰り返す
  フェリカポートで受け付けしてカードとする
  もしカードが無でなければ
    カードからIDmをテキストで取得して読み取り結果とする
    もし読み取り結果が無なら
    他でもしカードIDmが読み取り結果でなければ
      カードIDmは、読み取り結果
      名前は、名簿(カードIDm)
      もし入室リストに読み取り結果が存在するなら
        入室リストから読み取り結果を消す
        メイン画面のラベル1の内容は、「[時刻]さようなら。[名前]さん」
        入退室記録に{「[日付] [時刻]」、「[名前]」、「退室」}を加える
      そうでなければ
        入室リストへ読み取り結果として○を設定
        メイン画面のラベル1の内容は、「[時刻]こんにちは。[名前]さん」
        入退室記録に{「[日付] [時刻]」、「[名前]」、「入室」}を加える
      もし終わり
      入退室記録を入退室記録csvへ保存する
    もし終わり
  そうでなければ
    カードIDmは、「」
  もし終わり
  休憩する
繰り返し終わり

メイン画面とは
  ウィンドウを継承する
  はじめの手順
    初期化する
    ーー貼り付けた部品に対する操作をここに書きます
  終わり
  初期化する手順
  ーー自動生成された手順です。ここにプログラムを書き加えても消える場合があります
  この内部領域大きさを{459,101}に変える
  この種類を「ダイアログ」に変える
  この最大化ボタンを×に変える
  この最小化ボタンを×に変える
  この初期位置を「中央」に変える
  この内容を「入退室管理」に変える
  ラベル1というラベルを作る
    その位置と大きさを{12,28,279,34}に変える
    その内容を「カードを置いてください」に変える
    そのフォントを「Yu Gothic,18,太字」に変える
    そのドラッグドロップを×に変える
  終わり
終わり

入退室記録.csvには、次のように時刻と名前、入室か退室かが記録されていきます。

実行可能ファイルにする時の注意

FeliCaプラグインは、32ビット向けに用意されています。64ビット版のWindowsでもプロデルデザイナ上では動作しますが、実行可能ファイルとして作成するときには、常に32ビットで起動する(WoW64を有効にする)必要があります。

有効にするには、プロデルデザイナの「オプション」→「プログラム」の「常に32ビット(WoW64)で起動する」にチェックしてください。

まとめ

プロデルのFeliCaプラグインを使うことで、ICカードによる入退室管理ツールを作ってみました。FeliCaポートでできることはとてもシンプルですが、複数のカードを組み合わせて、何かの状態を表すことができるので、ゲームや作業管理など工夫次第で、日々の生活に便利で楽しいツールを作ることができるかと思います。

  • いいね (11)
  • 続編を読みたい (59)

“プロデルでFeliCaカードを使った入退室記録ツールを作る” への6件の返信

  1. お世話になります。
    便利そうなスクリプトで、リーダーを手に入れて試してみましたが、dllがロックされて開けないというメッセージが出ます。
    Windows 10 Pro 64bitです。
    もしかしてdllの置き場所によるのかもと思ったのですが、どこに配置すればよろしいのでしょうか?(いちおう同じフォルダに移動してみたのですが、、)
    お手すきのときに教えていただけるとありがたいです。
    よろしくお願いいたします。

  2. ご質問頂き、ありがとうございます。ご返答遅くなりました。
    プラグインのDLLファイルは、作成したプロデルプログラムがあるフォルダに一式をコピーしてください。
    プログラム中で『「Produire.Felica.dll」を利用する』と宣言すれば利用可能です。

    プロデルデザイナ等が起動している状態ではDLLファイルがロックされることがあります。この場合、一度プロデルデザイナを終了すると操作できます。

    なおプロデルをインストールしたフォルダ直下の「plugins」フォルダへコピーすれば、「利用する」文で明示しなくても利用できます。
    プラグインの最新版でインストールプログラムを添付しましたのでご活用ください。
    https://rdr.utopiat.net/files/plugins.html

  3. お世話になっております。
    手元にPasoriとFelicaカードがあり、すぐに試せる環境であったため試させていただきました。
    プロデルデザイナ上では正常に動作したのですが、exeを作成して実行すると下記エラーが出て停止してしまいます。

    エラーメッセージここから

    『フェリカポートで受け付け』という部分でプログラムの実行中にエラーが出ました。
    文法に間違えがないか、指定した値が正しいか、確認してください。

    文法や使い方が正しいにも関わらず、このエラーが表示される場合は、不具合の可能性があります。

    発生した例外:
    フェリカポートで受け付け(StaticCallExpression)

    [エラー番号901][はじめ:20行目]

    ←エラーメッセージここまで

    20行目の
    フェリカポートで受け付けしてカードとする
    という部分に文法の間違いが生じているのかもしれませんが、デザイナ上で問題なく使用できているのがよく分からず、質問させていただきました。

    だいぶ昔の記事に対する質問で恐縮ですが、よろしければご返答お願い致します。

    1. 上記内容につきまして、dllを実行ファイルのある場所に置いたところ、エラーメッセージは発生しなくなりました。
      ですが、別のエラーが発生してしまいました。

      プログラムを実行後、しばらくすると応答なしになってしまいます。
      カードを読み込むことはするのですが、時刻とあいさつの表示が出てきません。

      入室管理のCSVには名簿通りの名前と時刻が記入されているので動作はしているのですが、画面の切り替わりがないので読込み完了したかどうかのチェックができない状態です。

      自分でもいろいろと探ってみますが、宜しければ改善方法をお教えいただけませんでしょうか?

      どうかよろしくお願い致します。

  4. ご質問や不具合と思われる現象については、ここのコメントでは無く、公式掲示板へお願いします。
    FeliCaプラグインは、32ビットモードでのみ動作します。実行可能ファイルに限って動作しない場合は、「オプション」にて「常に32ビット(WoW64)で起動する」にチェックしてください。

コメントを残す