# リファクタリング方針: MQTT ネイティブ移行 ## 進捗状況 | Phase | 状態 | 内容 | |-------|------|------| | Phase 1 | ✅ 完了 | TCP→MQTT ブリッジ + InfluxDB + NiceGUI | | Phase 1.5 | ✅ 完了 | フロントエンド刷新 (FastAPI + Vite/React/TypeScript) | | Phase 2 | 未着手 | 衛星ファームウェア MQTT ネイティブ化 | ## 現在のアーキテクチャ (Phase 1.5: FastAPI + React) ```mermaid flowchart LR subgraph Satellite["衛星 (Pico W)"] sat_tcp[TCP Server
:80 CMD / :81 TLM] end subgraph Ground["地上局"] bridge[bridge.py
TCP→MQTT] server[server.py
FastAPI] ui[React UI
Vite dev server] end subgraph Infra["インフラ"] mqtt_broker[(Mosquitto)] influxdb[(InfluxDB)] end sat_tcp -- TCP:81 TLM/IMG --> bridge bridge -- publish --> mqtt_broker mqtt_broker -- subscribe --> server server -- write --> influxdb server -- WebSocket --> ui server -- query --> influxdb ui -- REST API --> server server -- publish CMD --> mqtt_broker mqtt_broker -- subscribe CMD --> bridge bridge -- TCP:80 --> sat_tcp ``` ## 目標アーキテクチャ (Phase 2: MQTT ネイティブ) ```mermaid flowchart LR subgraph Satellite["衛星 (Pico W)"] sat_mqtt[MQTT Client
lwIP MQTT] end subgraph Ground["地上局 (Python)"] server[server.py
FastAPI] end subgraph Infra["インフラ"] mqtt_broker[(Mosquitto)] influxdb[(InfluxDB)] end sat_mqtt -- publish TLM/IMG --> mqtt_broker mqtt_broker -- subscribe CMD --> sat_mqtt mqtt_broker -- subscribe --> server server -- write --> influxdb server -- query --> influxdb server -- publish CMD --> mqtt_broker ``` **Phase 2 で削除されるもの: `bridge.py` のみ。** `server.py` は変更不要。 --- ## Phase 2 実装手順 ### Step 1: 衛星ファームウェアの MQTT 対応 1. **lwIP MQTT を有効化** — `lwipopts.h` に以下を追加: ```c #define LWIP_TCP 1 #define MQTT_REQ_MAX_IN_FLIGHT 5 ``` `CMakeLists.txt` に `pico_lwip_mqtt` をリンク: ```cmake target_link_libraries(satelite pico_lwip_mqtt) ``` 2. **`hal/mqtt.h` / `hal/mqtt.cpp` を新規作成** — 以下の API: ```c int mqtt_init(const char *broker_ip, uint16_t port); int mqtt_publish(const char *topic, const uint8_t *data, uint16_t len); int mqtt_subscribe(const char *topic, mqtt_callback_t cb); ``` 3. **テレメトリ送信を置き換え** — `main.cpp`: - `wifi_write(telemetry)` → `mqtt_publish("sat/telemetry", json_payload)` - テレメトリフォーマットを JSON に変更(bridge.py のパース互換) - 画像: `mqtt_publish("sat/image", ...)` ※ QoS 0, 分割送信は MQTT レイヤーが処理 4. **コマンド受信を置き換え**: - `wifi_read()` ループ → `mqtt_subscribe("sat/command", cmd_callback)` ### Step 2: 通信テスト - Mosquitto のログで衛星からの publish を確認 - `server.py` が変更なしで動作することを確認 ### Step 3: bridge.py を削除 - `bridge.py` を削除 - `config.py` から `SAT_HOST`, `SAT_CMD_PORT`, `SAT_TLM_PORT` を削除 --- ## MQTT トピック設計 (Phase 1 / 2 共通) | トピック | 方向 | ペイロード | QoS | |---------|------|-----------|-----| | `sat/telemetry` | 衛星→地上 | JSON | 0 | | `sat/image` | 衛星→地上 | バイナリ (メタ長+JSON+画像) | 0 | | `sat/command` | 地上→衛星 | テキスト `COMMAND,VALUE` | 1 | --- ## 注意事項 - **Pico W の MQTT ペイロード上限**: lwIP の MQTT 実装はデフォルトでペイロードサイズに制限がある。320×240 = 76,800 バイトの画像は分割 publish が必要になる可能性あり。 - **ブローカーの QoS**: テレメトリは QoS 0 (欠損許容)、コマンドは QoS 1 (到達保証) を推奨。 - **WiFi 再接続**: MQTT のクリーンセッション / Will メッセージで接続断を検知可能。 - **JSON フォーマット統一**: Phase 2 では衛星が直接 JSON を生成するため、`cJSON` ライブラリ (Pico SDK 同梱) の使用を推奨。