Pico 2 W × Googleフォーム:IoTログ保存の最小構成
はじめに
2017年頃、Raspberry Pi 3でCO₂や気温・湿度・気圧を測るシステムが流行し、
情報を参考にCO2、気温、気圧、湿度を測定、接続したモニタにリアルタイム表示するシステムを構築しました。
その後、2023年にRaspberry Pi Pico 2 Wが登場したことで、構成を見直し
新しいシステムを作りましたが以下の問題に直面しました。
- ログ保存は1週間分のみ(内部記憶メモリの限界)
- 同じネットワーク内でしか閲覧できない
(処理能力・TLS実装の制限でwebサーバとしてhttpsをサポートできない) - MicroPython上でWebページ生成+1日分グラフ描画に毎回15秒近くかかるため、実用性に課題あり
Zero 2 W を選ぶことで回避できたかもしれませんが、あえて処理の負荷をGoogle側に委ねる構成とし、
Pico 2 W でも安定動作が実現できるアプローチとして本構成に落ち着きました。
使用デバイス・言語
- Raspberry Pi Pico 2 W
- MicroPython
- センサ類:SCD30 / AHT20 / BME280
- Googleフォーム + スプレッドシート + GAS
全体構成概要
センサ値取得(MicroPython)
↓
GoogleフォームへPOST送信(HTTPS送信のみなら実装・対応可)
↓
Googleフォームの結果をスプレッドシートの "ALLDATA" に書き込み
↓
GASがトリガーで月別シートへ転送後、ALLDATAのデータ削除
↓
Dashboardシートで最新値とグラフを表示
※ALLDATAという受け取り専用のシートを独立して作るのが重要です。
フォームに投稿されたデータはシートに書き込みの際は絶えず最終行に追加されていくため、
放っておくとそのシートはあふれて書き込み不可になります。
受け取ったらどこかにコピーし、行ごと削除を行い、シートが溢れない対策が必要です。
ALLDATAは当初データを張り付け続けるエリアにするつもりでしたが、行がどこかのタイミングでいっぱいになることに気づいたためデータ移動後、削除仕様にしました。TEMPDATAというシート名のほうが今の実態には合っているとおもいます。
フォームPOST実装(MicroPython)
フォームURL:
https://docs.google.com/forms/d/e/XXXXX/formResponse
ここに向けて POST します。
注意点
-
各項目の
entry.xxxxxxxxx
フィールド名は、ChromeのDevToolsでフォームHTMLを確認して取得します。 -
フォームがHTMLベースのPOSTを想定しているため、JSONなどは不可。
Content-Type: application/x-www-form-urlencoded を正確に送る必要があります。
MicroPythonでのポスト例
FORM_URL = "https://docs.google.com/forms/d/e/XXXXX/formResponse"
def post_to_google_form(datetime_str, temp, hum, pres, co2):
data = {
"entry.1234567890": datetime_str,
"entry.2345678901": temp,
"entry.3456789012": hum,
"entry.4567890123": pres,
"entry.5678901234": co2
}
headers = {"Content-Type": "application/x-www-form-urlencoded"}
encoded = "&".join(f"{k}={v}" for k, v in data.items())
urequests.post(FORM_URL, data=encoded, headers=headers)
スプレッドシートの構成とGAS処理
シート構成:
ALLDATA:フォームPOSTを受ける。常に2行目に最新データ。
yyyyMM:月別ログシート(例: 202507)。なければGASで自動作成。
Dashboard:最新値、指定日のデータ、グラフ表示。
GASの主な処理:
onFormSubmit トリガーでフォーム入力を検知
データを B2:F2 に上書き
該当月シートに追記
Dashboard に最新値を書き込み
2行目を削除
Dashboardのグラフは…
B7セルに日付を入力(デフォルトはToday)
GASが月別ログシートから該当日の行だけ抽出して A10〜 に貼り付け
グラフはその領域を参照して描画
なぜGoogleフォームを使うのか?
完全無料・長期安定(10年単位で仕様が変わっていない。)
認証不要・SSL対応でPOSTできる(フォームの特性上、当面匿名での書き込みは制限されない)
Firebase・IFTTTよりも変更リスクが低く、管理が不要
まとめ
「外部にログを送る」目的に対して、Googleフォームは実は非常に理にかなった選択
FirebaseやWebhookは機能的には過剰で、かえって壊れやすい
Pico 2 W + MicroPython + Googleフォームで、サーバレスかつ堅牢なIoTロガーが完成する
Googleフォームに自動POSTする際の注意点
本構成では、GoogleフォームをHTTPS送信先として直接利用しています。
非常に便利な方法ですが、Googleの正式なAPIではなく、あくまでフォーム構造を応用した非公式な手法であることを理解しておく必要があります。
実装上のポイント
- POST先は
https://docs.google.com/forms/d/e/.../formResponse
を使用する(/viewform
ではない) -
Content-Type: application/x-www-form-urlencoded
を必ず指定 - 各フィールドには
entry.xxxxxxxxx
の形式でパラメータを送る(Chrome DevToolsなどで調査) - フォームの公開設定を「ログイン不要(全員が回答可能)」に変更しておく
利用上の注意(Googleのポリシーへの配慮)
本構成では、Googleフォームの内部エンドポイントに対して直接HTTPS POSTを送信することで、ログ収集を実現しています。
これはGoogleが公式に提供するAPIではなく、「フォームのHTML構造を応用した非公式な方法」です。
Googleの利用規約に違反しない範囲で、安全に使用するために以下を守ってください:
- 送信頻度は 10分に1件程度の低頻度 にとどめること
- 商用利用や不特定多数からのPOST受付などには使用しないこと
- あくまで 個人の観測・実験用途に限定し、Google側に過度な負荷をかけないようにすること
本構成は、あくまで個人用途での楽しみ・観測・実験的利用にとどめることを推奨します。
商用利用や大量アクセスを前提とした用途では、Googleの利用規約に反する恐れがあります。
安定運用や公式保証が必要な用途では、専用のAPIやサービスの利用をご検討ください。
またスプレッドシートの以下の制限も考慮する必要があります。
- GAS経由の書き込みは、1日あたり約50,000セルまで(無料アカウント)
- スクリプト実行時間は 1回あたり30秒以内、1日合計6分以内(無料枠)
この構成は10分に1件程度のPOSTを想定しています。
大量のセンサのデータ送信が必要な場合は他の方法を検討してください
今後はGoogleフォーム以外のクラウド連携や、外部サービスとの連携も試していく予定です。
シンプルかつ無料で始めるなら、本構成のようにすべてがGoogleの中で完結する仕組みは非常に手軽で堅牢です。