public note

リングフィットアドベンチャーの運動ログをほぼ自動的に収集・可視化する

目的は自己管理と習慣化

リングフィットアドベンチャーは、家にいながらにして運動ができるという素晴らしいゲームです。 ただ一点、個人的に気になっていることがあります。それは、運動ログがソフトウェア内に閉じていることです。 もし出力することができれば、過去の実績や継続日数を記録として残し、PCやスマホで可視化できます。これにより習慣化につながったり、「もしかして私、アームツイストばかりやってる...?」みたいなトレーニングの偏りに気づくことができるのではないかと考えました。

システム要件

そうしたことを考えて、要件として抽出した結果が以下です。気づけば仕事とやっていることが一緒

  • 運動ログをゲーム外に出力すること
  • 運動ログを時系列データとして蓄積すること
  • 運動ログをグラフや表などで可視化すること
  • 可視化の結果はインターネットでいつでも見れること
  • 原則として自動化し、最小の手数で行うこと
  • できる限り低コストで行うこと

完成図

できあがったものがこちらです。

f:id:ts223:20210415092436p:plain

ゲーム終了後に表示される「本日の運動結果」のスクリーンショットを、Nintendo Switchの機能を使ってTwitterへ投稿します。 それだけで、その日の運動ログを記録できるようにしました。 処理対象となるスクリーンショットは、この2種類です。

https://pbs.twimg.com/media/Ey2TyOCVgAI4oXl?format=jpg&name=large

https://pbs.twimg.com/media/Ey2TyOCVIAUdEUF?format=jpg&name=large

必要なもの

  • 決済可能なクレジットカード
  • そのクレジットカードを紐付けたGoogle Cloud Platform アカウント
  • Twitter 開発者アカウント
  • スケジューラ機能をもつGo実行環境
  • https://github.com/tosh223/rfa

運用コスト

運用コストは、画像の投稿頻度とデータの蓄積量に依存します。 プレイ頻度は多くても1日に数回だと思いますので、個人で使う分には何百年かは0円で運用できると思います。*1

グラフ

DataStudioを使用しています。BigQueryに保存された最新データを常に表示できるうえに、PC・スマートフォンなどから参照できて便利です。ダッシュボードへのリンクをスマートフォンに登録したり、毎日見るようなページに埋め込むのがおすすめです。Gmailへの定期通知も簡単にできますので、合わせて設定しておくと忘れにくくなると思います。

僕の場合は、Notionを毎日複数回見ますので、トップページに埋め込んで必ず視界に入るようにしています。

f:id:ts223:20210415001723p:plain

Goプログラム

どんなことをしているのか、簡単にご紹介します。

help

$ ./rfa --help
Usage of ./rfa:
  -l string
        bigquery_location (default "us")
  -p string
        gcp_project_id
  -s string
        search_size (default "1")
  -u string
        twitter_id

ツイート検索

以下の条件でツイートを検索しています。

  • 指定したtwitter_idのツイートであること
  • リツイートでないこと
  • #RingFitAdventure ハッシュタグがついていること
  • BigQueryに保存されている最新日時より後にツイートされていること
  • 画像が添付されていること

Twitter 開発者アカウントの認証キーは、下記 ini ファイルの[DEFAULT]セクションに保存している前提です。

$ cat $HOME/.twitter/config.ini

[DEFAULT]
CONSUMER_KEY = ****************
CONSUMER_SECRET = ****************
ACCESS_TOKEN = ****************
ACCESS_TOKEN_SECRET = ****************

画像内のテキスト解析

Cloud Vision APITEXT_DETECTION を使っています。抽出したツイートに添付されている画像が、上述の2種類であるかをチェックします。 具体的には、画像内に本日の運動結果という文字列が存在するかを判定条件にしています。

Trueである場合は解析結果を確認し、日本語としてあやしいものや特定の条件下で発生する読み取りミスを補正します。

解析結果の登録

BigQuery へのデータ登録は、CSVファイルを経由して行います。github.com/gocarina/gocsv を使用して、構造体に詰め込んだテキスト解析結果をCSVファイルとして出力しています。そしてこの構造体が、そのままBigQueryのテーブル定義になっています。 1枚目の画像と判定されたら Summary、2枚目の画像の場合は Details として出力されます。

type Summary struct {
    TwitterId            string        `json:"twitter_id" csv:"twitter_id"`
    CreatedAt            time.Time     `json:"created_at" csv:"created_at"`
    ImageUrl             string        `json:"image_url" csv:"image_url"`
    TotalTimeExcercising time.Duration `json:"total_time_excercising" csv:"total_time_excercising"`
    TotalCaloriesBurned  float64       `json:"total_calories_burned" csv:"total_calories_burned"`
    TotalDistanceRun     float64       `json:"total_distance_run" csv:"total_distance_run"`
}

type Details struct {
    TwitterId     string    `json:"twitter_id" csv:"twitter_id"`
    CreatedAt     time.Time `json:"created_at" csv:"created_at"`
    ImageUrl      string    `json:"image_url" csv:"image_url"`
    ExerciseName  string    `json:"exercise_name" csv:"exercise_name"`
    Quantity      int       `json:"quantity" csv:"quantity"`
    TotalQuantity int       `json:"total_quantity" csv:"total_quantity"`
}

これからやりたいこと

pixelaで草を生やす

習慣化という点では、いつ・どれだけやったのかをもっとわかりやすく表示する点で改善の余地があります。これは、pixelaを使って草を生やすのがよさそうなので、ぜひ使ってみたいなと思っています。

pixe.la

過去データ移行

僕がやりたいだけなのですが、以前からやっている人は過去データを移行したくなると思います。習慣化に失敗したあの日々も可視化して、今後の戒めとするのです。

GCP Secret Manager 対応

Twitter 開発者アカウントの認証キーの保存先として、GCP Secret Manager を選べるようにしようと思います。 そうすれば Goプログラムを Cloud Functions に引っ越せるので、GCPですべて完結させることができるためです。

英語対応

リングフィットアドベンチャーには英語版もありますので、英語表記のスクリーンショットにも対応中です。*2

風来のシレン5 Plus 対応

いきなり違うゲームの話になりましたが、とても大事なことです。同じ方法で、別のゲームにも応用できると思っています。長らくさぼっているシレンも、しっかりとこなしていきたいものです。

*1:電気代除く。執筆時点の料金で試算した結果です。

*2:韓国語版もあるっぽい