【Python】睡眠時間をtogglに自動で記録する

eyecatch-【Python】睡眠時間をtogglに自動で記録する

Pythonを使って、togglに睡眠時間を自動で書きだすプログラムをつくります。

概要

自由な時間やゆっくりできる時間を絞り出すためにタスク管理ツールをいくつか使っています。メインツールとしてTickTickなどをつかって、完了したタスクの内容は把握しています。一方で、それぞれにどれだけ時間を費やしたかInput量が見えづらいことに気付きました。
Inputが見えずらい点に関して、togglというツールを使うとストップウォッチのように手軽に時間を測りながら、やった作業内容をクイックに記録できます。APIもあるので、自動でデータを蓄積することもできます。加えて、CSV出力機能もついているので、データをためて分析するところまで手軽にできることになります。
手始めに、スマートウォッチに蓄積されている睡眠時間を自動でtogglに登録する処理を書き、APIに少しずつ慣れていきます。

Inputデータ

スマートウォッチはGarminのVenu 2を使います。

GarminはOfficialなAPIは公開されていませんが、APIを叩けるライブラリは存在します。これを使って、睡眠ログを取得して、toggl API用にデータを変換します。今回はGarminのウォッチを使いますが、FitbitであればOfficialなAPIもあります。

他社製品なので、APIからのReturnは異なりますが睡眠の記録を取得できます。睡眠時間の記録に関しては、データ取得さえできればほかのウォッチでも良いと思われます。

また、データを変えれば睡眠に限らずにいろいろなデータを流し込めるので、他のAPIで運動時間など人の作業を記録したり、他に何か人に限らずとも時間を記録する用途で使うのも面白いかもしれません。

コーディング

今回書いたコードのRepositoryは以下のURLです。
https://github.com/rmc8/Tool-for-transcribing-sleep-records-to-toggl

Main

メインの処理はmain.pyに書きました。YAML形式のファイルやコマンドラインから設定を引き取りプログラムを実行します。

コマンドラインは以下のような構成です。

python main.py {さかのぼる日付数}

コマンドラインでさかのぼる日数に1と入力すると、プログラム実行日から前日の範囲、30と入力すると同様に30日前までの範囲の睡眠記録をまとめて取得を試みます。引数を省略すると当日分のみを取得を試みます。日数指定できないのは不便な気もしますが、タスクスケジューラーで自動的に登録しておしまいにしたいので、かなり簡素化しています。

YAMLファイルは以下の通りです。

time_zone: 9  
toggl:  
  token: # Required  
  time_entry:  
  workspace_id:  
  project_id:  
  task_id:  
  billable: False # Not required  
  tags:  
  - 睡眠  
garmin:  
  email: # Required  
  password: # Required

YAMLの読み込みはutil.pyでPyYAMLを使って実装しています。YAMLファイルを辞書形式で読み込める便利なライブラリです。この設定ファイルの内容はすべてAPIに流し込む値とです。time_zoneはUTC基準でどれだけ時差があるかを入力します。その他は、後述で説明します。

その後、GarminのAPIから睡眠時間を取得し、toggl用にデータを変換してAPIを通じてtogglに睡眠時間を登録する作業をします。その後、togglAPIからのResponseを、./outputにcsv形式で出力します。

Garmin API

https://github.com/rmc8/Tool-for-transcribing-sleep-records-to-toggl/blob/main/pkg/garmin.py

Garminからのデータ取得は、冒頭の通り非公式のライブラリを使います。そのため、リポジトリのREADMEやソースコード、デベロッパ―ツールを使った解析以外にデータの取得の手掛かりはありません。ソースコードを読むと、EndpointやPOST内容などもわかりますが、今回は割愛します。

APIへの接続

class GarminAPI:  
	def __init__(self, email: str, password: str, time_deff: int = 9):  
		self.client = Garmin(email, password)  
		self.client.login()  
		self.time_deff: int = time_deff

GarminAPIクラスを呼び出しと同時に、APIに接続します。認証はGarmin Connectのユーザー情報と同じです。メールアドレスとパスワードをconfig.ymlに記載します。Garmin APIからのReturnがUTC(GMT)なので、時差調整できるように一応time_deffを加えました。

睡眠ログの取得

get_sleep_logsメソッドを使ってまとめて睡眠情報を取得します。カプセル化により隠蔽されていますが、garminconnectライブラリで用意されているget_sleep_dataメソッドを使うとサクッと睡眠時間を含んだJSONを取得できます。
そのJSONのdailySleepDTOの値に、就寝時間と起床時間をエポック秒(GMT)形式で格納されています。これを、Pythonのdatetimeの形に変換して、時差を調整する作業を以下で行っています。

