ラズパイ3で Google カレンダー取得
Google Calenderの予定をPython3から取得する
と
Raspberry PiでGoogle Calendarの予定を読み上げさせる
Google Calendarの予定に応じてRaspberryPiに処理をさせる(その1)
Raspberry PiとGoogle カレンダでGoogle Homeにゴミの日を教えてもらう
を
参考に
まずはセットアップ
Google Calendar APIのPython Quickstart
を参考に行う
Enable the Google Calender API
をクリック
どのプラットフォームか聞かれるので
とりあえず Desktop app にして
CREATE をクリック
認証に必要な情報がでるので
DOWNLOAD CLIENTCONFIGURATION
をクリックし
json ファイルをダウンロード
終わったら
DONE をクリック
次にダウンロードしたファイルを
ラズパイ3にコピーする
scp credentials.json pi@192.168.1.4:/home/pi/
次にラズパイ3で必要なライブラリのインストール
sudo pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
次に認証のためのスクリプトの取得
wget https://raw.githubusercontent.com/gsuitedevs/python-samples/master/calendar/quickstart/quickstart.py
次に認証をブラウザで行うことになるので
【ラズベリーパイ(ラズパイ)】ラズパイをスピーカーにもっとも簡単に接続する方法!
を参考に
VNCで設定を行う
sudo raspi-config
で
5 Interfacing OPtions を選択
P3 VNC を選択
はい を選択
設定できたら
Finish を選択
./VNC-Viewer-6.20.113-Linux-x64
でVNC Viewer を起動
使い方に関しては
Raspberry Pi(ラズパイ)をSSHとVNC設定してリモート接続してみた!【Windows10】
を参考に
IPアドレスを入力
ユーザ名 pi
パスワードはログインパスワードを入力し
OK をクリック
これでリモートデスクトップが表示されるので
端末アイコンをクリック
python quickstart.py
しかし
Traceback (most recent call last): File "quickstart.py", line 20, in <module> from googleapiclient.discovery import build ImportError: No module named googleapiclient.discovery
となってしまう
googleapis /google-api-python-client
を見ると
virtualenv が必要らしい
pip install virtualenv
でインストール
virtualenv google_calender
で仮想環境を作成
source google_calender/bin/activate
で仮想環境を有効化
pip install google-api-python-client
の後に
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
を実行したが
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))': /simple/pytz/
と同じようにでてくる
仕方がないので
ラズパイ3での認証はやめて
Ubuntu で認証することに
Google Calenderの予定をPython3から取得する
を参考に
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
で必要なライブラリのインストール
Enable the Google Calender API をクリックし
API Console をクリック
これで API の設定画面になるので
OAuth 2.0 クライアントIDの
ダウンロードアイコンをクリックし
ダウンロードしたファイルを
credentials.json
へ変更
あとは
vim quickstart.py
でファイルを作成
from __future__ import print_function import datetime import pickle import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request # If modifying these scopes, delete the file token.pickle. SCOPES = ['https://www.googleapis.com/auth/calendar.readonly'] def main(): """Shows basic usage of the Google Calendar API. Prints the start and name of the next 10 events on the user's calendar. """ creds = None # The file token.pickle stores the user's access and refresh tokens, and is # created automatically when the authorization flow completes for the first # time. if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) # If there are no (valid) credentials available, let the user log in. if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server() # Save the credentials for the next run with open('token.pickle', 'wb') as token: pickle.dump(creds, token) service = build('calendar', 'v3', credentials=creds) # Call the Calendar API now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time print('Getting the upcoming 10 events') events_result = service.events().list(calendarId='primary', timeMin=now, maxResults=10, singleEvents=True, orderBy='startTime').execute() events = events_result.get('items', []) if not events: print('No upcoming events found.') for event in events: start = event['start'].get('dateTime', event['start'].get('date')) print(start, event['summary']) if __name__ == '__main__': main()
で保存
python quickstart.py
を実行すると認証画面になる
最後のほうで
このアプリは 確認されていません
とでるが
https://eguweb.jp/gas/this-application-has-not-been-confirmed
を参考に
承認作業を行えばOK
これで
token.pickle
が作成されるので
Google カレンダーに予定を追加し
python quickstart.py
を実行すると
最新10件まで Google カレンダーの予定を取得できる
あとは
token.pickle
credentials.json
をラズパイ3へ scp で転送する
scp token.pickle pi@192.168.1.4:/home/pi/ scp credentials.json pi@192.168.1.4:/home/pi/
次に
天気予報情報・Googleカレンダーの予定をpythonで取得する方法 on Raspberry Pi/Mac
を参考に
ラズパイ3で
wget https://raw.githubusercontent.com/karaage0703/karaage-echo/master/get_gcal_schedule.py
でファイルを取得
python get_gcal_schedule.py
を実行したけど
Traceback (most recent call last): File "get_gcal_schedule.py", line 7, in <module> from oauth2client import client ModuleNotFoundError: No module named 'oauth2client'
となるので
raspberry piでGoogleカレンダー取得スクリプトのセットアップ
を参考に
sudo pip install --upgrade oauth2client --ignore-installed six
でインストール後
再度実行しても
/home/pi/.pyenv/versions/3.6.10/lib/python3.6/site-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access /home/pi/.credentials/calendar-python-quickstart.json: No such file or directory warnings.warn(_MISSING_FILE_MESSAGE.format(filename)) Traceback (most recent call last): File "/home/pi/.pyenv/versions/3.6.10/lib/python3.6/site-packages/oauth2client/clientsecrets.py", line 121, in _loadfile with open(filename, 'r') as fp: FileNotFoundError: [Errno 2] No such file or directory: 'client_secret.json' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "get_gcal_schedule.py", line 91, in <module> get_schedule() File "get_gcal_schedule.py", line 60, in get_schedule credentials = get_credentials() File "get_gcal_schedule.py", line 45, in get_credentials flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES) File "/home/pi/.pyenv/versions/3.6.10/lib/python3.6/site-packages/oauth2client/_helpers.py", line 133, in positional_wrapper return wrapped(*args, **kwargs) File "/home/pi/.pyenv/versions/3.6.10/lib/python3.6/site-packages/oauth2client/client.py", line 2135, in flow_from_clientsecrets cache=cache) File "/home/pi/.pyenv/versions/3.6.10/lib/python3.6/site-packages/oauth2client/clientsecrets.py", line 165, in loadfile return _loadfile(filename) File "/home/pi/.pyenv/versions/3.6.10/lib/python3.6/site-packages/oauth2client/clientsecrets.py", line 125, in _loadfile exc.strerror, exc.errno) oauth2client.clientsecrets.InvalidClientSecretsError: ('Error opening file', 'cl
となる
このため
一度 ubuntu で
google_calender ディレクトリを作成し
ここで作業
別ディレクトリを作成したのは
quickstart.py がすでにあるので
別のファイルを作りたいため
vim quickstart.py
でファイルを作成
from __future__ import print_function import httplib2 import os from apiclient import discovery from oauth2client import client from oauth2client import tools from oauth2client.file import Storage import datetime try: import argparse flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args() except ImportError: flags = None # If modifying these scopes, delete your previously saved credentials # at ~/.credentials/calendar-python-quickstart.json SCOPES = 'https://www.googleapis.com/auth/calendar.readonly' CLIENT_SECRET_FILE = 'client_secret.json' APPLICATION_NAME = 'Google Calendar API Python Quickstart' def get_credentials(): """Gets valid user credentials from storage. If nothing has been stored, or if the stored credentials are invalid, the OAuth2 flow is completed to obtain the new credentials. Returns: Credentials, the obtained credential. """ home_dir = os.path.expanduser('~') credential_dir = os.path.join(home_dir, '.credentials') if not os.path.exists(credential_dir): os.makedirs(credential_dir) credential_path = os.path.join(credential_dir, 'calendar-python-quickstart.json') store = Storage(credential_path) credentials = store.get() if not credentials or credentials.invalid: flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES) flow.user_agent = APPLICATION_NAME if flags: credentials = tools.run_flow(flow, store, flags) else: # Needed only for compatibility with Python 2.6 credentials = tools.run(flow, store) print('Storing credentials to ' + credential_path) return credentials def main(): """Shows basic usage of the Google Calendar API. Creates a Google Calendar API service object and outputs a list of the next 10 events on the user's calendar. """ credentials = get_credentials() http = credentials.authorize(httplib2.Http()) service = discovery.build('calendar', 'v3', http=http) now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time print('Getting the upcoming 10 events') eventsResult = service.events().list( calendarId='primary', timeMin=now, maxResults=10, singleEvents=True, orderBy='startTime').execute() events = eventsResult.get('items', []) if not events: print('No upcoming events found.') for event in events: start = event['start'].get('dateTime', event['start'].get('date')) print(start, event['summary']) if __name__ == '__main__':
で保存し
cp ../ダウンロード/client_secret_354559203980-pd3t3vum75cc19ihvj6pgttqasf8npbd.apps.googleusercontent.com.json client_secret.json
でダウンロードしたファイルを
client_secret.json
として保存
あとは
python quickstart.py
を実行すればブラウザが立ち上がり認証画面になる
詳細をクリックし
Project Default Service Account(安全ではないページ)に移動
をクリック
許可をクリック
許可をクリック
これで ubuntu で
calendar-python-quickstart.json
が生成されるので
scp /home/snowpool/.credentials/calendar-python-quickstart.json pi@192.168.1.4:/home/pi/.credentials/
で
ラズパイ3のディレクトリにコピー
これでラズパイ3で再度
python get_gcal_schedule.py
を実行すれば
get_gcal_schedule.pyが正常に動作する
あとは予定の読み上げ
Raspberry PiでGoogle Calendarの予定を読み上げさせる
では
python get_gcal_schedule.py | aquestalkpi/AquestalkPi -f - | aplay #pythonの出力結果をaquestalkpiにパイプし、それをさらに、aplayにパイプ
で読み上げていた
aquestalkpi は個人で非営利なら無料らしい
オプションなどについては
それ、ラズパイでつくれるよ——日本語を喋らせる
を参考に
-f オプションで
読み上げるテキストファイルを指定している
sudo bluetoothctl connect 6C:56:97:3A:52:98
を実行し Amazon Echo へ接続
ctrl + d で抜けて
jtalk.sh
でファイルを作成し
#!/bin/bash tempfile=`tempfile` #option="-m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice \ option="-m /usr/share/hts-voice/mei/mei_normal.htsvoice \ -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow $tempfile" #echo "$1" | open_jtalk $option python get_gcal_schedule.py | open_jtalk $option #aplay -q $tempfile aplay -D bluealsa $tempfile rm $tempfile
として保存
./jtalk.sh
を実行すれば
予定があれば読み上げ
ないのなら
今日の予定はありません
と Amazon Echo で音声が流れるようになる