United Statesからアクセスのようです。言語設定をEnglishに切り替えますか?
Switch to English site
Skip to main content

花粉予報装置を作る!!花粉飛散状況を表示するスタックライト

USB制御のスタックライト(タワー式警告灯)とRaspberry Pi、Node-REDを組み合わせて、近所の花粉飛散量を表示する。

Pollen beacon

はじめに

この記事ではNode-REDでウェブスクレイピングを行い、ウェブからのデータを用いてUSBスタックライト(タワー式警告灯)を制御し、地域の花粉の飛散状況を表示させる方法を紹介します。

暖かくなるにつれ、イギリスでは日本と同様に花粉の飛散量が急増しています。これは花粉アレルギーを持つ人にとっては大きな問題です。そこで私たちはFAや生産設備等で用いられる信号機スタイルのスタックライトを使用して、花粉の飛散量を表示する装置を作成することにしました。

ハードウェア

私たちはまずアイデア出しから始めました。設計要件は机の上に置けるサイズで、花粉の飛散状況を知ることができ、しかもユーザー操作を必要としないものと決定しました。

他のプラットフォーム(リソースが制限されるマイクロコントローラでのウェブスクレイピング)に比べて、Node-REDの実行能力や開発プロセスを大幅に簡素化できることから、Raspberry Pi (182-6547) で今回のプロジェクトを開発することにしました。また、Raspberry Pi 3BにはオンボードWiFiが搭載されており、このシステムの動作のために電源ケーブルとスタックライトとRaspberry  Piの接続ケーブルの2本だけで完了できる点でも優位です。

次にスタックライトの選定をしました。多くの産業用スタックライトは24Vで動作しますが、Raspberry PiのGPIOピンは3.3Vなので従来の産業用スタックライトを使用するためにはGPIOインターフェースが必要になります。そこでUSB電源だけで使用可能なPatlite LR6-USB (200-8570)のスタックライトを選択することにしました。

Hardware - the stack light

選択したスタックライトは赤、黄、緑色のLED表示灯のセット、複数のパターンとトーンを出すことが可能な内蔵ブザーを搭載しており、USB経由で電源と制御が可能です。

Patlite(パトライト)はWindowsとLinuxのx86/x64システム上で動作できる、スタックライトを制御するソフトウェアのDLLを提供しています。Raspberry PiのARMプロセッサ上のLinuxではアーキテクチャの不一致のため、このソフトウェアを動作させることはできませんでした(Pythonのライブラリ“ctypes”を用いて試してみましたがダメでした)。ですが、ライトを制御する代替手段を見つけました、詳細はソフトウェアで後述します。

次にPiを収納してスタックライトを取り付けるための筐体を選択しました。今回はFiboxの小型筐体 (738-9183) を選択しました。今回のRaspberry PiではWiFiを使用するため、プラスチック製の筐体を選択することが重要でした。金属製の筐体ではファラデーケージとして機能しまい、WiFiの信号を遮断する恐れがあります。

最後の部品選定は5V、3Aのプラグトップ式電源 (182-7131) です。これはRaspberry Piとスタックライトの両方を動かすのに十分な電流を流すことができます。

スタックライトを筐体の蓋に取り付けるために、レーザーでカットしたテンプレートに穴あけの目安として使用しました。さらにM4ナット3個でスタックライトを固定しました。電源入力用のバレルジャックも取り付け穴をあけ、最後にRaspberry Piを筐体内部に設置しました。

必要な部品の選定と組み立てが完了したので、次にソフトウェアのセットアップに移ります。

ソフトウェア

このプロジェクトではNode-REDを使用することにしました。Node-REDはドラッグ&ドロップ形式で簡単にプログラミングができ、膨大な数のブロック・ライブラリがインストール時に含まれているためすぐに使い始めることができます。プロジェクトではNode-REDを使った経験があるとスムーズに進められると思いますが、初心者でも簡単にできますのでご安心ください。

Raspberry Piのセットアップ

まず、適切なマイクロSDカードに「Raspberry Pi OS Lite」イメージを書き込みました。このイメージは完全なデスクトップ環境を必要としない場合に適しており、今回のプロジェクトのような「組み込み」ユースケースに理想的です。私はディスクイメージの書き込みにWin32DiskImagerをよく使いますが、Raspberry Pi財団では “Raspberry Pi Imager” というディスクイメージのダウンロード及び書き込みを一括でできるツールも提供されています。お好みに合わせてお使いください。

ディスクイメージを書き込めたら、Piを起動してsudo apt-get update && apt-get upgrade を実行してシステムが最新であることを確認します。次にsudo raspi-configでWiFiとシステムホスト名を設定しました。Piの設定とホスト名の設定が完了したところで、Node-REDのインストールに移りました。

Node-REDのインストール

Raspberry PiへのNode-REDのインストールは、“Getting Started”ガイドに記載されているインストールスクリプトを実行するだけで簡単に行えます。このスクリプトはGitHubでも公開されており、Node.jsとNode-REDをRaspberry Pi固有のノード(GPIOと相互接続できるものも含む)で設定します。またインストーラは、システムが起動したときにNode-REDが利用できるようにサービスの設定も行えます。

インストーラはNode-REDがデフォルトの1880番ポートで動作するように設定されていますので、その設定の確認と上記セットアップの確認のために別のPCからRaspberry Piにアクセスしました。正しく設定されていることが確認できたので次のステップに移ります。

