見出し画像

【GASでIoT】(最終)「簡単デバイス」からGASにアクセスして、デバイス⇒スプレッドシートへの記録、およびスプレッドシート⇒デバイスへのレスポンス受信をおこなう

実機では様々な理由により、この説明通りにいかない場合がしばしばあります。申し訳ありませんが、自己責任・自己解決でお進めくださるよう、お願いいたします。

ラズベリーパイをGASの利用と組み合わせる記事もようやく最後まできました。この記事では、ラズベリーパイからGASにアクセスして、スプレッドシートに記録を行い、かつ、GAS側からラズベリーパイにレスポンスを返すまでをご説明します。

ラズベリーパイからのアクセスを受けるためのGoogleスプレッドシートとGAS(Google Apps Script)を用意する


一旦、ラズベリーパイを離れ、しばらくぶりに、スプレッドシートとGASでの作業に入ります。

まず、適当なスプレッドシートを用意しておき、「記録用」という名称の空白のシートを作っておきます。

画像1

次に、Googleドライブ内でGASのプロジェクトを(スプレッドシートとは独立に)作成します。(このスクリプトは公開しますので、スプレッドシートとは分けておいた方がセキュリティ上望ましいかと思います)

画像5

プロジェクト内で以下のスクリプトファイルを1つ作成します。(スクリプトファイルの名称は何でも結構ですが、ここではコード.jsとしました)

画像6


コード.js

//-----------------------------------------
//----ラズパイのトライ--------------------------
//---著作:Particlemethod-2021年11月05日-----
//---無断複製・転載・配布を禁じます-------------
//-----------------------------------------
function doGet(e) {
 var x=e.parameter.x;


 if(e.parameter.x == null){
   return ContentService.createTextOutput('NoData');
 }else{

 //アプリケーションを取得|スプレッドシートのIDは各自のものを記入
 var myApp = SpreadsheetApp.openById('☆スプレッドシートのID☆');

 //対象シートをシートの名前を指定して取得
 var mySheet = myApp.getSheetByName('記録用');
 
 //最終行+1行目にデータを記録
 mySheet.getRange(mySheet.getLastRow() + 1, 1).setValue(x);

 //最終行+1行目をレスポンスとして返す
 return ContentService.createTextOutput(mySheet.getLastRow() + 1);

 }

 
}
コード中の☆スプレッドシートのID☆部分は、各自のものに打ち換えてください。

ポイントは以下の2つです。

1.クエリーパラメータの設定

GASの公開URLに続いて、「?変数名=[]」と打ち込んでからアクセスすると、単にアクセスするだけでなく、パラメータの変数(この場合は)およびその変数の値(この場合は[])を引き渡す事ができます。

これをクエリーパラメータと言います。ごく単純なテキスト情報であればこの方法で簡単に情報をGAS側に遅れます。

スクリプト側では、doGET( e)関数の中で、以下のプロパティから受け取る事ができます。

 e.parameter.変数

function doGet(e) {
 var x=e.parameter.x;

・・・}
このプログラムでは、取り出したクエリーパラメータを、所定のスプレッドシートに書き込む様にしています。


2.テキストによるレスポンスの設定

GASがURLのアクセスを受けた場合に、テキストの返り値(レスポンス)がアクセス者に返る様に設定します。

return ContentService.createTextOutput( 返したい文字 );

 //最終行+1行目をレスポンスとして返す
 return ContentService.createTextOutput(mySheet.getLastRow() + 1);
今回、データ入力したGoogleスプレッドシートの最終行数+1を返す事にしました。(通信検証の為ですのであまり意味はありません)

GASを保存したら、実行者は「自分」、アクセスできるユーザは「全員」としてデプロイしておきます。(ユーザー認証をラズパイ側から行うのは難しいので、だれでもアクセスできる状態にしておきます)

GASを新規デプロイしたらそのIDを控えておきます。


ラズベリーパイ側のプログラムの修正

