データベース
 Computer >> コンピューター >  >> プログラミング >> データベース

Raspberry PiとElasticsearchで作る樽スケール警報システムの構築方法

Raspberry PiとElasticsearchで作る樽スケール警報システムの構築方法

以前のブログ記事では、オフィスにあるコールドブリューコーヒーの樽の重量を利用して、残量が少なくなったときにSlackへアラートを送信する仕組みについて詳しくご紹介しました。

本記事は2部構成シリーズの後編として、そのスケール(重量計)をどのように構築したのかを解説します。できるだけ時間と費用をかけずに済ませたいというのが主な狙いで、既製品の中には私たちのニーズに合うものが見つかりませんでした。

樽スケールの要件定義

まずはプロジェクトの要件を整理することから始めました。

  • 安価であること(100ドル未満)
  • メンテナンスの手間が最小限であること
  • リモートで管理できること
  • 樽の残量を簡単に確認・報告できること
  • コールドブリューが樽から取り出されたタイミングを検知できること(ストレッチゴール)
  • そして何より、作業時間を最小限に抑えられること*

*筆者には本業があり、樽スケールの製作は仕事の範囲外です。

初期調査

最初の課題は、樽からどのようなデータを収集するか、そもそも何を測定すべきかを見極めることでした。

樽を監視するためのオープンソースプロジェクトもいくつか存在します。少し調べてみると、計測方法は大きく分けて以下の2つがあることがわかりました。

  • 重量による測定
  • 流量計を使用する方法

既存のソリューションの多くは流量計を採用しています。しかし流量計では、樽が「空」になったかどうかの判定がやや難しく、樽の交換時期を判断するには何らかのユーザーの介入が必要になります。さらに、実際のコーヒーの配管ラインにデバイスを設置する必要があり、それ自体にも潜在的な問題があります。

そこで、参考になる事例が少ないというハンディを抱えつつも、スケール(重量計)を使って重量から樽の残量を判定する方式を採用することに決めました。

樽スケールの選定

スケール本体のハードウェアについては、Raspberry Piのような小型コンピューターに接続できる市販品を探しました。Wi-FiやBluetooth対応のスケールは数多く存在しますが、連続読み取りに対応していないもの、電池式のもの、インターフェースの接続が面倒なものばかりでした。樽専用のスケールもいくつかありますが、いずれも高価すぎました。

というわけで、再びDIYの出番です。

私はRaspberry Piを使った開発経験があったため、Piでスケールを組むためのハードウェアを探すことにしました。Amazonで、まさにこの用途向けの50kg対応ロードセルとHX711アンプのセットを見つけました。

HX711を使ったArduinoスケールの製作事例は豊富にありますが、Raspberry Pi向けの情報はかなり少なめです。幸い、Instructablesのチュートリアルと、ユーザーtatobari氏のGitHubリポジトリ(Python製のHX711ユーティリティを含む)が見つかり、これらがぴったり役立ちました。

システム全体のアーキテクチャ

まず、システム全体の構成を把握するために簡単な概要図を作成しました。

Raspberry PiとElasticsearchで作る樽スケール警報システムの構築方法

ハードウェアの組み立て

最初の課題は、樽の下に敷けてキガレーター(樽用冷蔵庫)内に収まり、かつ約68kg(150ポンド)の樽の重みで曲がらない強度を持つ、薄型のスケールを見つけることでした。

複数の設計案や補強方法を試しましたが、不安定になったり、厚みが増してしまい上部のチューブに圧力がかかったりと、うまくいきませんでした。

最終的な構成は、古いグリル網にホームセンターで購入した小さな鋼材(Cチャンネル)を補強材として組み合わせ、ダクトテープと結束バンドで固定するというものでした。
Raspberry PiとElasticsearchで作る樽スケール警報システムの構築方法Raspberry PiとElasticsearchで作る樽スケール警報システムの構築方法

完璧とは言えませんが、結果的にすべての設計要件を満たすことができました(もっと頑丈なソリューションをお持ちの方がいれば、ぜひアイデアを教えてください)。

配線作業

HX711ボードは4本のGPIOピン経由でRaspberry Piに接続し、スケール側はホイートストーンブリッジからの4本のワイヤでHX711ボードに接続します(詳細はInstructablesを参照)。

キガレーターの中は非常にスペースが狭く、樽の出し入れの際にはかなりの衝撃もあるため、HX711とRaspberry Piを樽と同じ場所に置くのは得策ではありません。そこで、両者はキガレーターの外側すぐ隣に設置し、スケール本体からHX711までは標準的なケーブル(お馴染みのCat 5またはCat 6)で長距離接続することにしました。スケール側とHX711側のそれぞれにRJ45コネクターを取り付ければ、手持ちのどんなイーサネットケーブルでも接続できます。

HX711とRaspberry Piの間は、隣接して設置しているため、通常のジャンパーワイヤーを使用しました。

ソフトウェア

Raspberry Piを採用したことで、Linux上で動作するものであれば基本的に何でも使えます。

最初のパーツは、GPIO経由でHX711アンプとやり取りするコードです。

HX711関連のプロジェクトの多くはArduino向けですが、GitHubにはRaspberry Pi向けのHX711コードのリポジトリもそれなりに公開されています。例えばPythonで書かれたリポジトリなどが見つかります。

