こんにちは、普段農業向けのアプリケーションの開発をしている上山です。
私の働くオプティム東京オフィスには、ウォーターサーバーが複数台設置されています。 このウォーターサーバーは、水道と接続されていないため、タンクの水がなくなると誰かが給水しなければなりません。 給水業務は、新卒スタッフや給水に気づいた方によって⽇々の運⽤が⾏われています。
しかし、給水のタイミングに気づかれず、タンクが空のまま放置されることが度々ありました。 その結果、お昼時など利用者が多い時間帯に水が出ないという問題が発生していました。
この問題を解決するため、小型マイコンのM5Stack AtomS3と重量センサーを使用して、水量管理と給水タイミングの通知を行うシステムを構築しました。
初代給水アラートの開発
システム構成は以下のとおりです。

M5Stack AtomS3でウォーターサーバーのタンク重量を測定し、10分毎にHTTP POSTで測定値をMicrosoft Power Automateに送信します。
Microsoft Power Automateは重量が閾値以下かを判定し、給水が必要になったら、Microsoft Teamsのチャンネルでその日の給水担当者に通知します。 取得したデータは、Excelに書き込んでいました。
残水量の表示
M5Stack AtomS3の画面には可愛らしいお顔を表示しています。

このお顔は、m5stack-avatarというライブラリを使用しています。
以下のように、簡単にお顔を表示することができます。
#include <Avatar.h> using namespace m5avatar; Avatar avatar; void setup() { // お顔の表示 avatar.init(); }
また、表情差分が用意されており、簡単に変更可能です。
この機能を使用し、残水量が減るにつれて「笑顔 → 普通 → 不機嫌」といった表情に変化するように実装しました。

給水担当者への通知
このシステムでは、正確な時刻管理は不要であり、一定間隔での通信ができれば十分であるため、M5Stack AtomS3のmillis()1メソッドを使用した簡易タイマーを実装しました。
このタイマーを用いて、定期的な重量確認を行い、給水が必要になったら、Microsoft Teamsで給水担当者に通知します。
表示モード切替
M5Stack AtomS3は、画面が押し込めるボタンになっている1ボタン式のマイコンです。
このボタンを押下すると、現在のタンクの重量を数値で確認できるようにしています。
重量測定
重量の測定には重量センサーHX711を使用しています。
HX711を使用すると以下のように重量の取得ができます。
#include <HX711.h> HX711 scale; void setup() { scale.begin(M5.Ex_I2C.getSCL(), M5.Ex_I2C.getSDA()); // キャリブレーション scale.set_scale(27.61f); // 重量を0合わせ scale.tare(); } void loop() { // get_units() で 10回測定した平均を取得 float weight = scale.get_units(10); }
setup()でキャリブレーション係数calibration_coef2を設定し、現在のセンサーの状態を0gとします。
get_units(10)により10回測定した平均値を取得することで、振動やノイズの影響を軽減し、安定した重量測定を実現しています。
設置作業の様子

ウォーターサーバーのタンクを入れている金属の箱の下に重量センサーを設置し、箱の上にM5Stack AtomS3本体を置いています。
タンクを外した状態の台車と、台の上の紙コップやインスタントドリンクの棚が乗っている状態で、scale.tare()をして0合わせをしています。
重量センサーとM5Stack AtomS3はGROVEケーブルで接続します。箱の下に重量センサーを設置しているので、給水時の抜き差し等は必要ありません。
これにより、設置作業が完了し、給水担当者に通知が送られるようになりました。
2代目給水アラートの開発
この構成でしばらく動かしていましたが、運用していく中でさまざまな問題が発生するようになりました。
- Excelのデータ量増大による読み書き速度の著しい低下
- 大量の通知によるMicrosoft Power Automateの利用可能枠の占有
- 重量の誤検知
これらの問題を解決するため、バックエンドサーバーを立てることになりました。 新しいシステム構成は次のとおりです。

重量センサーとM5Stack AtomS3による計測部分は従来通り維持しつつ、通知やデータ管理の処理をMicrosoft Power AutomateからNode.js + Honoで構築したWebサーバーへ移行しました。
バックエンドサーバーの構築
| 項目 | 技術名 | 選定理由 |
|---|---|---|
| ランタイム | Node.js | 業務経験があり開発効率を重視 |
| 言語 | TypeScript | 型安全性による開発体験向上 |
| フレームワーク | Hono | 軽量高速で開発体験が良好 |
| ORM | Prisma | 情報が豊富で導入しやすい |
| DBMS | MySQL | 業務での理解を深めるため |
| 可視化ツール | Grafana | 監視可視化のデファクトスタンダード |
ExcelからMySQLへデータストアを移行したことで、データ量に依存しない安定した読み書き性能を確保できました。
また、通知処理をバックエンドサーバーで直接制御することで、Microsoft Power Automateの利用可能枠を圧迫することなく、必要なタイミングで確実に通知を送信できるようになりました。
⾃動キャリブレーション機能の実装
しばらく運用を続けると、重量センサーの値がズレる現象が発生しました。
センサーの経年劣化、振動、使用方法など、正確な原因は特定できていませんが、 毎回手動で重量の0合わせを行うのは運用上の負担が大きいため、24時間毎に自動でキャリブレーションを実行する機能を実装しました。
おわりに
私個人の思いつきから始まったプロダクトが、周囲の方々の協力によって形になったことに、新卒ながらエンジニア集団の力強さを実感しました。
このシステムは、初めて通知を送信してから約1年半に渡り運用・改善してきました。 現在では、18万件の測定値が蓄積されています。
導入効果として、給水担当者の給水回数が増え、利用時に水が出ずに肩を落とすスタッフの姿も減少しました。
さらに、蓄積された測定値を活用してウォーターサーバー自体の故障原因の予測ができないか?という取り組みも着手する予定です。
小さなアイデアから始まったものではありますが、これからも愛着の湧いた給水アラートの保守を通じて、自身の成長に繋げられたらと考えています。 身近な課題をIoTで解決する取り組みの参考になれば幸いです。
当社では、AI・IoT・ロボティクスの力で社会の課題を解決していくエンジニアを募集しています!技術的な挑戦を楽しみながら、一緒にプロダクトを成長させていける仲間を募集していますので、ご興味のある方は、ぜひご連絡ください。