【第2回】Googleスプレッドシートでデータ収集をしてみよう ― reCameraではじめる計器デジタル化入門

前回のおさらい

前回の第1回では、reCamera1台でNode-REDフローを開発し、温度計の画像をGemini APIで読み取り、メールで通知するところまでを実現しました。

しかし現実には、冷蔵庫が5台、冷凍庫が3台、製造ラインの温度管理ポイントが4箇所……と、1台では到底足りません。今回は複数台のreCameraを接続してデータをGoogle Spreadsheetに自動記録する構成に発展させます。

連載の全体像

テーマキーワード
第1回reCamera単体でフロー開発Node-RED、Gemini API、メール通知
第2回(本記事)複数台reCameraとゲートウェイ連携reTerminal、Google Sheets連携、スケールの課題
第3回enebularによるセキュアなクラウド連携実行環境間の接続、クレデンシャル管理

今回のゴール

  • 2台のreCameraを同一ネットワーク上で通信できるようにする。
  • reCameraは「撮影→Gemini APIで読み取り→結果をゲートウェイに送信」を行う
  • ゲートウェイは受信したデータをGoogle Spreadsheetに記録する

システム概要

まず、前回のフローからの構成変更について説明します。

前回はreCameraの中で撮影からGemini API呼び出しまですべて完結していました。今回は「reCameraの役割」と「ゲートウェイの役割」を意識的に分離します。

システム構成
※冷蔵庫の温度は既設のデジタル温度計の表示をカメラ撮影して取得

reCameraのフローは前回とほぼ同じですが、1つだけ違いがあります。debugノードの代わりに、http requestノードでゲートウェイにデータを送信します。

この設計には明確な理由があります。reCameraのフローを「撮影→読み取り→送信」だけに絞ることで、全台まったく同じフローで動かせるようになります。reCameraは自分がどの冷蔵庫を見ているかを知りません。「第1冷蔵庫」という機器名を付けるのは、ゲートウェイの仕事です。10台に増えたとき「全台同一フロー」と「台ごとに設定が違うフロー」では運用コストに大きな差が出ると考えました。


ステップ1:reCamera側のフローを修正する

前回のフローの末尾を変更します。debugノードを外し、代わりにhttp requestノードでゲートウェイに送信します。

変更前(第1回の一部)

変更後

http requestノードの設定は以下の通りです。。

  • メソッド:POST
  • URL:http://192.168.40.11:1880/api/temperature(例)
  • 戻り値:JSONオブジェクト

ここで 192.168.40.11 はUSB接続時のゲートウェイ側IPアドレスです(reCameraから見たゲートウェイのアドレス)。

reCameraが送信するJSONは前回と同じ構造です。

{
  "temperature": 26.2,
  "humidity": 53,
  "date": "2/25",
  "time": "16:39",
  "confidence": "high"
}

このフローをそのまま2台のreCameraにデプロイします。2台ともまったく同じフローです。


ステップ2:ゲートウェイ(reTerminal)のフローを作る

ゲートウェイのNode-REDでは、reCameraから受信したデータに機器名を付与し、Google Spreadsheetに書き込みます。

フロー全体像

2-1. http inノード(データ受信)

reCameraからのPOSTリクエストを受信するエンドポイントです。

  • パレットから「http in」ノードを配置します
  • メソッド:POST
  • URL:/api/temperature

2-2. functionノード「機器名の付与」

reCameraはどの冷蔵庫を見ているか知らないので、ゲートウェイ側で送信元のIPアドレス等に基づいて機器名を付与します。

// IPアドレスからデバイス名へのマッピング
// HTTPリクエストの送信元IPを元に、どの冷蔵庫からのデータかを識別する
const deviceMap = {
    "192.168.42.1": "第1冷蔵庫",
    "192.168.43.1": "第2冷蔵庫"
};

// IPv6形式で表現されたIPv4アドレス(::ffff:192.168.x.x)からプレフィックスを除去し、
// 純粋なIPv4形式に変換する
const sourceIP = msg.req.connection.remoteAddress.replace('::ffff:', '');

// マッピングにないIPの場合は "不明な機器" をフォールバックとして設定
msg.payload.device_name = deviceMap[sourceIP] || "不明な機器";

// データ受信時刻をISO 8601形式で記録(例: 2025-04-08T10:00:00.000Z)
msg.payload.timestamp = new Date().toISOString();

return msg;

2-3. functionノード「閾値判定」

機器ごとに設定された閾値と比較して、ステータスを判定します。