@staticmethod
def epoc2date(epoc: int, time_deff: int):
	dt = datetime.fromtimestamp(epoc / 1000)
	return dt + timedelta(hours=time_deff)


start = self.epoc2date(display["sleepStartTimestampGMT"], self.time_deff)
end = self.epoc2date(display["sleepEndTimestampGMT"], self.time_deff)

その後、toggl用にデータを変換しています。辞書の内容は以下の通りです。

Key

Value

Description

date

寝た日

使わないけど参考程度に

description

説明

ここではいつ寝たか説明文として書いています。
今回はTitleと思っていただいて大丈夫そうです。

start

開始時間

ここでは就寝時間がこれにあたります。

stop

終了時間

ここでは起床時間がこれにあたります。

duration

経過時間

どれぐらいの時間が経過したか秒数で書きます。

durationはtogglの公式ドキュメントで小難しい説明がされていますが、下図の黄色マーカーの箇所の表示に使われます。


マイナスもあり得るとよくわからないことも書いてありますが、これをうまく使うと睡眠時間の間に眠れず起きていた時間を差し引いた時間を埋め込むような使い方もできます。その他は特にトリッキーなものではないので一旦省略します。

すべての日付をさかのぼり睡眠時間などをまとめたデータが完成したら、Pandasのデータフレーム形式に変換してmain.pyに返します。

toggl API

https://github.com/rmc8/Tool-for-transcribing-sleep-records-to-toggl/blob/main/pkg/toggl.py

toggl APIはGitHubにまとめられています。Pythonのクライアントもあるようですが、PyPIから取得できず使い方もソースコード読まないとわからない気がしたので、ドキュメントをもとに必要な処理だけ自前で書きました。

APIの認証にはトークンを使います。Profileページの下方にトークンがあります。これを、config.ymlのtoggl > tokenに記載します。その他、toggl > time_entry内の3種類のIDは特定の場所に記録したい場合に記載します。billableは睡眠が直接利益を生み出すわけでもないので、基本的にはFalseで良いでしょう。その他、tagsはリスト形式でタグを複数設定できます。一旦のところ、- 睡眠で一つだけタグを設定しています。

toggleに記録する

create_time_entryメソッドを使うと、togglに睡眠時間を記録します。必須の値を中心に引数で引き取り、その他はキーワード引数とアンパックを使って必要に応じて追加できるようにしています。
stopは必須ではないですが、duration周りがトリッキーでstopがないと終了時間がずれがちなので、時間を明示できるように入れました。

その後、ドキュメントに従ったJSON Payloadっぽいものが生成されるので、これを_requestメソッドに投げ込み、API経由でまとめて睡眠時間を登録します。

ログ出力

./outputディレクトリにAPIの結果をCSV形式で出力します。サンプルは以下の通りです。

id,wid,billable,start,stop,duration,description,tags,duronly,at,uid
2xxxxxxxxx,5xxxxxxxx,False,2021-09-25T23:46:00.000+09:00,2021-09-26T06:56:00.000+09:00,25800,Sleep time on 2021-09-25,['睡眠'],False,2021-09-26T08:59:03+00:00,7xxxxxxxx

今後の応用

睡眠時間を自動で登録することはできました。これと同じように、スマートウォッチやIoTの活用で自動登録できるものは、まず自動登録を進めたいです。

TickTickはGASやらIFTTTやら連携させつつ、重要なタスクは手動で登録させたりなどして、やることをまとめています。これをAPIで取得して、やっているタスクを選びストップウォッチを(
起動・停止)・(完了・未完)の制御ができると、InputとOutputの管理がしやすくなりそうです。

その他、APIが使えない部分はアプリの機能がとてもシンプルなのでそれをそのまま使えばだいぶタスクの管理や分析が楽になりそうです。

普通にtogglアプリを使う以外はまだまだコーディングが必要ですが、ありあわせのものを再利用しつつAPIで連携でき、しかもクラウドですべての端末で情報共有もできます。個人利用なら無料で使えて必要十分以上の機能なのでとてもありがたいです。

まとめ

時間を管理し分析するプラットフォームとしてtogglはとても良いです。日本語の対応はまだまだですが、英語にアレルギーがなければ非常に有用で拡張性の高いツールだと思います。ぜひ、色々なIoT機器やAPIなどと組み合わせて遊んでみてください。