![見出し画像](https://assets.st-note.com/production/uploads/images/80497552/rectangle_large_type_2_39699597ef4871e69937c09fa25b70d9.jpeg?width=1200)
【GASでIoT】GASとラズパイでおこなう、お手軽データ・ロギング&フィードバック制御〔解説編3〕~ラズパイ側での、温度センサ DS18B20の読み取りとGASへの送受信~
この記事のシリーズでは、Googole Apps Script(GAS)を利用して、日常生活を便利にする事をテーマにしています。
GASへのアクセスは、通常はキーボードから文字情報で行いますが、「Raspberry Pi(ラズベリーパイ)」というシングルボードコンピュータを介することで、文字以外の情報をインプットする事ができます。
今回インプットする情報は「温度」で、この情報を利用して電気なべの温度をコントロールしよう、というのがテーマです。
先回までで、ラズベリーパイにという、セットアップが大変楽な1-wire仕様の温度センサ DS18B20を 接続するまでを解説しました。
今回の記事は、温度センサで読み取った値をGASに送信する方法についての紹介です。
HTTPSを介した、シングルボードコンピュータとGASとの通信について
今回のシステムでは、ラズベリーパイを「クライアント」と見立てて、サーバーに見立てた「GAS」との通信によって電気なべを制御します。
以前の記事でご紹介したシステム全体図を再掲しましょう。
![](https://assets.st-note.com/img/1654997317839-u43YPPhQeH.png?width=1200)
この様な事例ではラズベリーパイをサーバー側として、ラズベリーパイにアクセスして制御している事が多いのです。
しかし、この様にラズベリーパイをサーバー側ではなくクライアント側とすると、ラズベリーパイへの不正なアクセスを避けたり、運転途中で制御を変えるといった柔軟な運用ができます。
URLを介したGASへのアクセス
このシステムでは、ラズベリーパイがGASへアクセスする事でデータの受け渡しが始まります。
Google Apps Script は、「デプロイ」とよばれる手続きをすることで、HTTPSではじまるURLと紐づける事ができ、このURLにアクセスすることでGASを起動する事ができますので、この仕組みを利用してアクセスします。
![](https://assets.st-note.com/img/1654995698158-ozXuWGeSSe.png)
「デプロイ」など、基本的なGASアプリの作り方については、以下の記事から始まる記事でご紹介しています。
記事がブログでは細切れなので、拙文ながら冊子の形に資料化したものも作ってみました。(読みやすい様に縦書きにしてみました)
以下の記事でご紹介しています。ご興味を持たれましたらどうぞ・・・
ラズベリーパイからGASへの情報引き渡し
アクセスした際に最初におこなう事は、ラズベリーパイ側からGASへデータ情報を引き渡す事です。
この時、「マクロコード」と呼ばれる付加情報をURLに付け加えてアクセスする事で、アクセス先に情報を引き渡せます。
マクロコードは以下のルールで使用します。
・「?」をURLの後ろに付け加えて始める
・「変数名=値」のテキストを追加する
・「&」でつなぐ事で、2つ以上の変数とデータを引き渡し可能
図解?するとこんな感じです。
![](https://assets.st-note.com/img/1654995895921-no9NNGJOj8.png)
このマクロコードを利用することで、文字ベースの情報であれば簡単に情報を引き渡す事が可能です。
GASからラズベリーパイへのレスポンス受け取り
今回のシステムでは、電気なべの制御は、GASからの指示で行います。
そのため、ラズベリーパイは、温度データをGASへ引き渡したあと、GASで判断した制御情報を、GASからのレスポンスとして受け取る必要があります。
「レスポンス」というと、一般的には下図の様に、HTML文書の形で返される場合が多いのですが・・・
![](https://assets.st-note.com/img/1654996991361-fAoyOnDdGc.png)
・・・今回は、単なるテキストデータをレスポンスします。
![](https://assets.st-note.com/img/1654997989382-iWl2qyoNHb.png)
GASのプログラムでテキストのレスポンスは簡単にできます。
コードの詳細は引き続きご説明しますが、以上の方法で、ラズベリーパイからGASへの通信および情報のやりとりをします。
HTTPS通信~OSを搭載しているタイプのシングルボード・コンピュータでないとGASとの通信はむずかしい~
ここで、少し脇道にそれますが、GASへアクセスする時のURLで用いられる、HTTPS通信について触れておきます。
日常生活を少し便利にするためのGASですが、このGASを活かすために使うラズベリーパイという製品は、少し高いですね?
同じシングルボード・コンピュータであればもっと安いものがあるのに、どうしてラズベリーパイに固執するのだろう・・・とお思いの方も居るかもしれません。
その理由は、ラズベリーパイの様な、OSを搭載したタイプのシングルボード・コンピュータでないと、HTTPSをURLにもった相手とは通信が難しいからなのです。
WEBアドレスの元祖・・HTTP通信
WEB上の通信は、もともとは HTTP~ではじまる、末尾に「S」がないURLで行われていました。
このタイプのURLであれば、OSを搭載しないタイプのシングルボード・コンピュータである、Arduiono(アールデュイーノ)※や、
※有線LANのみ
![](https://assets.st-note.com/img/1654999158411-vxDIjqrue6.png)
その互換機でWiFiモジュールを搭載したESP32が使えます。
![](https://assets.st-note.com/img/1654999203104-LuPWcK01Nk.png)
これらは非常に安価で、店舗によっては1000円以下で調達できます。
しかし、残念ながら、GASが用いているHTTPS通信がこれらの製品では難しいのです。
できない事はないのですが、SSL認証の中身をプログラム内に記載する必要があります。SSL認証の中身を取得するのも、プログラムに盛り込むのも、なかなか骨が折れます。 色々トライしたのですが、リクエストは何とかなったもレスポンスを得ることが難しく、諦めた次第です。
セキュリティ対策したHTTPS通信
HTTPではじまるURLで普及したWEB通信ですが、普及するにつて、アクセス先が虚偽のサーバであったり、通信内容が盗み見られるという、セキュリティ上の問題が出てきました。
そこで、「SSL認証」という、通信のセキュリティを境界した仕組みができました。この仕組みを使用している通信はHTTPSで始まるURLとなり、GASものこのタイプのURLを利用しています。
この通信は、不正確なのを承知でご説明すると以下の様なものです。
①クライアントがサーバにアクセスします。
![](https://assets.st-note.com/img/1654999445334-rbsTLX0Uk8.png)
②すると、レスポンスが送られる前に、まず暗号化のための鍵が返されます。
![](https://assets.st-note.com/img/1654999499074-TBHSrQyrg3.png)
③戻った鍵を再び返して、鍵をクライアントとサーバで共有します。
![](https://assets.st-note.com/img/1654999537216-IyBqMQs7Tp.png)
④ここまで済んだら、ようやく通信が始まります。情報は互いに暗号化の鍵を掛けて(金庫に入れて流すイメージ)、受け取った側は同じ鍵で金庫を開けて中身を取り出します。
![](https://assets.st-note.com/img/1654999614752-YJS9lF0Nh0.png)
以上の手続きをOSの無いESP32の様なシングルボード・コンピュータで実装するのは(できない事はないのでしょうが)非常に難しく、鍵を扱う部分でかなりのプログラムが必要になるはずで、アマチュアの域を超える内容かと思います。
ラズベリーパイであれば、OSが処理してくれるので、ユーザはこの部分で何もする必要がありません。
ラズベリーパイを使うのは、こうした理由からです。
温度センサの値を読み出して、GASに投じるプログラム~Raspberry Pi(ラズベリーパイ)側~
それでは、温度センサの値を読み出してGASに投じるまでのラズベリーパイ側のプログラムをご紹介します。
1-wire仕様のセンサの値の読み出しは、以下ブログなどを参考にしました。この場を借りて御礼申し上げます。
ライブラリのインポート
まずはいくつかのライブラリをインポートします。ライブラリは基本的には標準で備わっており、外部からファイルはダウンロードしないで済むはずで、プログラム中で宣言するだけです。
#---時間を利用するためのライブラリ
import time
#---WEBにリクエストを投じるためのライブラリ
import requests
import sys
#---GPIOを利用するためのライブラリ
import RPi.GPIO as GPIO
#---1Wireを利用するためのライブラリ
import os
import glob
from time import sleep
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
GPIOの準備
外部のリレー(SSR)へ、ON/OFFの信号を送るため、GPIOのピンを使うので、GPIOを宣言します。
1-wireで既に、4番ピンなどは予約ずみなので、バッティングしない様、なるべく後ろの番号である26番ピンを今回は使う事にしました。
#---GPIOの準備
GPIO.setmode(GPIO.BCM)
#GPIO2を出力モードに設定
GPIO.setup(26, GPIO.OUT)
実物では、SDカードを上にした状態で以下の囲みの位置のピンです。
![](https://assets.st-note.com/img/1655023720168-tjaaF6i89I.png)
1-wireを設定し、同時にGPIOを設定することは、あまり推奨されていない様で、実行させるとワーニングが出ます。(そのまま実行されますが)
読み出すファイルの設定
1-wireでは、所定のフォルダが自動生成されて、ここにデータが書き込まれますが、そのファイルを設定します。
#--読み出すファイルの設定
#---1WireのDS18B20温度センサの記録フォルダ
base_dir = '/sys/bus/w1/devices/'
#---28で始まるフォルダ
device_folder = glob.glob(base_dir + '28*')[0]
#---記録ファイル
device_file = device_folder + '/w1_slave'
これは、要するに以下のW1_slaveというファイルを設定しているのです。
![](https://assets.st-note.com/img/1655023974444-FYxVlm6XNl.png)
対象ファイルから温度データを抽出する関数
読み出すファイルを設定したら、このファイルから1行ずつ読み込んで、温度を記載しているテキストを抽出する関数を作成します。
以下では、read_temp_raw( ) という関数で1行単位で読み込みます。
次いで、read_temp( ) とう関数で、「t=」を含む行において、「t=」以降の文字列を抽出しています。
# 温度ファイルのデータを取得する関数
def read_temp_raw():
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines
# 温度データのみを取り出して返す関数
def read_temp():
lines = read_temp_raw()
# 温度データ行のみを取り出して返す関数
# 最後の3行文字がYESでない行を取得
while lines[0].strip()[-3:] != 'YES':
sleep(0.2)
lines = read_temp_raw()
#「t=」の文字位置を取得
equals_pos = lines[1].find('t=')
if equals_pos != -1:
#「t=」以降の文字を取得
temp_string = lines[1][equals_pos + 2:]
# 取得した文字を1000で割ると温度となる
temp_c = float(temp_string) / 1000.0
return temp_c
これは、ファイルを開いて 以下の「t= 」の部分を温度として抽出して、これを1000で割っている訳です。
![](https://assets.st-note.com/img/1655024242607-8y038bQi8U.png?width=1200)
15秒置きに繰り返し温度を取得
ここまで出来たら、ループを使って、15秒毎に処理を繰り返しで行う記述をします。
try:
while True:
#---温度
thrm = read_temp()
print(thrm)
#---URLにアクセス
print('Accesing to GAS...')
r = requests.get("https://script.google.com/macros/s/★デプロイID★/exec?thrm=" + str(thrm))
・・中略・・・
#---15秒待つ
sleep(15)
except KeyboardInterrupt:
pass
重要部分は以下の1行です。
r = requests.get("https://script.google.com/macros/s/★デプロイID★/exec?thrm=" + str(thrm))
上記の1行で、GASにマクロコード付きでアクセスし、同時にレスポンスをrという変数に格納しています。
マクロコードは ?thrm=" + str(thrm) の部分です
さきほどから触れている、HTTPSへのアクセスとレスポンス取得が、以下のたった一文で記述されている点にご注目!。
レスポンス= requests.get(URL)
GASのレスポンスに従って、GPIOピンをHigh/Lowする
GASから取得したレスポンスは、以下の一文でテキストとして取り出せます。
これを使って、GPIOを操作します。
プトグラムは以下です。
#---レスポンスをコンソールに表示
print(r.text)
#---レスポンスに応じたGPIOピンのH/L
#---rが「On」なら赤いピンをHighにする
if(r.text == 'On'):
GPIO.output(26, GPIO.HIGH) #----GPIO2の出力をHigh(3.3V)にする
else:
GPIO.output(26, GPIO.LOW) #----GPIO2の出力をLow(0V)にする
#---15秒待つ
sleep(15)
except KeyboardInterrupt:
pass
長くなりましたので、ここで一旦切ります。
GAS側のプログラムは、次回の記事でご説明します。
![](https://assets.st-note.com/img/1655025947656-zDgtgcmeoh.png)