TOPIC命名規則
1.通常の一斉送信
センサー情報やカメラ情報の一斉送信の場合は以下のトピックで送信します
swpf/{user\id}/{device\id}/{unit\_id}/{channel}
| 項目 | 説明 | 備考 |
|---|---|---|
| user\_id | サーバーから連携時に取得した顧客のID | |
| device\_id | プレフィックス+ハッシュ化したMACアドレス 例:esp32\_xxxxxxxx | プレフィックスは、esp32c3、espcamとかarduinoなど |
| UNIT\_ID | マイコンに接続されるセンサーなどユニットのタイプ+何台目かを表す番号 {device\type}\{index} 例:temperature\1camera\1fan\_1 | 詳細は別紙参照 |
| CANNEL | メッセージの内容を表すコード boot env image/\# status control(Controlは次項の要求と応答で使用) など | ※ {channel}は以前は/sensor/envでしたがここをenvにしました |
swpf/1/esp32\C80CABF16E20/camera\1/image/meta
2.要求送信と応答返信(将来案)
サーバー側から要求に対してESP32が応答を返すような場合は以下のトピックでやり取りします。
※この場合はCannelも限定されます。
制御の場合はControl、ステータス情報要求の場合はstatusになります
Drupal → ESP32 の要求送信:
swpf/{user\id}/{device\id}/{unit\_id}/{channel}/request
ESP32 → Drupal の応答返信:
swpf/{user\id}/{device\id}/{unit\_id}/{channel}/response
例)水やりポンプへの制御要求なら次のようになります
swpf/{user\id}/{device\id}/waterpump\_01/control/request
ESP32からPublishするTOPIC一覧
📊 ESP32送信TOPIC一覧
| カテゴリ | TOPIC | 内容 | タイミング | 重要度 |
|---|---|---|---|---|
| boot | /boot | 起動情報 | 起動時 | ★★★★★ |
| env | /env | センサー情報 | 定期 | ★★★★★ |
| image meta | /image/meta | 画像メタ | 撮影時 | ★★★★★ |
| image begin | /image/begin | 分割開始 | 撮影時 | ★★★★ |
| image chunk | /image/chunk | 画像データ | 撮影時 | ★★★★★ |
| image end | /image/end | 分割終了 | 撮影時 | ★★★★ |
| error | /error | エラー通知 | 異常時 | ★★★★★ |
📊TOPICごとのPayload項目一覧
①BOOT Payload一覧(swpf.boot.v1)
Topic /SWPF/user\id/device\id/system\_1/boot
| キー | 型 | 例 | 必須 | 説明 |
|---|---|---|---|---|
| schema | string | swpf.boot.v1 | ◎ | スキーマバージョン(仕様識別) |
| type | string | boot | ◎ | イベント種別(起動) |
| user\_id | string | 123 | ◎ | ユーザー識別子 |
| device\_id | string | esp32\_C80CABF16E20 | ◎ | デバイスID(ESP32) |
| unit\_id | string | thermometer\_1 | ◎ | ユニットタイプ+番号 |
| ts | number | 1776298443 | △ | UNIX時刻(秒)※未同期時は0 |
| uptime\_ms | number | 11357 | ◎ | 起動からの経過時間(ミリ秒) |
| wifi\_connected | bool | true | ◎ | WiFi接続状態 |
| time\_ready | bool | true | ◎ | NTP同期状態 |
| ip | string | 192.168.0.6 | △ | デバイスのIPアドレス |
| rssi | number | \-51 | △ | WiFi電波強度(dBm) |
| heap\_free | number | 209032 | ◎ | 現在の空きヒープメモリ |
| heap\_min | number | 200292 | ◎ | 起動後の最小ヒープ(最重要) |
| psram\_free | number | 8333584 | △ | 空きPSRAM容量 |
| reset\_reason | string | POWERON | ◎ | リセット原因 |
| fw\_version | string | 1.0.0 | ◎ | ファームウェアバージョン |
| app | string | Project TOMATO | ◎ | アプリ識別名 |
リセット原因詳細
| 値 | 説明 | 検証テスト |
|---|---|---|
| POWERON | 電源投入 | |
| EXTERNAL | 外部リセット | |
| SOFTWARE | ソフトリセット | |
| PANIC | クラッシュ | |
| INT\_WDT | 割り込みWDT | |
| TASK\_WDT | タスクWDT | |
| WDT | その他WDT | |
| DEEPSLEEP | DeepSleep復帰 | |
| BROWNOUT | 電圧低下 | |
| SDIO | SDIO関連 |
② ENV Payload一覧(swpf.env.v1)
Topic /SWPF/user\id/device\id/UNIT\ID/env UNIT\IDの命名規則は別紙参照
■ 共通ヘッダ(Bootと共通)
| キー | 型 | 例 | 必須 | 説明 |
|---|---|---|---|---|
| schema | string | swpf.env.v1 | ◎ | スキーマバージョン |
| type | string | env | ◎ | データ種別(環境データ) |
| user\_id | string | SincereWill-999 | ◎ | ユーザー識別 |
| device\_id | string | esp32\_C80CABF16E20 | ◎ | デバイスID |
| ts | number | 1776296167 | △ | UNIX時刻(未同期時は0) |
| uptime\_ms | number | 13874 | ◎ | 起動後経過時間(ms) |
| wifi\_connected | bool | true | ◎ | WiFi接続状態 |
| time\_ready | bool | true | ◎ | NTP同期状態 |
| ip | string | 192.168.0.6 | △ | IPアドレス |
| rssi | number | \-54 | △ | WiFi電波強度(dBm) |
| heap\_free | number | 208856 | ◎ | 現在の空きヒープ |
| heap\_min | number | 200340 | ◎ | 起動後最小ヒープ(最重要) |
| psram\_free | number | 8330000 | △ | 空きPSRAM |
| fw\_version | string | 1.0.0 | ◎ | ファームウェアバージョン |
| app | string | Project TOMATO | ◎ | アプリ識別 |
■ センサー情報(ENV固有)
| キー | 型 | 例 | 必須 | 説明 |
|---|---|---|---|---|
| temperature | number / null | 26.50 | △ | 温度(℃) |
| humidity | number / null | 47.05 | △ | 湿度(%) |
| lux | number / null | 237.50 | △ | 照度(lux) |
| pressure\_hpa | number / null | 1013.25 | △ | 気圧(hPa) |
| co2 | number / null | 800 | △ | CO2濃度(ppm) |
| soil\_moisture | number / null | 45.20 | △ | 土壌水分(%) |
値のルール
🔹 nullの扱い
| 条件 | 出力 |
|---|---|
| センサー未接続 | null |
| 読取失敗 | null |
| 無効値 | null |
例:
"co2": null
🔹 数値フォーマット
| 項目 | 推奨 |
|---|---|
| temperature | 小数2桁 |
| humidity | 小数2桁 |
| lux | 小数1〜2桁 |
| soil\_moisture | 小数2桁 |
🔹 CO2ルール
| 値 | 意味 |
|---|---|
| \>0 | 正常値 |
| 0 or 負数 | nullとして扱う |
🔹 RSSI目安
| 値 | 状態 |
|---|---|
| \-30〜-50 | 非常に良い |
| \-50〜-70 | 通常 |
| \-70以下 | 弱い |
③ META Payload一覧
Topic /SWPF/user\id/device\id/UNIT\_ID/meta
| 項目 | 型 | 内容 | 用途 |
|---|---|---|---|
| type | string | "meta" 固定 | メッセージ種別(meta/begin/chunk/end) |
| device\_id | string | デバイス識別子 | 送信元の特定 |
| event\_id | string | イベントID(ユニーク) | 1枚の画像の識別キー |
| ts\_ms | number | 起動後ミリ秒 | イベント発生タイミング |
| jpeg\_len | number | JPEGサイズ(バイト) | 完全受信判定 |
| sha256 | string | SHA256ハッシュ | データ完全性チェック |
| chunked | boolean | 分割送信フラグ | CHUNK再構築判定 |
④ BEGIN Payload一覧
| 項目 | 型 | 内容 | 用途 |
|---|---|---|---|
| type | string | "begin" 固定 | CHUNK送信の開始 |
| device\_id | string | デバイスID | 送信元識別 |
| event\_id | string | イベントID | 画像単位の識別キー |
| ts\_ms | number | 起動後ミリ秒 | タイミング情報 |
| jpeg\_len | number | JPEG総サイズ(bytes) | 完了判定 |
| chunk\_size | number | 1チャンクのサイズ | 分割単位 |
| total\_chunks | number | チャンク総数 | 再構築用 |
| sha256 | string | ハッシュ値 | 完全性検証 |
📊 ③ Error Payload(将来)
トピック
swpf/device/{device\_id}/error
Payload一覧
| キー | 型 | 説明 |
|---|---|---|
| type | string | error |
| device\_id | string | デバイスID |
| ts | number | 時刻 |
| error\_code | string | エラーコード |
| error\_message | string | 詳細 |
| context | string | 発生箇所 |
📸 ④ Image Meta(重要)
スケッチの publishChunkFromSd() の最初に送信されるデータです。
トピック
swpf/camera/{device\id}/UNIT\ID/meta
Payload
| キー | 型 | 例 | 説明 |
|---|---|---|---|
| type | string | meta | 種別 |
| device\_id | string | esp32\_xxx | デバイス |
| event\_id | string | xxx\_171... | イベントID |
| ts\_ms | number | 12345 | millis |
| jpeg\_len | number | 18566 | 画像サイズ |
| sha256 | string | xxxx | ハッシュ |
| chunked | bool | true | 分割送信か |
📸 ⑤ Image Begin
トピック
swpf/camera/{device\id}/UNIT\ID/begin
Payload
| キー | 型 | 例 | 説明 |
|---|---|---|---|
| type | string | begin | 種別 |
| device\_id | string | esp32\_xxx | デバイス |
| event\_id | string | xxx | イベントID |
| ts\_ms | number | 12345 | 時刻 |
| jpeg\_len | number | 18566 | サイズ |
| chunk\_size | number | 2048 | チャンクサイズ |
| total\_chunks | number | 10 | 総数 |
| sha256 | string | xxxx | 整合性確認 |
📸 ⑥ Image Chunk(バイナリ)
トピック
swpf/camera/{device\id}/UNIT\ID/chunk/{event\_id}/{index}
Payload
👉 バイナリ(JPEGの一部)
| 項目 | 内容 |
|---|---|
| payload | JPEGデータ(分割) |
| index | topicから取得 |
| event\_id | topicから取得 |
---
📸 ⑦ Image End
トピック
swpf/camera/{device\id}/UNIT\ID/end
Payload
| キー | 型 | 説明 |
|---|---|---|
| type | string | end |
| device\_id | string | デバイス |
| event\_id | string | イベントID |
| total\_chunks | number | chunk数 |
🔗 event\_id の役割(重要)
event\id \= device\id \+ timestamp \+ millis
👉 これで
- meta
- begin
- chunk
- end
を1つの画像としてまとめる
🧠 Payload設計の思想(SWPF)
① 必ず type を持つ
→ Drupal側で判別
② event\_id で束ねる
→ 非同期でも再構築可能
③ chunkはtopicで識別
→ JSON不要・高速
④ meta → begin → chunk → end の順
→ ストリーミング設計
🔥 Drupal側での使い分け
| type | 保存先 |
|---|---|
| boot | device\status \+ event\log |
| heartbeat | device\_status |
| error | event\_log |
| meta | capture\_log |
| begin | capture\_session |
| chunk | temp storage |
| end | file保存 |
🚀 この構成の強み
- スケーラブル
- 非同期耐性あり
- 再送対応しやすい
- YOLOなどAIと相性◎
- Drupalでの集約が簡単
🎯 あなた向け最適まとめ
あなたの構成だと👇
- Boot → 状態監視
- Image → AI解析
- MQTT → 非同期連携
- Drupal → 集約・可視化
このPayload設計はかなり理想形です。
👉 次にやるべきこと
ここまで来たら次はこれ👇
- Drupal受信API(完成版コード)
- 画像復元処理(chunk→JPEG)
- 管理画面(一覧 \+ 詳細)
必要なら 👉「そのまま動くDrupalモジュール(ZIP)」出せます。
🧠 各TOPICの中身(軽量版)
🔹 boot(起動時)
{
"type": "boot",
"fw": "0.0.1",
"ip": "192.168.0.6"
}
👉 device\_idはトピックに含まれるので省略OK
🔹 env
{
"t": 25.6,
"h": 60.2
}
🔹 image/meta
{
"e": "event\_id",
"s": 18234,
"w": 640,
"h": 480
}
🔹 image/chunk
👉 バイナリ or base64
🔹 error
{
"c": 1001
}
🚀 設計ポイント(重要)
① device\_idをトピックに含める
👉 JSON軽量化できる
② sys配下で管理
/sys/mem
/sys/wifi
👉 拡張しやすい
③ imageは分離
👉 chunk対応しやすい
④ 短縮キー推奨
👉 JSONサイズ削減
🔥 一言
👉 「シンプルなTOPIC \= 強いシステム」