次に、前の記事でラズベリーパイ側で書いたプログラムを開き、下の方の以下記述部を修正します。(不要な#を削除し、☆GASのID☆を具体的な文字列に置き換える)

具体的には以下の部分です。

#---URLにアクセス
r = requests.get("https://script.google.com/macros/s/☆GASのID☆/exec?x=" + str(Flag))
print(r.text)
#ーーーーーーーー利用モジュールの引用----------
#---WEBにリクエストを投じるためのモジュール
import requests
import sys

#---GPIOを利用するためのモジュール
import RPi.GPIO as GPIO

#---時間を利用するためのモジュール
import time


#ーーーーーーーーGPIOの準備----------

GPIO.setmode(GPIO.BCM)

#GPIO23を入力モードに設定してプルダウン抵抗を有効にする
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

#GPIO2を出力モードに設定
GPIO.setup(2, GPIO.OUT)


#ーーーーーーーーwhile文で無限ループーーーーーーーー
#---初期化処理
Flag = 0
#---ループに入る
while True:
   try:
       #---フラグが1なら
       if(Flag == 1):
           GPIO.output(2, GPIO.HIGH)     #----GPIO25の出力をHigh(3.3V)にする
           Flag = 0                          #フラグを0にする

       #---フラグが0なら
       else:
           GPIO.output(2, GPIO.LOW)      #GPIO25の出力をLow(0V)にする
           Flag = 1                          #フラグを1にする
       time.sleep(1)                           #1秒間待つ

       #---URLにアクセス
       r = requests.get("https://script.google.com/macros/s/☆GASのID☆/exec?x=" + str(Flag))

       print(r.text)

       #---タクトスイッチが押されるまでループ
       while(GPIO.input(23) == 0):
           time.sleep(0.1)                     #0.1秒間待つ
       #---タクトスイッチのループ終わり---
   #---終了処理
   except KeyboardInterrupt:                   #Ctrl+Cキーが押された
       GPIO.cleanup()                          #GPIOをクリーンアップ
       sys.exit()                              #プログラムを終了

コードを修正したら保存します。

ポイントとなる部分は以下です。

1.import requests

 WEB上にURLでアクセスするための関数群をインポートします。

2.変数=equests.get( URL )
  print(変数.text)

 WEB上にURLをリクエストし、レスポンスがあれば変数で受けます。

 受け取ったレスポンスは、テキストなら 変数.text で取り出せます。

このコードは、アクセスする時に、URL末尾にクエリーパラメータとしてLEDの点灯状態を追加してアクセスする様にしています。
受け取ったGASからのレスポンスは、シェル画面に表示する様にしています。


いよいよラズベリーパイからプログラムを作動させてみる

プログラムを保存したら配線状態を確認し、ラズベリーパイでプログラムを作動させてみましょう。配線や、LANケーブルがつながっている事を確認してください。

そして、ラズベリーパイのプログラム編集画面および、所定のGoogleスプレッドシートを表示させておきます。

ラズベリーパイのプログラム画面から「Run」ボタンをクリックすると、以下の様に作動するはずです。

1.タクトスイッチを押すと、LEDが点灯/消灯すると同時に、ラズベリーパイ内部ではURLでWEBにアクセスします。

画像3

2.アクセスを受けるとGASが作動し、受け取った数値(0か1)がスプレッドシートに記録され、かつ、シートの最終行+1がレスポンスされます。

画像7

画像2

3.ラズベリーパイがレスポンスを受けとりとプログラム画面の下側にあるシェル画面に結果を表示します。

画像4

簡単なデバイスを操作して以下の双方向の通信ができました!!

■タクトスイッチを押すと、デバイスからWEB(スプレッドシート)に情報が送信される

■WEB(スプレッドシート)からの情報をデバイスで受信する

GASのレスポンスが返ってくるまでタイムラグがあるので、タクトスイッチを連打する場合は、5秒ほど間隔を開けてください。


付記)デバイスでのWEB通信について ~ デバイスを「サーバ」として設定するべきか、「クライアント」として設定するべきか? ~


今回記事にした通信方法は、アクセス時にGAS側のURLを利用しています。

つまりこの方法は、ラズベリーパイを「クライアント」GAS側を「サーバ」として働かせています。

世の中にはもうひとつ、ラズベリーパイなどのデバイス側を「サーバ」または「アクセスポイント」として設定し、公開されたIPアドレスを手掛かりに通信する方法も盛んにおこなわれています。

ラズベリーパイはもとより、今回採用しなかった、ESP32という通信機能付きのArduinoの互換機を使った通信では、こうした実装例が沢山あります。

画像8

この方法はアクセスする側の設定が楽という特徴がある反面、「サーバ」となったデバイスがハッキングされるリスクが比較的高くなります。

NASAで、ラズベリーパイがハッキングされるニュースがありましたが、おそらくこれは、ラズベリーパイをサーバとして設定したシステムであろうと推察します。

 今回ご紹介した方法は、例えばクエリーパラメータにパスワードを乗せてやる事で疑似的にパスワード認証もできるので、比較的安全な方法と言えそうです。

デバイス側をクライアントに設定するメリットをここで記しておきました。

211113_記事末



この記事が気に入ったらサポートをしてみませんか?