# リファクタリング方針: 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 同梱) の使用を推奨。