RON-V 連載リンク
← 前の記事:#15 — 統合後編:自動配送と再起動後の復帰
→ 次の記事:#17 — Google Sheetsへの非同期同期
L0〜L4の定義追記(2026-10-25)
本文中のコード・試験結果は執筆当時の記録として残しています。画像AI・音声を関連付ける現在の定義は次のとおりです。
| レベル | 残す内容 |
|---|---|
| L0 | Meshtastic向けの23バイト短報。画像AIの候補通知は任意設定 |
| L1 | 個別の観測・撮影/録音/認識の状態と、詳細への参照 |
| L2 | 一定時間の観測件数・分類別候補などの集計 |
| L3 | 画像AIの詳細、録音情報、文字起こし全文 |
| L4 | 元画像JPEG、元音声WAV、LTEのraw logなど |
L0の警報欄は1バイト=8ビットです。新しいversion=2の定義は、倒木 0x01、冠水 0x02、煙 0x04、道路上の障害物 0x08、路面の穴 0x10。残り3ビットは未割り当てです。0x03は倒木と冠水の組み合わせで、煙の番号ではありません。0x00はL0上では未判定で、安全を示しません。 候補ありでは元イベントの時刻・位置を使い、現在地と混同しません。
発信元はnode_uid、根拠は画像・音声などです。「処理成功」「災害の候補」「人の確認済み」を分けます。初期の確認状態はunreviewed。画像AIの検出0件を「危険なし」とせず、音声の否定も全文へ残します。人が補足・訂正する画面と、音声からの災害自動分類は今後の実装です。
10月25日にL1の関連付け・L2の集計・音声L3/L4の転送処理をコードへ追加しました。新連携の実機確認はこれからです。音声転送とL0候補通知は初期設定では無効で、個別に有効化します。従来のL0 version=1へ、この分類の意味を遡って付けません。
Looker Studioで使用中のSheets summaryはRF測定から直接出力する既存の10列で、L2とは別です。今回の追加で列名・順序・値の意味、既存Grafanaの参照項目は変えません。L1のMesh送信、写真・音声のMesh転送、自動公開は実装していません。
詳細と設定手順:データレベルの定義(リポジトリの閲覧権限が必要です)。
[!NOTE]
2026-09-23 現行GitHub同期メモ本記事の実装基準は GitHub
mainです。現在はgspread/google-authをrequirements.txtで固定し、app/integration/google_sheet_check.pyで7シートの構造を検証します。#16執筆時には将来扱いだった L3/L4 は、その後 #18 までに実装済みです。
はじめに
#15までで、RON-VはRaspberry Pi 5上に観測・保存・統合・Mesh配送の基盤を持つようになりました。
次の段階では、ローカルの観測データを外部から扱いやすくするため、
RON-V
↓
SQLite
↓
Google Sheets
↓
Looker Studio
という可視化経路を用意します。
ただし、RON-Vの一次保存先はGoogleではありません。
測定
↓
SQLite / ローカルファイル
↓
測定完了
↓
外部同期は後段で非同期実行
というローカルファースト設計を維持します。
1. Google Sheetsを使う目的
Google Sheetsへ出す目的は主に次の3つです。
- Looker Studioから参照しやすくする
- PCやスマートフォンから確認しやすくする
- RON-V本体と外部可視化を疎結合にする
一方、Google API障害や通信断によってRF/LTE/Vehicleの測定を止めてはいけません。
そのためGoogle連携は、測定処理とは別のworkerとして扱います。
2. 現在のSpreadsheet構造
RON-Vでは1つのSpreadsheetに次の7 Worksheetを用意します。
summary
L0
L1
L2
L3_INDEX
L4_INDEX
SYNC
用途は次のとおりです。
| Sheet | 用途 |
|---|---|
summary |
Looker Studio向けのフラットなRF観測データ |
L0 |
Node Beacon |
L1 |
Vehicle / LTE / RFなどのSensor Fact |
L2 |
一定時間窓のCycle Summary |
L3_INDEX |
Structured Evidenceの索引 |
L4_INDEX |
Raw Evidenceの索引 |
SYNC |
Mesh / Google Driveなどの配送状態 |
summary と L2 は似ていますが、役割は別です。
summary
Looker Studioで扱いやすい平坦な表
L2
RON-V内部の時間窓統合オブジェクト
3. 現在のRON-V内部データ
SQLiteには、代表的に次のテーブルがあります。
rf_measurements
lte_measurements
vehicle_measurements
vehicle_events
mesh_messages
l0_beacons
sync_objects
sync_deliveries
sync_cursors
現行実装では、
L0 : node_beacon
L1 :
vehicle
LTE
RF
L2 :
cycle_summary
L3 :
LTE structured evidence
Vehicle / Camera manifest
L4 :
LTE raw cell_search log
Vehicle / Camera JPEG
まで実装されています。
L3/L4は「L2の次に必ず変換される段階」というより、必要な観測についてEvidenceを別表現で残すレベルとして扱っています。
4. Python依存関係
初期開発時には個別に pip install しましたが、現在はGitHubの requirements.txt を正とします。
Google関連は、
gspread==6.2.1
google-auth==2.58.0
です。
新規環境では、
cd /home/ronv/ronv
/home/ronv/.venvs/ronv/bin/pip install \
-r requirements.txt
で揃えます。
5. Service Account認証
Raspberry PiからGoogle Sheetsを自動操作するため、Service Accountを利用します。
認証JSONは例として、
/home/ronv/.config/ronv/secrets/google-service-account.json
へ置きます。
権限は制限します。
chmod 700 /home/ronv/.config/ronv/secrets
chmod 600 \
/home/ronv/.config/ronv/secrets/google-service-account.json
このJSONには秘密鍵が含まれるため、GitHubやQiitaへ載せません。
6. Spreadsheetはユーザー側で作成する
RON-VではSpreadsheet本体は通常のGoogle Driveユーザー側で作成し、Service Accountへ編集権限を付与する形を採用しました。
Google Drive user
↓ owns
RONV Spreadsheet
↓ shared as editor
Service Account
↓ API
Raspberry Pi 5
Service AccountからSpreadsheet全体を複製する方式では権限条件によって403になることがあったため、RON-Vでは「既存Spreadsheetを共有して利用する」方式にしています。
7. ronv.toml
実環境では、
[google]
enabled = true
spreadsheet_id = "<SPREADSHEET_ID>"
credentials_file = "/home/ronv/.config/ronv/secrets/google-service-account.json"
を設定します。
公開用 config/ronv.example.toml では、
[google]
enabled = false
spreadsheet_id = "<SPREADSHEET_ID>"
credentials_file = "/home/ronv/.config/ronv/secrets/google-service-account.json"
とし、実IDは登録しません。
8. Google Sheets構造チェック
現行実装では、
app/integration/google_sheet_check.py
がSpreadsheetとWorksheetの構造を確認します。
検査対象は、
summary
L1
L0
L2
L3_INDEX
L4_INDEX
SYNC
です。
例えば summary は、
band
datetime
lat_lon
peak_count
burst_count
max_power
field_activity_index
can_speed
can_rpm
imu_acc
を持ちます。
L3/L4 INDEXは、ファイル本体をSheetsへ入れず、
object_uid
level
event_time_jst
data_type
local_path
mime_type
local_bytes
sha256
upload_transport
upload_state
remote_id
received_at_jst
などを索引として保存する設計です。
確認は、
cd /home/ronv/ronv
/home/ronv/.venvs/ronv/bin/python \
-m app.integration.google_sheet_check
で行います。
正常なら各Worksheetが OK となり、最後に RESULT : OK になります。
9. #16時点と現在の違い
#16を最初に実装した時点では、
認証
Spreadsheet共有
7 Worksheet作成
Header検証
までを範囲としていました。
そのため当時は、
Google Sheets側は空
L3_INDEX / L4_INDEXも空
で正常でした。
現在は後続の #17 / #18 まで実装が進み、
SQLite
↓
google_sync_worker
↓
summary / L0 / L1 / L2
↓
L3_INDEX / L4_INDEX / SYNC
まで同期できます。
10. なぜ観測ループへGoogle APIを入れないのか
RON-Vで重要なのは、
Internet断
Google API障害
認証一時エラー
が発生しても、
RF観測
LTE観測
GNSS
Vehicle受信
Camera
SQLite保存
を継続することです。
そのためGoogleは常に後段処理です。
RF ─┐
LTE ├─→ SQLite ─→ Google Sync Worker ─→ Google Sheets
CAN ┤
IMU ┘
この分離が、災害時・移動時のネットワーク不安定環境で重要になります。
まとめ
#16ではGoogle Sheets連携の「受け皿」を構築しました。
現在のRON-Vではこの基盤を使って、
summary
L0
L1
L2
L3_INDEX
L4_INDEX
SYNC
まで扱えます。
実装の正はGitHub main の、
requirements.txt
config/ronv.example.toml
app/integration/google_sheet_check.py
app/integration/google_sync_worker.py
です。
次の #17 では、SQLiteからGoogle Sheetsへ非同期同期し、通信障害時にも観測を止めない仕組みを扱います。