🎄

クリスマスイルミネーションをつくった話

2021/12/23に公開

この記事はあくあたん工房 Advent Calendar 2021の参加記事です.

さて皆さん今月は12月下旬,もうすぐクリスマスがやってきます.楽しみにしている人も忙しくなりそうな人も観測されていますが,クリスマスといえば「イルミネーション」ですね!
というわけで,私たちあくあたん工房は,京都工芸繊維大学の企画部irodoriとコラボ企画として大学にイルミネーションを設置してきました.

もちろん技術者として,ただLEDを光らせるだけでは物足りないので,今回Twitterの反応と連携して光り方を変化させることにしました.このギミックの結果,Twitter上では学生から様々な反応を頂けました!とてもありがたいですし頑張った甲斐があるというものです.

この記事では,その裏側でどういう技術が使われていたか書いていこうと思います.

構成

KITクリスマス イルミネーションの技術的な話 マイコン編より引用しています.
サービス構成

サーバサイドやフロントエンドは,猶予期間も短いため慣れているTypeScriptを使いました.マイコンとの通信は,MQTTを使ってみたい&マネージドサービスを使ってみたい,ということでGCPのCloud IoT Coreを使ってみました.類似サービスとしてAWS IoT Coreなんかもあるので,そのあたりも使ってみたいところです.
ちなみにそれらを稼働するサーバは,さくらのクラウドを利用しました.ISUCON本戦のときのオマケのやつが手元にあったので…

ハードウェアまわり

そもそも光り方を柔軟に変化させる上で,LEDが単色にしか光らないものだとパターンが限られてしまい面白くありません.なので,今回はNeoPixel系のマイコンからLEDの色を個別変化させられるLEDを利用しました.AliExpressで防水の5m50球が1000円くらいで売っています.このLEDは,内部にRGB LEDのほかにマイコンが内蔵されていて,デイジーチェーンで接続してやればどこまでも伸ばせるという割と便利なやつです.
そのLEDに光り方を指示するために,ESP32を利用しました.ESP32のおかげで,WiFi経由でインターネットに接続して光り方をリアルタイムに変えることができます.光り方は14種類を事前に書き込んでおき,その番号をCloud IoT CoreのMQTTで送信していました.この部分のプログラムはあくあたん工房のゆゆくんが作成してくれました.

詳しくはゆゆくんのKITクリスマス イルミネーションの技術的な話 マイコン編をご覧ください

Twitterまわり

いろいろなアイデア出しや相談の結果,Twitterのツイートへのいいね・RTなどの反応と,特定のハッシュタグへのツイートを集計してパターンに反映することにしました.APIでスクレイピングというのが一般的ではありますが,今回はリアルタイム性が重視されるので,定期的なスクレイピングは適していません.そこで,反応の集計にはAccount Activity APIを,ハッシュタグの集計にはFiltered streamのAPIを利用しました.

データ取得

TwitterAPIまわりは,twitter-api-v2を利用しています.

Account Activity APIについては,twitter-api-v2に実装が無かったため,twictを参考に独自の実装を行いました.Webhook受信にはHTTPS接続が必要なので,本番はnginxによりリバースプロキシしました.開発中はcloudflaredを用いることで,証明書を考えずに実験をすることができました.

Account Activity APIでは,いいね・RTなどの反応を数秒の遅延でリアルタイムに集計できます.いいねについてはfavorite_eventsというイベントで飛んできますが,それ以外のRTやリプライはすべてtweet_create_eventsというイベントで飛んできます.RTの場合,RTで生成されたツイートオブジェクトが,リプライの場合リプライのツイートオブジェクトが付いくるので,それを基に判断しないといけません.RTについては,retweeted_statusを,リプライについてはin_reply_to_status_idを見ることで判断していました.正直これでいいのかはだいぶ不安ですが,動いているのでヨシとしています.

Filtered streamは,HTTPの接続を維持することでリアルタイムに検索結果を得ることができます.これを利用してハッシュタグ検索を行います.trackというquerystringにカンマ区切りでキーワードを渡せば検索できます(最初スペース区切りと間違えてうまく動きませんでした).これについてはtwitter-api-v2で対応されているため,問題なく利用できます.

集計

イルミネーションの点灯パターンの数や,ツイートがどの程度するかが分からなかったため,パターン決定のルールはハードコーディングではなく柔軟に設定できることが求められました.

そのため,データベースに

  • 集計をいつ行うか(いいねなどの反応時か,何もない定期更新のときに行うのか)
  • 何番目に集計を行うか(優先度)
  • 集計対象のツイートとハッシュタグ
  • いいね・RTなどのうちどれを集計するか
  • 集計結果の範囲についての条件(下限・上限)

を記録し,それに対して点灯するパターンと,再集計までの時間を指定することで柔軟な変更に対応しています.再集計までの時間は,例えばいいねされたときだけ点灯パターンが一定時間変わるような状況に対応するためのものです.

IoTまわり

Google Cloud PlatformのCloud IoT Coreを利用しました.IoT Coreは組み込み機器からMQTTで接続して情報をやり取りするのですが,任意のtopicに対してメッセージを自在に投げられるというようなサービスではありません.IoT Coreでは/devices/{id}/config/devices/{id}/commandsというtopicのみを扱います.configについては,構成という形でHTTPでデータを書き込み,それがIoT Core側で保持されMQTT送信されます.このtopicは特殊で,接続・購読時に必ず最新の構成が送信されるようになっています.commandsは,HTTPでデータを書き込むと,IoT Core側で保持されることなく1度だけMQTTで送信されます.

この特性を生かして,configには点灯パターンを,commandsには再起動などを割り当てて使っていました.また,データの送信はHTTP APIを経由して行いました.

フロントエンド

ルールの設定やその他の設定をするためのフロントエンドをSvelteで作成しました.なんとここで初めてSvelteを触りました.普段使うReactよりは簡単にUIや状態管理を行えたので,開発期間を短縮することができました.フロントエンドでは,点灯用の集計ルールなどを変更・編集できます.
フロントエンド
ルール追加

最後に

企画の決定からソフトウェア作成完了まで約2週間,設置したあともbug fixをやってなんとか企画を無事に成功させることができました.まるでハッカソンのように大量のコードを書いていて,疲れることもあったのですが,おかげで多数の反応を学内で貰え,大変嬉しい限りです.

謝辞

大学からの許可取りや企画作成など行っていただいたirodori様,マイコンのコード作成を担当していただいたゆゆくん,その他あくあたん工房のメンバーの皆様,今回はありがとうございました.

Discussion