ラズパイに接続したセンサーで取得したデータを定期的にGoogleスプレッドシートに上げる方法です。
今回はLPS25Hを使って、1秒ごとに取得した気圧データをスプレットシートにアップロードしてみました。
データをサーバに上げたいけどデータベースサーバーを立ち上げるまでもないかな〜と言った場合にスプレッドシートは何かと重宝します。
取得したデータを公開したり、共有したりも簡単にできますし。ますます捗る!(゚∀゚)b
<環境>
・Raspberry Pi 3
・Google Sheets API v4
気圧データの取得
気圧データの取得は、秋月電子通商で買ったLPS25H使用 気圧センサーモジュールを使用しました。
I2Cインターフェースなので、wiringpiなどのI2Cライブラリを使用すれば簡単に接続することができます。
from __future__ import division import wiringpi as wp import time ADDR = 0x5c class LPS25H(object): def __init__(self): self.i2c = wp.I2C() self.fd = self.i2c.setup(ADDR) whoami = self.i2c.readReg8(self.fd, 0x0f) assert whoami == 0xbd , "Couldn't connect to device!" def read(self): self.i2c.writeReg8(self.fd, 0x20, 0x90) time.sleep(0.1) po_xl = self.i2c.readReg8(self.fd, 0x28) po_l = self.i2c.readReg8(self.fd, 0x29) po_h = self.i2c.readReg8(self.fd, 0x2a) value = po_h << 16 | po_l << 8 | po_xl pressure = (value // 40.96) / 100 #小数点第2位まで return pressure if __name__ == '__main__': dev = LPS25H() for i in xrange(100): pressure = dev.read() print('Pressure %.2f mbar' % (pressure)) time.sleep(1)
LPS25HモジュールはSA0(4ピン)で、I2Cアドレスを切り替えることができます。VDDと接続すると0x5d、GNDと接続すると0x5cです。
今回は0x5cに設定しました。取得する気圧の単位はmbar(ミリバール)になります。
スプレッドシートAPIを使ってデータを上げる
次に、取得したデータをラズパイからスプレッドシートに上げる方法です。
スプレッドシートは他のアプリから操作するためのAPIが用意されています。2017/4月の時点ではAPI v4です。
https://developers.google.com/sheets/api/
APIを使用するための準備は以下のとおりです。
- Google API ConsoleでSheets APIを有効にする
- 認証情報を作成する
- アップ先のスプレッドシートを作成
- Google Client Libraryをインストール
では、詳しく見ていきましょう。
1.Google API ConsoleでSheets APIを有効にする
Google API Consoleで適当なプロジェクトを作成し、Sheets APIを有効化します。
このウィザードにアクセスすると有効化できます。
有効化されたあと、引き続き認証情報を追加する画面になりますが、これは一旦キャンセルします。
2.認証情報を作成する
次に認証情報を追加します。認証情報は、
- APIキー
- OAuth2.0
- サービスアカウント
の3種類があり、用途に合わせて使用できます。
今回は、ラズパイからスタンドアローンで読み書きできるようにしたいため、サービスアカウントを使用します。
*基本的にはOAuthが推奨だと思われます(サンプルもOAuthだし)。APIキーの場合はReadOnlyです。
【認証情報を作成】ボタンを押して“サービスアカウントキー”を選択します。
“サービスアカウント名”を入力します。
“キーのタイプ”はJSONを選択します。
ここで、“サービスアカウントID”をコピーしておいて下さい。次で使用します。
最後に、作成ボタンを押すと自動的に認証用JSONファイルがダウンロードされます。
3.アップ先のスプレッドシートを作成
次にデータのアップロード先のスプレッドシートを作成します。
シートを作成したら右上の共有ボタンを押して、共有するユーザーに先ほどコピーした“サービスアカウントID”を入力します。
これでサービスアカウントからこのシートの編集が可能になりました。
4.Google Client Libraryをインストール
最後にPythonからAPIを使用するためのClient Libraryをインストールします。
sudo pip install --upgrade google-api-python-client oauth2client
これで準備は完了です。
PythonでAPIを叩く
Client Libraryを使ってスプレッドシートにアクセスする方法です。
今回は、スプレッドシートで「データ取得日」、「取得時間」、「気圧」の3項目のログを記録するクラスを書きました。
import httplib2 import numpy as np from apiclient import discovery from oauth2client.service_account import ServiceAccountCredentials SCOPES = 'https://www.googleapis.com/auth/spreadsheets' APPEND_RANGE = 'Sheet1!A1:C1' class SpreadSheet(object): def __init__(self, sheet_id): self.sheetId = sheet_id credentials = ServiceAccountCredentials.from_json_keyfile_name('認証情報作成時のJSONファイル名', scopes=SCOPES) http_auth = credentials.authorize(httplib2.Http()) discoveryUrl = ('https://sheets.googleapis.com/$discovery/rest?''version=v4') self.service = discovery.build('sheets', 'v4', http=http_auth, discoveryServiceUrl=discoveryUrl) def append(self, values): assert np.array(values).shape==(3,) , "The shape of value %s must be 3" % (np.array(values).shape) value_range_body = {'values':[values]} result = self.service.spreadsheets().values().append(spreadsheetId=self.sheetId, range=APPEND_RANGE, valueInputOption='USER_ENTERED', body=value_range_body).execute() #print(result) if __name__ == '__main__': sheet = SpreadSheet("シートID") sheet.append(["test", "test", 3])
__init__に渡す“sheet_id”は編集するシートのIDで、シートのURLの下記赤枠の文字列になります。
今回使用したAPIはシートに順次追加していくappendです。
service.spreadsheets().values().append( spreadsheetId='シートのID' range='データを追加する場所 例)Data1!A1:C1はData1とう名前のシートのA列からC列' valueInputOption='データ入力オプション RAW:そのまま入力、USER_ENTERED:ユーザ指定の書式に従う?' body='入力するデータ' ).execute()
入力するデータは、{‘values’:[[1,2,3]]}のような形式で指定する。
この場合、A1セル=1,B1セル=2,C1セル=3になる。ちなみに{‘values’:[[1,2,3],[4,5,6]]}こんな感じに複数指定すると、A2=4,B2=5,C2=6のように一気に複数行の追加が可能。appendは基本下の行に追加される(insertDataOptionでコントロール可)。
APIの詳しい使い方については、ここが参考になります。
追加以外のAPIはこちら。
気圧データを定期的にアップする
最後に気圧の取得とスプレッドシートへのアップをするプログラムです。
5秒ごとに気圧データをスプレッドシートに追加していきます。
from lps25h import LPS25H from spredsheet import SpreadSheet from time import sleep import datatime sensor = LPS25H() sheet = SpreadSheet('シートのID') while(1): date = datetime.datetime.now().strftime("%Y/%m/%d") time = datetime.datetime.now().strftime("%H:%M:%S") pressure = sensor.read() sheet.append([date, time, pressure]) sleep(5)
以上です。
あとがき
最近はよくGoogleドキュメントを使うようになりました。やっぱり簡単にデバイス間や関係者間で共有できるのは便利だなと思うわけです。
逆にGoogleドキュメントに変換できないようなワードファイルとかで送られてくると若干イラっと・・・。