ウェブスクレイピング

ウェブサイトをスクレイピングするために必要なセットアップが全て完了したので、次にウェブスクレイピングの実行方法を検討しました。まず、花粉の状態を少なくとも1日に1回更新することに決めました。これは気象庁のデータは1日毎に更新され、その中には5日間の予報も含まれています。この要件を満たすために12時間の間隔でinject”ノードを追加することにしました。

injectノードのセットアップが完了したので、Node-REDに含まれるHTTPリクエストの作成を検討しました。HTTP requestは一般的なHTTPメソッドは勿論の事、ノードに渡されるメッセージによってメソッドを設定する機能もサポートしています。

Node-RED with timestamp and HTTP request

「URL」フィールドにMet Office花粉予報ページの正確なURLを追加し、他の値はデフォルトのままにしました。HTTPリクエストノードの設定はこれだけで完了です。とても簡単にできます!

Identifying and extracting the pollen counts from the scraped data

これでウェブページのデータを「msg.payload」で取得できるようになったので、取得データから花粉飛散状況を抽出する作業を行いました。まず、花粉飛散状況のデータを含むウェブページの要素を特定しました。これは、Chromeの“inspect eleme(検証)”オプションを使って簡単に行うことができます(上図)。※要素を確認したいサイトで右クリック>検証を押すと出せます

HTML parser node was then dropped onto the flow and string entered

次に「HTML」パーサーノードをフロー上にドロップし、先ほどの検証で確認した要素を要素セレクタに入力しました。正しいノードを指定するために試行錯誤しましたが、最終的には上図設定で問題なく動作しました。この時点でのデータ出力の設定はそのままにしてあります。

Debug node to test HTML parse code

花粉飛散状況の値が正常に取得できていることをテストするため、HTMLパースノードの出力にデバッグノードを接続しました。次にフローを展開してinjectノードをクリックし、手動トリガーでinjectノードを動かしてウェブ情報を注入しました。上図が実行結果で、ウェブページから正常にデータを取得・抽出することができました。

スタックライトの制御

花粉予報のウェブサイトから花粉飛散状況値を抽出することに成功したので、次はスタックライトを制御するためのインターフェースの作成に取り掛かりました。

前述したように、スタックライトが提供しているDLLはARMアーキテクチャでは動作しないため、Patliteのカスタマーサポートにメールを送りました。すると、サードパーティが作成したスタックライトを制御するためのプログラムが含まれたGitHubのリポジトリのリンクが送られてきました。そこで、このリポジトリに含まれるサンプルファイルを用いて、スタックライトの動作テストをしてみました。

このプログラムの最初に注目すべき点は、デフォルトでpythonスクリプトの実行にroot権限を要求していることです。これはセキュリティの観点からあまりよくありません。しかし、これは簡単に修正できます、次の行を「udev」ルールに追記するだけです:

SUBSYSTEM=="usb", ATTR{idVendor}=="191a", ATTR{idProduct}=="8003", GROUP="pi", MODE="0666"

これにより、“pi”グループに属するユーザーであれば指定のVIDとPIDを持つUSBデバイス(この場合はスタックライト)に対しては書き込み・読み込みが可能になります。

udevルールを再起動せずに読み込むためには、ターミナルでudevadm control --reloadを実行します(再起動でも大丈夫です)。その後スタックライトのケーブルを抜いて再び接続します。この状態でサンプルスクリプトを(sudoを使用せずに)再度テストしました。

サンプルプログラムを元にして適切な光の色を設定するシンプルなPythonスクリプトを作成しました。プログラムではコマンドライン引数として“red”、“yellow”、“green”のいずれかを受け取り、その色に合わせてスタックライトを光らすことができます。このスクリプトはchmod +x stacklight_colour.pyで実行可能としてマークされました。

Python script - with four outputs representing the pollen level

Node-REDのフローとPythonスクリプトを接続するために、“L”、“M”、“H”、“VH”の値に対応する4つの出力を持つスイッチノードを追加しました。次にこれらの出力はそれぞれ、適切な色を引数としてスクリプトを呼び出す「exec」ノードに結び付けられました。

Node-REDの全フローが完成したところでシステム全体のテストを行いました。injectノードのボタンをクリックすると、スタックライトの赤いランプが点灯したので、花粉の数が多い、もしくは非常に多いことを示しています。後程、動作結果を確認したところこの時の赤色は「多い」でした。

最後のセットアップはもう一度sudo raspi-configを実行し、overlay filesystem(オーバーレイファイルシステム)を有効にすることです。これによりファイルシステムが読み取り専用になりますが、その上に読み取り/書き込み可能なオーバーレイを作成するのでアプリケーションが安全に通常通り機能します。オーバーレイファイルシステムに書き込まれた変更はストレージメディア(この場合はRaspberry Pi SDカード)にコミットされません。

ストレージメディアを変更する必要がある場合は「raspi-config」内でオーバーレイファイルシステムを無効化することができます。

まとめ

今回はNode-REDのセットアップ方法と、その中でウェブスクレイピングを行うための各種ノードの設定方法、特定の要素をフィルタリングする方法、そしてNode-REDのフローから実世界のデバイスを制御する方法について見てきました。

是非皆様もNode-REDとUSBデバイスを連携させて、自宅のデスクで本格的な予報デバイスを動かしてみてください!

Engineer of mechanical and electronic things by day, and a designer of rather amusing, rather terrible electric "vehicles" by night.