HX711のサンプルコードをもとに、定期的な重量の読み取り値をファイルに出力し、そのファイルをElasticsearchへ送れるようにする小さなPythonユーティリティを作成しました。設定ファイルから動作するよう拡張し、いくつかのテストモードも追加しましたが、それ以外はごくシンプルなコードです。

Elasticsearchへのデータ送信

次に、このデータをElasticsearchへ送る仕組みが必要でした。

Filebeatを使って重量ファイルを読み込み、Elasticsearchへデータを送信する方式を採用しました。Pythonスクリプトから直接Elasticsearchに書き込むことも可能ですし、Logstashでファイルを読む、あるいはスクリプトを直接呼び出してリアルタイムに読み取ることもできます。ただしFilebeatは非常に軽量で、必要な作業量が最も少なかったため採用しました。

Filebeat使用時の唯一の小さな課題は、Elastic社がRaspberry Pi/ARM向けのバイナリをデフォルトでは提供していないことです。そのため自分でビルドする必要がありました。

幸い、Elastic公式サイトの手順はとても明快です。使用したいFilebeatのバージョンに合ったGoのバージョンを選択すれば、ビルドはかなりスムーズに進むはずです(開発者ガイドに記載されていますが、ページ右側で正しいBeatのバージョンを選択するのを忘れないでください)。

すべてのコンポーネントが正常に動作するようになったら、最後にスケール読み取りスクリプトとFilebeatをsystemdサービスとして設定し、起動時に自動スタートするようにします。

データのインデックス化

次は、この重量データをElasticsearchにインデックス登録する段階です。Filebeatを使う場合、私はElasticsearch側でインジェストパイプラインによりデータをパースすることにしました。Logstashも選択肢の一つですが、Raspberry Piにかかる負荷を最小限に抑えたかったのです。Piをローカルダッシュボードとして使い、将来的に温度センサーなど他のセンサーへ拡張できるようにしておきたかったからです。

重量リーダーは数秒ごとに「2018-06-22T20:57:02+0000 – 134.0」のようなログ行を出力します。タイムスタンプの後に「-」と重量値が続くだけの極めてシンプルな形式なので、インジェストパイプラインも同様にシンプルになります。


{
  "description" : "Parse the readings from the keg scale",
  "processors" : [
	{
  	"grok": {
    	"field": "message",
    	"patterns": ["^%{TIMESTAMP_ISO8601:readtime}\\s+-\\s+%{BASE10NUM:weight}$"]
  	}
	},
	{
  	"convert": {
    	"field" : "weight",
    	"type": "float"
  	}
	},
	{
  	"date" : {
    	"field" : "readtime",
                                             	"formats" : ["ISO8601"]
                                	}
	}
  ],
  "on_failure" : [
	{
  	"set" : {
    	"field" : "ingest_error",
    	"value" : "{{ on_failure_processor_type }} - Error processing message - {{ _ingest.on_failure_message }} : {{ message }}"
  	}
	}
  ]
}

その結果、数秒ごとに浮動小数点型の「weight」とタイムスタンプを含むドキュメントが生成され、Filebeatが付与する各種メタデータも一緒に保存されます(将来複数の樽へ拡張する際に活用できます)。

Elasticsearchクラスタ

ObjectRocketのおかげで、この部分は非常に簡単でした。基本構成のクラスタを立ち上げ、ACLをいくつか開放し、ユーザーを設定すれば、あとはデータを送り始めるだけです。その他に必要なのは、Kibana付きの稼働中のElasticsearchクラスタだけです。

まとめ

すべてのセットアップが完了したら、あとは電源をつなぐだけです。

これだけで、あっさり動いてしまいました。

初期の実行結果をご覧ください。

Raspberry PiとElasticsearchで作る樽スケール警報システムの構築方法

最終的には、以下をひと目で確認できるシンプルなゲージが完成しました。

  • 樽に残っているコールドブリューの割合
  • Timelionによるトレンドライン
  • 直近の樽交換日

CanvasやVegaといった新しいプロジェクトを活用すれば、さらなる機能追加の余地も十分にありますが、現時点でも目的は十分に果たせています。

  1. MongoDBインスタンスをスケーリングすべきタイミングの見極め方

    以前のブログ記事では、MongoDBによる大規模スケーリングの基礎をご紹介しました。スケーリングはどうしても受動的になりがちで、対応が遅れるとアプリケーションのパフォーマンス低下、最悪の場合にはシステム全体のダウンタイムといった問題につながります。その結果、顧客体験の悪化を招き、ビジネスへの悪影響も避けられません。では、ビジネスに損失を出さないために、MongoDBデータベースをスケールすべき適切なタイミングはどうやって見極めればよいのでしょうか。アプリケーションに適した閾値を見つける利用者の増加やトラフィックの急増という「嵐」を乗り切るためには、本番環境にスケーリングなどの変更を加える前に、

  2. Windowsエラーコード43とは?主な原因と解決方法を徹底解説

    Windowsエラーコード43は、PCがハードウェアを正常に動作させるために必要な設定や情報を正しく処理できない場合に発生するトラブルです。このエラーは、主にデバイスドライバーが古くなっている、あるいは正しくインストールされていないことが原因で表示されます。本記事では、Windowsエラーコード43の発生原因と、具体的な解決手順について詳しく解説していきます。 Windowsエラーコード43の原因は? このエラーが発生すると、画面には次のようなメッセージが表示されます。 「Windows は、このデバイスに問題が発生したため停止しました(コード 43)」 エラーコード43は、システムに接続さ