はじめに ― 画像は送らない、URLを送る。この発想がすべてを変えた。
今回の議論の中心は、次の一点でした。
「画像、どう送る?」
MQTT に画像を流すのか?
HTTPで直接流すのか?
Gyazoから受け取ったURLを使うのか?
実はこのテーマ、すでに別記事で 「画像送信の仕組み」 を詳しくまとめています。
👉 https://qiita.com/GGT1629/items/f744dae9276a84fd80d0
今回の記事ではその続編として、「じゃあ実際にどんなデータを送るか?」というデータ構造編 を中心に書いています。
問題点 ― ペイロードが上書きされる地獄
Python から Node-RED に送られてくるデータは本来こう。
- label(アリ/ゴキブリ)
- confidence(確信度)
- image_path
- timestamp
しかし Gyazo API を通して画像URLを取得した瞬間…
「あれ?Pythonのデータ消えた?」
という事件が何度も発生。
原因は、Node-RED のペイロード上書き仕様でした。
-
msg.payload = 〜→ 全部上書き -
msg.payload.xxx = 〜→ プロパティ追加
これを理解していなかったため、Python のデータが Gyazo の値で消えてしまう事態が発生したわけです。
解決策 ― Gyazo_image_path を“追加プロパティ”にする
今回は、大切な Python 由来のデータを守るために、
msg.payload.Gyazo_image_path
という新しいプロパティを追加する方式に切り替えました。
- Pythonの image_path(ローカルパス)は上書きしない
- Gyazo の公開URLは Gyazo_image_path として保存
- MQTTへ送る時は両方含める
これで データ衝突ゼロの安全設計 が完成しました。
データ通信方式 ― MQTTはURLだけ、画像はHTTPで取得
ここが今回の設計の最重要ポイントです。
🧭 送信するのは「画像そのもの」ではなく「画像URL」
MQTT に大量のバイナリデータを流すと、
- 帯域を圧迫
- ブローカー負荷増大
- 転送に時間がかかる
などデメリットだらけ。
そのため、議論の結果こうなりました。
✔ Gyazo に画像を保存
✔ Gyazo が公開URLを返す
✔ MQTT ではそのURLだけ送信
✔ 受信側が HTTP GET で画像を取得
このアーキテクチャは、
IoT通信で非常によく使われる「軽量化の王道」です。
デバッグ ― “set properties of undefined” の正体
今回で最も混乱を呼んだエラーがこれ。
set properties of undefined
原因は、なんと…
- 複数のインジェクトノードが同時に発火
- どのデータが流れているかわからない
- その結果、payload が空の状態でプロパティを追加していた
という “人間側が混乱していた” というオチ。
対策として、
- テスト用フローは無効化
- ダミーデータで単体テスト
- スイッチノードでデータ入口を一元化
- payload を
pythonと明示的に名前付け
こうした整理によって、ようやく正常動作しました。
最終的なペイロード ― 完全に統合された美しい構造
最終版のJSONはこれです。
{
"label": "ant",
"confidence": 0.92,
"image_path": "/local/temp.jpeg",
"timestamp": "2025-11-27T10:33:21",
"Gyazo_image_path": "https://i.gyazo.com/xxxx.jpg"
}
この形式なら
- Node-RED側の音声判定
- ログ保存
- HTTPリクエストによる画像取得
- 表示や分析処理
すべてに対応できる 万能フォーマット に。
結論 ― 画像送信は「別記事」。今回は“データ構造”が主役。
繰り返しになりますが、
画像送信の仕組みそのものは以下の記事で詳しく解説済みです。
📌 画像送信の仕組みはこちら
https://qiita.com/GGT1629/items/f744dae9276a84fd80d0
本記事では、その仕組みをどうデータ構造に落とし込むか
――ここが最大の論点でした。
今日のまとめ
- 画像はMQTTで送らず、URLだけ送る
- Pythonのデータを守るため、上書きではなく追加方式に
- Gyazo_image_path という独立プロパティを採用
- フロー整理でデバッグが劇的に楽に
Node-RED のデータ設計は、ちょっとした理解で全体が劇的に良くなります。