先日ESP8266/ESP32でGoogle Spreadsheetのセルを書き込むコードを紹介しました。
今回はセルの内容を読み込む方法を紹介します。
この方法をベースにGoogle Apps Scriptでカレンダーの参照とか他にもいろいろできそうです。
僕はGoogle Calendarから日本の祝日を参照して、電子ペーパーの日めくりカレンダーを妄想中。
#使うもの
ArduinoIDE - ESP8266/ESP32
Google Apps Script
Google Spreadsheet
Sujay Phadkeさん作 HTTPSRedirect リンク
#ESP8266/ESP32からGoogle Apps Scriptを呼ぶ
GScriptId = Script作成で紹介されるIDをセットします。
GSpreadsheetId = スプレッドシートIDです。
GsheetName = シート名です。 (全角文字未対応)
cell = 読み込むセルの位置です。
戻り値
client->getResponseBody() = Google Apps Scriptの戻り値(Script内のエラーならエラーメッセージが入るので、細工が必要です)
#ESP32で使う方法
HTTPSRedirect.hソースでコメントされているstop()を動作する様にします。
//stop(); // may not be required
※2024年2月追記 ESP32C3を使う為に最新のArduinoIDEやライブラリを適用しましたが、動きません。
とりあえず旧ArduinoIDEと従来ESP32では動くので大事にしときます。
※2024年6月追記 ESP32C3向けに環境を整えていくと動作する様になりました。
多分何か勘違いしていたのだと思います。
#Google Scriptのソース
update:2018-08-18 アクセス引数と引数の解析が気に入らないので大幅修正しました。
update:2022-12-19 セルの範囲指定ができる様にGetValuesに書き換えました。
update:2024-06-13 Windows Python3.11.6のrequestsで利用できるのを確認
update:2024-06-13 VisualStudio2010Express c#のWebBrowserで利用できるのを確認
// ログ出力
function logOutput( message )
{
Logger.log(message);
return message;
}
// 戻り値の作成
function messageOutput( message )
{
return ContentService.createTextOutput( logOutput(message) );
}
// doGet command分岐処理
function doGet(e){
try{
logOutput( e.parameter );
var command = e.parameter.command;
if( command == "cellRead" ) return messageOutput(doGetCellRead(e));
}
catch(f){ return messageOutput("ERROR," + f.message); }
return messageOutput("ERROR,commandが判りません");
}
// doGetでのセル読み込み
function doGetCellRead(e)
{
var sheetSS = SpreadsheetApp.openById( e.parameter.sheetid );
var sheet = sheetSS.getSheetByName( e.parameter.sheet );
var range = sheet.getRange( e.parameter.cell );
return range.getValues();
}
function doPost(e)
{
return messageOutput("ERROR,処理できません");
}
#ESP8266のソース
update:2018-08-18 Google Scriptの変更に合わせて引数にcommandを追加しました
update:2022-12-19 ArduinoIDEのESP8266Ver3.0.2で動作するソースに変更しました
#include <ESP8266WiFi.h>
#include "HTTPSRedirect.h"
// Fill ssid and password with your network credentials
const char* ssid = "guest";
const char* password = "guest";
const char* host = "script.google.com";
const int httpsPort = 443;
// Replace with your own script id to make server side changes
// google scriptのscriptID
const char *GScriptId = "==google SciptIDをセットします==";
const char *GSpreadsheetId = "==google SpreadsheetIDをセットします==";
const char *GsheetName = "==Sheet名をセットします==";
// Fetch Google Calendar events for 1 week ahead
const String urlScriptID = String("/macros/s/");
const String urlSheetID = "/exec?command=cellRead&sheetid=";
const String urlSheetName = "&sheet=";
const String urlCell = "&cell=";
void setup() {
Serial.begin(115200);
Serial.flush();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
HTTPSRedirect* client = nullptr;
String payload = "";
bool flag;
if( client == nullptr ){
// Use HTTPSRedirect class to create a new TLS connection
client = new HTTPSRedirect(httpsPort);
client->setInsecure();
client->setPrintResponseBody(true);
client->setContentTypeHeader("application/json");
Serial.print("Connecting to "); Serial.println(host);
// Try to connect for a maximum of 5 times
flag = false;
for (int i=0; i<10; i++){
int retval = client->connect(host, httpsPort);
if (retval == 1) {
flag = true;
break;
}
#ifdef GoogleSpreadSheet_LOG
else
Serial.println("Connection failed. Retrying...");
#endif
}
if (!flag){
#ifdef GoogleSpreadSheet_LOG
Serial.print("Could not connect to server: ");
Serial.println(host);
Serial.println("Exiting...");
#endif
delete client;
client = nullptr;
return;
}
}
String cell = "A8"; //読み込むセルをセットします
String url = urlScriptID + GScriptId;
url = url + urlSheetID + GSpreadsheetId;
url = url + urlSheetName + GsheetName;
url = url + urlCell + cell;
Serial.println(url);
client->GET(url, host);
Serial.print( "Status :"); Serial.println( client->getStatusCode() );
Serial.print( "reasonPhrase:"); Serial.println( client->getReasonPhrase() );
Serial.print( "body :"); Serial.println( client->getResponseBody() );
delete client;
client = nullptr;
delay(10000);
}
セルを読むのはGetで、書くのはPutだったりします。
どちらもGetで行うのがスマートですが、結果的にGetとPutの資料になっているので良いかなっと。
※GoogleSpreadSheetから一挙に読み込む形式GetValuesでの動作確認をしました。
指定例 "A8"=1セル(A8) / "A8:B9"=4セル(A8,B8,A9,B9)