Raspberry Pi 4Bに接続した温度センサの値をGoogleスプレッドシートにアップしてNotion上にグラフ表示

## はじめに
IoTが叫ばれている昨今（あれっ！？もうIoTって聞かなくなってきたような。死語かな…）、 手持ちのラズパイを使って何か出来ないかと考えていたところ、GoogleAPIを使うとスプレッドシートにデータをアップロード出来ることを発見。
備忘録として、それまでの手順をまとめます。
更に、Notionでグラフ表示できることも分かって、スゲー！ってなったので、それについても記載しています。

なので、基板周りはサラッと流させて下さい。
私としてはスプレッドシートにアップできたところ、Notionでグラフ表示できたところに感動があったため、その辺りにウェイトを置いた記事となります。

なお、言語はpythonで記載します。


## ラズパイと温度センサの接続準備
ラズパイはRaspberry Pi 4Bを使用しています。
温度センサはアナログデバイセズ社のADT7310を使用しています。
秋月電子で売っているのを使いました（[こちら](https://www.akizukidenshi.com/catalog/g/gM-06708/))。
ラズパイとの接続はSPI通信方式となります。以下、参考接続図です。
（ADT7310がFritzingに見当たらなかったため別のセンサでSPI接続図を書いています。すみません。ホント、参考程度に）
![Raspi_SPI_0_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/1d85e4ee-7a64-8129-5714-9cb96dd68243.png)

### ADT7310の温度取得
SPI通信を使用するため、まずはラズパイの設定でSPI通信を使用許可して下さい。
`raspi-config`で設定しても良いですし、GUIであればスタートボタン→設定→Raspberry Piの設定からでも設定できます。

Raspberry Pi設定画面
![スクリーンショット 2021-06-09 101911.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/ddc63a08-5248-00d0-18b0-a39d2ae3ecd8.png)

pythonでSPI通信を使うために、`spidev`ライブラリを使います。
インストールされていない場合はインストールしましょう（[参考](https://pypi.org/project/spidev/)）。

#### ソースコード
```python:adt7310.py
import spidev
import time

class ADT7310:

    def __init__(self) -> None:
        print('adt7310 init')
        self.spi = spidev.SpiDev()
        spi_ch = 0  # use cs0 pin
        self.spi.open(0, spi_ch)
        self.spi.mode = 0x03
        self.spi.max_speed_hz = 1000000

        time.sleep(0.25)
        self.spi.xfer2([0xff, 0xff, 0xff, 0xff])


    def get_temp_adt7310(self):
        self.spi.xfer2([0x54])
        # time.sleep(0.5)
        time.sleep(0.25)
        adc = self.spi.xfer2([0xff, 0xff])
        temp = (adc[0] << 8) | adc[1]
        temp = temp >> 3
        if(temp >= 4096):
            temp = temp - 8192
        
        temp = temp / 16.0
        return temp

    def close(self):
        self.spi.close()
```

## Googleスプレッドシートにアップするために
さて、この記事のメインです。スプレッドシートに書き込みましょう！
今回の方法ではGoogle Cloud PlatformにてGoogle Drive APIとGoogle Sheet APIを有効化し、サービスアカウント作成とjsonキーの取得を行います。
やっていきましょう。
### Google Cloud Platformの設定1
まずは[Google Cloud Platform](https://console.cloud.google.com/flows/enableapi?apiid=sheets.googleapis.com&pli=1)にアクセス。
以下の画面になるのでそのまま「続行」しましょう。
![スクリーンショット 2021-06-09 104126.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/442678c6-22de-0413-2746-c93e7d9a1ec6.png)

何もせず、「認証情報に進む」ボタンをクリックします。
![スクリーンショット 2021-06-09 104258.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/070b5886-6e84-03cd-2d91-358f64e4e4be.png)

次の画面では、完了せずに「キャンセル」をクリックします。
![スクリーンショット 2021-06-09 104514.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/4991e259-3f39-3b3e-2f7b-744a660c27bd.png)

### APIの有効化
キャンセルした後の画面で、左メニューから「ダッシュボード」をクリック、さらに「＋APIとサービスを有効化」をクリックします。
![スクリーンショット 2021-06-09 104940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/0359c346-647c-0e54-4a06-d6ef47c68bed.png)

APIライブラリでGoogle Drive APIを検索し、有効化します。
![スクリーンショット 2021-06-09 105128.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/af85afb9-ec43-aa23-6181-f72b4cfd4b83.png)

次は、Google Sheet APIを検索し、同様に有効化します。
![スクリーンショット 2021-06-09 105329.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/3ad547f3-32fd-c2f1-34d1-011739a8fb20.png)

### サービスアカウントの作成とキー取得
APIとサービス画面から、「認証情報」をクリックし、「サービスアカウントの管理」をクリックします。
![スクリーンショット 2021-06-09 105941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/3f99e660-cfa2-eb11-d9d8-83a324845e3b.png)

次の画面で「+サービスアカウントの作成」をクリックします。
![スクリーンショット 2021-06-09 110123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/6322c8e6-7a81-db5e-8cc8-6c5cb0707a41.png)

サービスアカウントの作成画面に遷移するので、サービスアカウント名を記載して作成をクリックします。
今回はサービスアカウント名を「raspi_temp_sheet」としました。
サービスアカウントは自動で作成されますので特に記載する必要はないです。
![スクリーンショット 2021-06-09 110637.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/a8221f0b-a6b5-0886-9ad2-892746ac05bb.png)

作成後、②と③は省略可とあるため、そのまま完了してしまいましょう。
![スクリーンショット 2021-06-09 111017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/8bf9917e-d428-38e2-6fea-37045cff3b1d.png)

作成が完了したら、作成したアカウントのメールをクリックします。
![スクリーンショット 2021-06-09 111220.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/b9d17760-4843-326a-64fa-3337bab6b535.png)

「キー」タブをクリック後、鍵を追加をクリック。「新しい鍵を作成」を選択します。
![スクリーンショット 2021-06-09 111408.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/fdb774e6-2cdb-a04e-41ce-58f5fd8f768f.png)

鍵はjsonにしましょう。
![スクリーンショット 2021-06-09 111525.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/c564608c-6fdb-4a65-2425-c78967906c78.png)

jsonファイルがローカルにダウンロードされたと思います！
後で使用しますのでなくさないようにしましょう。

### スプレッドシートの作成と設定
ラズパイから書き込むためのスプレッドシートを作成します。
作成したら、ファイル名、シート名は各自で記載しましょう。私はシート名は「temp」にしました（あとで使います）。
また、1行目に 「date」「cpu temp」「atmos temp」の3つを記載しました。
dateはラズパイで温度をセンシングした時間
cpu tempはラズパイのCPUの温度
atmos tempは先ほどラズパイで接続したADT7310でセンシングした温度
とします。
![スクリーンショット 2021-06-09 112533.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/1235115e-51b9-1324-693d-a5d6f3ee818a.png)

このスプレッドシートを共有します。
共有相手は、先ほど作成したサービスアカウントのID（メールアドレス）となります。
![スクリーンショット 2021-06-09 112856.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/65c40ea2-e1c9-5ea8-6234-0565190a9424.png)

これにてサービスアカウントとスプレッドシートとの連携が取れたかと思います。
次はラズパイからこのスプレッドシートにデータを書き込んでいきましょう。

### ラズパイの設定とコード
まずはライブラリをインストールしましょう。
`pip install --upgrade google-auth google-api-python-client google-auth-httplib2 google-auth-oauthlib`

その後、以下のコードにて時刻・CPU温度・センサ温度をスプレッドシートに書き込みます。
先ほどのjsonファイルはpythonファイルと同じ階層に置いています。
各自、jsonファイル名や階層などによってソースコードを変更してください。
また、SPREAD_SHEET_IDは先ほど作成したスプレッドシートのURLの/d/の後から/editの前のURLとなります。
例えば、`https://docs.google.com/spreadsheets/d/sample/edit#gid=0`というURLの場合は
`sample`がSPREAD_SHEET_IDに該当します。

なお、ADT7310のソースコードも以下のpythonファイルの直下に置いてください。

```python:main.py
import datetime
import sys
import time

from googleapiclient.discovery import build
from googleapiclient.errors import HttpError as googleHttpError
from google.oauth2 import service_account

from gpiozero import CPUTemperature

from adt7310 import ADT7310

# your create json file
JSON_FILE = './key.json'
# edit your spread sheet id
SPREAD_SHEET_ID = 'your_sheet_id'
# sheet name
SHEET_NAME = 'temp'


service = None


def login_service(json_file, sheet_id):

    credentials = service_account.Credentials.from_service_account_file(json_file)
    scoped_credentials = credentials.with_scopes(
    [
        'https://spreadsheets.google.com/feeds', 
        'https://www.googleapis.com/auth/drive'
    ])

    print('credentials: ', scoped_credentials)

    service = build('sheets', 'v4', credentials=scoped_credentials)
    sheet = service.spreadsheets()

    try:
        result = sheet.get(spreadsheetId=sheet_id).execute()
    except googleHttpError as e:
        print(e)

    for sheet in result['sheets']:
        print('Index %s: Sheet name = %s' % (
            sheet['properties']['index'],
            sheet['properties']['title'])
        )
    
    return service


def append_sheet(service, sheet_id, sheet_name, val):
    values = [
                val
            ]

    body = {
                'values': values
            }

    ret = service.spreadsheets().values().append(spreadsheetId=sheet_id, range=sheet_name, valueInputOption='USER_ENTERED', body=body).execute()
    print('{0} cells appended.'.format(ret.get('updates').get('updatedCells')))


if __name__ == '__main__':

    my_adt7310 = ADT7310()

    time.sleep(0.1)

    while True:
        try:
            # Login if necessary.
            if service is None:
                service = login_service(JSON_FILE, SPREAD_SHEET_ID)

            # get cpu temp at gpiozero
            tmp = CPUTemperature()
            cpu_temp_gpio = tmp.temperature

            # get atmos temp
            atmos_temp = my_adt7310.get_temp_adt7310()

            # get date
            now_date = datetime.datetime.now().isoformat(' ')

            # upload to spreadsheet
            append_sheet(service, SPREAD_SHEET_ID, SHEET_NAME, [now_date, cpu_temp_gpio, atmos_temp])
            print("{0}__cpu_temp: {1}'C,  atmos_temp: {2}'C".format( now_date, cpu_temp_gpio, atmos_temp))


        except KeyboardInterrupt:
            my_adt7310.close()
            sys.exit(0)

        except:
            # Error appending data, most likely because credentials are stale.
            # Null out the worksheet so a login is performed at the top of the loop.
            print('Append error, logging in again')
            worksheet = None
            # time.sleep(1)
            continue

        finally:
            # wait...
        #    time.sleep(0.1/2)
            time.sleep(60)

```

スプレッドシートに書き込めましたか？ 書き込めましたね！
やった！
![スクリーンショット 2021-06-09 121304.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/2d420b24-3fc0-9490-c403-e130f5192447.png)


## Notionにシートのグラフを表示する
ここまで結構な道のりでした。お疲れ様です。
最後にNotionで先ほどのスプレッドシートの情報をグラフ表示してみましょう。

### Googleスプレッドシートの設定
共有設定にて、「リンクを知る人全員が閲覧可能」の設定に変更します。
![スクリーンショット 2021-06-09 121637.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/2edc5753-ba22-e4cb-de26-4e3ea7b89c09.png)

### Notionに表示する
NotionにはNotion Chartsというサービスがあり、こちらを利用してNotion上にグラフ表示を行います。
まずは以下をクリックしてください。
[こちら](https://www.notion.vip/charts/)

さて、一つずつ記載していきましょう。

- GOOGLE SHEETS DOCUMENT ID : pythonファイルにも記載した、自身のスプレッドシートのリンクの一部です
- SHEET NAME : スプレッドシートのシート名（私の場合はtemp）
- DATA RANGE : グラフ表示したいセルの領域


![スクリーンショット 2021-06-09 122231.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/75f7d5d1-dc41-c5bc-7934-538b43ba1db1.png)

ここでの変更は、「Craft your pallet.」の「Color2」を追加したのみです。
今回のグラフはCPU温度と気温の2つを表示したいため、Color2を追加しました。
![スクリーンショット 2021-06-09 122817.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/87152469-f0e2-ee14-9b84-9bcfda264852.png)

最後に、作成です（Make Magic）！
![スクリーンショット 2021-06-09 123017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/223fe8d0-bb35-20da-4221-0cc4633eff77.png)

作成されたリンクをNotionに「Create embed」で貼り付けましょう。
![スクリーンショット 2021-06-09 123138.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/b56ea1fc-3185-27d4-6514-a38f0ff56aab.png)

すると、、、
![スクリーンショット 2021-06-09 123643.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17169/02a2c318-c2b4-c12e-6f16-35f2d5ab05fc.png)

表示が出来ましたね！

さらに、DATA RANGEを広めに指定しておけば、Notionのグラフが自動で更新されていくのがわかると思います。

## まとめ
ラズパイで得たデータをGoogleスプレッドシートに書き込んで、Notionでグラフ表示しました。
IoTやった感がありますね。
また、Google APIはスプレッドシート以外にもたくさんのサービスを利用できます。
気が向いたら他のサービスも触ってみたいと思いますし、皆さんもぜひ色んなサービスを使ってみてはいかがでしょうか。

最後に、Notionを使用し始めて3週間程度ですが、Notion凄い便利ですね。
凄い。スプレッドシートのグラフ表示が出来ることがわかり、より一層Notionが好きになりました。

## 参考リンク
- Google Sheet API
    - [python quickstart](https://developers.google.com/sheets/api/quickstart/python)
    - [read write cell](https://developers.google.com/sheets/api/guides/values#python)