// デバイスごとの温度閾値設定
// normal_min: 正常範囲の下限, normal_max: 正常範囲の上限, warn_threshold: 警告と異常の境界
const thresholds = {
    "第1冷蔵庫": { normal_min: 0, normal_max: 5, warn_threshold: 8 },
    "第2冷蔵庫": { normal_min: 0, normal_max: 5, warn_threshold: 8 }
};

const device = msg.payload.device_name;
const temp = msg.payload.measurement.temperature;
const th = thresholds[device];

// デバイス名が未登録、または温度データが存在しない場合はエラー
if (!th || temp === undefined || temp === null) {
    msg.payload.status = "error";
} else if (temp >= th.normal_min && temp <= th.normal_max) {
    // 正常範囲内(0℃以上5℃以下)
    msg.payload.status = "normal";
} else if (temp >= th.warn_threshold) {
    // 警告閾値以上(8℃以上)
    msg.payload.status = "warning";
} else {
    // 正常範囲を外れているが警告閾値未満(5℃超8℃未満)
    msg.payload.status = "critical";
}

return msg;

2-4. Googleスプレッドシートノードによる書き込み

Node-REDのGoogleスプレッドシートノードを使ってスプレッドシートに書き込みます。

ノードの使い方は過去記事を参照してください。

Google スプレッドシート・ノードを使おう | enebular blog

2-5. アラートを判定してGoogleチャットに投稿する

Google チャットのスペース(グループのようなもの)にはアプリ統合の機能があり、Webhookの仕組みでフローから通知を投稿できます。閾値判定してcriticalやwarningのアラートのみをchatに飛ばすフローを追加しています。


ステップ3:動かしてみる

2台のreCameraを電源に接続し、同一ネットワーク上に置きます。それぞれのreCameraには同一のフローをデプロイし、デジタル温度計を同じようにセットします。

ゲートウェイのフローもデプロイすると、reCamera側で設定した間隔でデータが自動的にGoogle Spreadsheetに記録されていくことを確認します。

スプレッドシート上には以下のようなデータが蓄積されていきます。

timestampdevice_nametemperaturehumidityconfidencestatus
2026-02-25T14:00:05+09:00第1冷蔵庫3.265highnormal
2026-02-25T14:00:08+09:00第2冷蔵庫4.858highnormal
2026-02-25T14:15:04+09:00第1冷蔵庫3.564highnormal
2026-02-25T14:15:07+09:00第2冷蔵庫7.261highwarning

ここまでで、複数台のreCameraからの温度データをゲートウェイ経由でクラウドに記録する仕組みが完成しました。


見えてきた課題

さて、2台で動きました。次は工場内のデジタル温度計すべてに展開しよう。さらに別の工場にも広げよう ― そう考えたとき、いくつかの課題が浮上してきます。

秘密鍵の拡散

現在の構成では、Google スプレッドシートノードに設定した秘密鍵がゲートウェイ上にあり、それを使って、Google spreadseatに認証します。

ゲートウェイが1台であれば管理は容易ですが、3工場に展開すれば3台のゲートウェイにそれぞれ同じ秘密鍵をおくか、別の秘密鍵を用意して設定する必要があります。

これはセキュリティ上のリスクです。ゲートウェイが物理的に盗まれた場合、秘密鍵ごと漏洩します。もし、他のゲートウェイも同じ秘密鍵を使っていたら、全部更新し直す必要があります。別々の秘密鍵を用意するにしても台数分管理の手間がかかります。

工場のゲートウェイは事務所のサーバールームではなく、製造現場に設置されることが多いため、物理アクセスの管理が甘くなりがちです。Gemini APIのAPIキーについても同様の問題を抱えています。

フローの更新が台数に比例して手間になる

閾値を変更したい。アラートの通知先を変えたい。新しい機器を追加したい。こうした変更が発生するたびに、全ゲートウェイに1台ずつSSHでログインしてNode-REDを修正する作業が必要です。

遠隔地の工場であればなおさら負担は大きく、「変更したいけど面倒だからそのまま」という状況になりかねません。

観点1〜2台(デモ/PoC)10台以上(本番展開)
鍵管理ゲートウェイに直接配置で十分配置先が拡散し、管理とセキュリティの課題に
フロー更新手作業でも問題ない台数に比例してコストが増大
死活監視目視で把握可能一覧管理の仕組みが必要
設定管理フロー内にハードコードでも可環境変数等で外部化しないと破綻する

まとめ

今回の構成は、デモやPoCとしては十分に実用的ですが、複数台数を見据えると、考慮すべき課題はたくさんあります。

次回の第3回では、この課題を解決するアプローチについて考えていきたいと思います。「小さく始めて、安全に大きく育てる」ためのステップを進めましょう。