全社集会の受付システムを自作した話

はじめに
さくらインターネットの米田です。
当社の社内イベントで「AllHands」という、全社員が集まる会議があります。年1回ぐらいのペースで開催していて、今年は3月28日(土)に大阪で開催しました。
当社の社員数は、自分が新卒で2022年に入社した時は500人ぐらいだったのですが、今ではグループ会社も含めると1000人近くいて、そのうち600人ぐらいがAllHandsに現地参加します。その会議の来場者受付システムを自作しましたので、それについて紹介します。
受付システムを自作した経緯としては、まず昨年秋に「さくらスプラウト」という社内イベントを開催したときに、QRコードを読むと氏名や部署名が書かれたテプラの名札が印刷される簡易受付システムを制作しました。このイベントは100人ぐらいの規模だったのですが、作ったシステムが好評だったのでAllHandsでも同様の受付システムを用意したいということで制作を依頼されました。既製の受付システムをレンタルすると結構な費用がかかることや、さくらインターネットはできるだけ内製する文化があることも関係しています。
受付システムの挙動
この受付システム、そもそもどういう動きをするかを説明します。
まず社員には、個別にQRコードと受付番号が書かれた名札が送付されます(当社の社員はリモートワーク前提で働いているので基本的には自宅に届きます)。社員はそれを持ってAllHandsの会場に行き、受付でこのQRコードをリーダにかざします。すると受付システムがそれを読み取り、その社員が出席したことをサーバに記録するとともに、パトライトを点灯します。サーバに記録されたデータを集積することで、最終的にどの社員が来ていたとか、参加者数の集計などができるというものです。
システム構成
このシステムの全体像を図にしたものを上に示します。結構大がかりなものになっています。
まず、QRコードリーダが5台×2群の合計10台あります。受付に同時に10人ぐらいやって来ても並列処理できるようにということで用意しました。AllHandsには600人ぐらいの参加が見込まれていましたが、その人数を受け付けるのを開場からイベント開始までの1時間程度でさばく必要があったので、QRコードリーダは多めに用意しました。
図の左端にはパトライトが10台+予備2台の合計12台並んでいます。パトライトは工場やネットワーク監視などで使われている機材で、例えばアラートが上がると赤や黄色や緑に光って音が鳴ったりします。今回のシステムでは、受付でQRコードが正常に読み取られたら緑色に光るように設定しました。
図の右側には、さくらのクラウドとさくらのセキュアモバイルコネクトを使って構築した集計システムがあります。こちらについては後ほど説明します。
用意した機材
このシステムを作るにあたって用意した機材は以下の通りです。
- Raspberry Pi:2台
- QRコードリーダ:10台
- パトライト:10台
- L2スイッチ(24ポート):1台
- LANケーブル:15本
- 電源タップ:6台程度
- 電鍵ケーブル:1本程度
- ACアダプター:14本程度
- USBハブ:2台
ACアダプターが14本程度とかなり多いですが、これは今回使用したパトライトがACアダプターを必要とするタイプの物だったため10台必要だったことに加え、USBハブもQRコードリーダが5台接続されると電源供給不足になりがちなのでACアダプターをつないで電源供給したことによります。L2スイッチもポート数の多いものを使っていますが、これもパトライトやRaspberry Pi、それから作業用PCなどを接続すると14ポートぐらいは使うので、24ポートのスイッチが必要でした。
QRコード読み取り部
今回のシステムを大別すると、QRコードを読み取るハードウェア的な部分と、読み取ったデータを集計して表示するソフトウェア的な部分に分かれます。まずはQRコード読み取り部について解説します。
システム構成
QRコードの読み取り部分には、図にも描かれていますがRaspberry Piを使っています。1台のRaspberry Piに対してQRコードリーダが5台接続され、それが2組あります。どうしてこのような構成になっているかというと、Raspberry Piが1台壊れても残りの1台(QRコードリーダとしては5台)で受付業務が継続できるようにという冗長化のためです。
それから、この2台のRaspberry PiはQRコードリーダで読んだデータを取り込むサーバになっているのですが、読み取ったデータを2台のサーバ間で同期する仕組みも実装しています。これとは別にセキュアモバイルコネクト経由でさくらのクラウドにもデータを保存しているのですが、セキュアモバイルコネクトによる通信が切れることも考慮して、会場内でもデータの同期を行っています。まとめると、読み取ったデータはローカル(Raspberry Pi)に保存、もう1台のRaspberry Piにも保存、セキュアモバイルコネクト経由でクラウドにも保存という三重の冗長化を行っています。
試作
このQRコードの読み取りシステムを試作したのは1月後半か2月ぐらいだったように記憶しています。最初は自宅にQRコードリーダを持ち込んでテストしました。そのときの動画を上に載せます。QRコードをかざすとパトライトが緑色で光るのが見えるかと思います。このテストではQRコードをA4のコピー用紙に印刷していますが、薄い紙だとちょっと認識しづらかったです。(本番はもっと厚手の紙を使いました)
自宅でのテストでとりあえず動くことを確認できたところで、今度はさくらインターネットの大阪本社に機材を持って行って、本番の1週間前ぐらいから、本番と同じ機材構成でテストを重ねました。
余談ですが夜にテストしたときの写真です。夜になったらこんな感じで結構きれいに光ります。大阪本社は通称「うめきた」と呼ばれるエリアにあって夜景がきれいなのですが、夜景に混ざって赤く光るのはなんとも言えない美しさがありました。
大阪本社からAllHandsの会場までは歩いて5〜10分程度の距離なので、前日の夜に機材を会場まで運んで設営し、イベントに供用しました。
データ集計画面
続いてはQRコードを読み取ったログをどのように集計するかという話に移ります。こちらについては、上図のようなWeb UIをPythonとDjangoで作成して用意しました。
Raspberry Piの中では下記のようなCSV形式でデータを保存しています。ログを保存するプログラムもPythonで実装しました。
読み取った時刻,受付番号,サーバ番号
データの例を以下に示します。client2というのは2台目のRaspberry Piのことです。
20250329110822,547,client2
さくらのクラウドにデータを保存する時は、クラウドから定期的にRaspberry PiにアクセスしてCSVデータを取得し、さくらのクラウドのエンハンスドデータベースにデータを保存します。
Web UIはそのデータベースからデータを読み出し、整形して表示します。データベースに保存しているので、読み出すときにいろいろな条件でフィルタをかけることもできます。例えば自分の名前でフィルタをかけると、2025/3/29の8:25に出席したというデータが表示されます。option1の項目には部署名が入るので、部署名で検索して、部署ごとに誰が出席しているかを把握することもできます。これは当日に受付を担当した社員の方々にも有効に使っていただけたようです。
ツラかったこと
このシステムを作る中で苦労したことをいくつか紹介します。
一番大変だったのは、QRコードリーダのサーバとして使っていたRaspberry Piのうち1台が本番の前日に故障したことです。受付システムの設営は前日の19時ぐらいから始めたのですが、Raspberry Piの電源を落としてもう一度起動したら1台が動かなくなっていて、確かそれが20時ぐらいでした。このRaspberry PiではPythonやDjangoなども動いていたのでどうしようかと思いましたが、会社から支給されているMacでも同様に動くことは事前に確認していたので、そちらに置き換えて対応しました。
それから、QRコードリーダもパトライトも10台あるので、それらの機材を並べて配線するだけでも結構な作業量になります。特に自宅でこの量の機材を並べて検証するのはかなり大変でした。パトライト5台に対してACアダプターが5台、USBハブとRaspberry Piも電源がいるので、QRコードリーダ5台の1セットに対して電源の口を7個も使います。これを2セット並べる必要がありました。
システムの構築や事前検証も、ソフトウェア開発だけであれば場所を問わずに作業できるのですが、今回は物理機材を使用しているため、どうしても機材のある場所に行かないと検証できないのも大変でした。自宅勤務のときはいいですが出張などで出かけている間は作業ができないので、そこは苦労した点です。
また、会場にQRコードとパトライトを設置するにあたっては、どのように設置すれば見栄えがよいかを考えるのも結構苦労しました。
ChatGPTを使って来場者数をグラフ化してみた
このような苦労を経て構築した受付システムも本番では無事に稼働し、本来の役目を果たすことができました。本番終了後、このシステムで取得した来場者の受付通過時刻などのログをChatGPTに渡して、来場者数に関するいろいろなグラフを作ってもらいました。
まず累計来場者数のグラフがこちらです。8:30ぐらいに自分がテストで1回通したので0からほんの少しだけ上昇し、受付開始は11時ですが運営メンバーはそれより前に受付をしてもらうので10時過ぎから少しずつグラフが上がっていってます。そして11:00より少し前から11:50ぐらいにかけて実際の来場者が受付を通過したので一気に増えています。QRコードを忘れたなどの理由でこのシステム以外の方法で受け付けた人もいるので、実際には600人以上が来場しましたがQRコードをかざした人は600人弱という数字になっています。事前の予想ではイベント開始直前に一気に受付に来るかと思ってたのですが、実際にはそうでもなかったのがこのグラフでわかります。
1分ごとの来場者数グラフも作ってもらいました。11:08が一番多くて19人受け付けたようです。受付開始が11:00で、それから11:10ぐらいまでに1つの山があり、その後で11:30〜11:40ぐらいにかけてもう1つの山があるような、そういった傾向が見えます。
10分ごとの来場者数グラフも出してみました。こうして見ると11:30〜11:40の間が一番多いのがわかりますね。ちなみにこの10分間で135人が来ました。
30分ごとのグラフも作ってみたんですが、30分間で見ると11時台の前半の方が少し多いようです。
このようにログをもとにグラフ化してみると結構面白いなと思いました。
ところで、先ほどWeb UIの説明で、データベースから取得するデータはフィルタをかけて絞り込むことができるという話をしましたが、それを使って自分が所属するネットワークユニットで絞ってみたグラフが上の図です。8:20の1名は自分で、他のメンバーは11時台に一気に来ていることがわかります。
こういった感じで、ログを取って分析することによって、これぐらいの時間帯にだいたいこれぐらいの人数が来たんだなというのがわかったので、今後また全社集会のような大きなイベントが行われるときの参考になるのではないかと思います。
おわりに
今回はさくらインターネットのAllHandsで使用した受付システムを自作した話をお届けしました。期末ということもあり、他業務の兼ね合いでかなり忙しくかなり突貫工事で作りました。 そのようなことと、規模が大きくなったこともあり、当日は本当に動くのか心配していましたが、思いのほか大きな問題もなくしっかりと動いてくれてホッとしました。 また、「このシステムをどうやって作ったん?」と聞いてくれていろんな人に興味を持っていただけた点でも作った甲斐があったなと思いました。これを一回だけのものにせず、社内イベントなどで使い回しが出来るように作れると非常に面白いと思いますので、そういったことも視野に入れてブラッシュアップ出来たら良いのかなと考えています。