ログをとるために生きている

だって楽しいんだもん。

リングフィットアドベンチャーのフィットスキルログを収集する(iOSショートカットアプリとGASで)

リングフィットアドベンチャーをやっている人ならだれでも思うはず
「これまでの努力を集計してくれ!!!」
世の中にそういう系の記事がいっぱい出回ってるので、n番煎じで私もやってみた。

全体像

採用した案

とはいっても、今回のことに新しいプラットフォームを使う気にはなれず
普段から使っているもので賄った結果、半自動くらいのものになった。


SwitchからTwitterに画像投稿。
iPhoneTwitterを開いて、画像の共有マークからショートカットを実行。
切り取られた画像がファイルに保存されるので、それを手動でGoogleドライブに保存。
あとは定期実行しているGoogleスプレッドシートのApps Scriptで処理してくれる。

画像切り取りはこんな感じで、フィットスキル名と値でそれぞれ切り取る。

フィットスキル名
フィットスキルの値

却下した案

今後の参考のために却下した案も書いておく。

画像を行ごとに切り取り or 画像を切り取らず Googleドライブにアップロード

今回採用した列切り取り以外にも、行切り取り、切り取り無しの計3パターン全部やってみた。

精度が一番いいのは行切り取り。
ただし問題は、ショートカット実行時に読み込む画像のログ行数を指定しないといけない点。

これ何行かぱっと見でわかりますか?

これは?

答えは上が12行、下が11行。

数えるたびにイラッとするのでやめた。
ちなみに画像枚数も増えるので、GASの処理も時間がかかってしまうデメリットもあった。


切り取りなしは一番手間がかからないし、切り取りがない分将来的にGoogleドライブへのアップロードも自動化できるかもしれない。
けど、読み取った後の加工が難しい・・・。
綺麗に列ごとまたは行ごとにテキストになってくれればいいんだけど

読み取り順序の理想(行ごと)
読み取り順序の理想(列ごと)

実際には結構な頻度でランダムな読み取りになる。

実際の読み取り順序

こうなってくると、フィットスキル名と値をセットで書き出すのが大変になっちゃうので却下。

ちなみに画像読み取りの結果はGASを書かなくても、Googleドライブで画像ファイルを右クリックして、Googleドキュメントで開くと確認できる。
これを知らずに、最初からGASで書いて「出来上がった!実行するぞ!」という段になって読み取り順序がめちゃめちゃなことに気付いた。
サンプルで何個か読み取りの状況を確認しておくべきだった。

make(旧Integromat)でTwitter監視して、Googleドライブに写真を保存。

make上でGoogleドライブにアップロードするには、Googleアカウントが個人用じゃダメらしい。
認証の段階でエラーになってしまった。

iPhoneのショートカットアプリで、テキスト抽出を利用してNumbersに書き込み

iPhoneで完結したら面白いかなと思ったんだけど、1枚の情報量が増える(画像の文字が小さくなる)につれてテキストの認識の精度が下がってしまい、使い物にならなかった。
精度が上がってくれば、ノーコードでできる可能性があるのは良いよね。

こっちの画像のログを収集するだけなら、字も大きいしいけるかも(やってない)。

それ以外にも何かに使えそうな可能性だけは感じる仕組みだった。
一度別の記事にまとめておきたいなぁ。

仕組みの詳細1 ショートカットアプリで画像切り取り

全体像


導入


たまにTwitter投稿忘れることがあるので、RFAをした日付はその都度指定する作りにした。
画像の列数によって切り取り位置が変わるので、列数は自分で選択する。
(行数を選択するよりずっとマシ)

列ごとに定数を定義

列数ごとに、画像切り取り位置を書き出している。

各項目の値が示している箇所は画像のとおり。
実際に作ってる時に混乱してたから、先にこうやってまとめておけば良かった。

選択した列数の定数を取得

このセクションが必要になっちゃうのが、普通のコードで書くプログラミングと違うところなのかな。

メニューで選択した結果として対応する列数の辞書が出力されるんだけど、実際にその値を使うには事前に変数として取り出しておく必要がある模様。
使う時に辞書の値を直接参照することが出来たら楽なんだけどな。
作る時はちょっとめんどい。

画像切り取り(列数分繰り返し)

ここまで来たら実際に画像を切り取ってファイルに保存するだけ。

RFAをした日付と何列目かをファイル名に入れておいて、このあとのGASの処理に利用している。
Googleドライブに直接保存出来たら嬉しいんだけど、そうはいかなかった。

仕組みの詳細2  GASで画像読み取り

Googleスプレッドシート上での処理

スプレッドシートの出力

GASで日付とフィットスキル名と値を書き込み。
この時点では値に「回」や「秒」などの単位が入っているので、計算式を使ってカット。
「回」が「@」や「0」に誤読み取りされることが多いけど、単純に「(」前の一文字から後をカットしてるので影響しない。
画像ファイル名と処理日時は、エラーが出た時の原因確認用に出力。


Apps Scriptでの処理

画像ファイルをコピーすることでOCR処理できるので、
コピー→OCRした結果を微修正→名前と値をそれぞれ1つずつ配列に入れる→順番に取り出してスプシに書き込み
という感じ。

画像ファイル名はショートカット側で以下で統一している。
「YYYY-MM-DD- フィットスキル-列番号-名前.png
「YYYY-MM-DD- フィットスキル-列番号-値.png

たとえば画像が2列あったら、以下の4つのファイルが存在していて、列番号が同じものがペア。
「2023-03-05-フィットスキル-1-名前.png
「2023-03-05-フィットスキル-1-値.png
「2023-03-05-フィットスキル-2-名前.png
「2023-03-05-フィットスキル-2-値.png


とりあえずこれで動く。
列数の処理の順番とかなんか微妙なところもある気がする。


別のスクリプトも同じスプレッドシート内にあるので、フォルダIDなどの共通の変数は別ファイルにまとめて書き出してある。

//全ファイル共通の定義
  // 画像を保存しているフォルダのID
    const folderId = "xxxxxx";
  // 画像を保存しているフォルダ
    const folder = DriveApp.getFolderById(folderId);
  // 書き込み先のスプレッドシートのID
    const ssId = 'yyyyyy';
  // 書き込み先のシートの名前
    const shName = 'zzzzzz';
  // 書き込み先のシート
    const sh = SpreadsheetApp.openById(ssId).getSheetByName(shName);

活用方法

スプレッドシート内で集計結果をグラフ化して、その画像を公開している。
毎朝実行するショートカットアプリでグラフ画像を写真に保存して確認することで、RFAのことを忘れないようにしていきたい。

↓実際に公開しているグラフ。



作ってみて

OCR処理は作った後実際に使ってみて微調整するのが大変そう。
しばらく様子見する。

番外編

楽しくて直近の画像以外も全部処理したくなった。
SwitchとPCを繋げば、一括で画像をダウンロードできる。
これにはプレイ中のスクショなどログ以外のものも含まれるので、これをショートカットアプリで分類した。
この分類に使ったショートカットは他にも色々応用がききそうなので、今度まとめておきたい。

追記:まとめた
engineer-rumpop.hatenadiary.com

参考にしたサイト

今回は後で自分が見返した時になんなのかわかるように、コメント丁寧に入れて変数の名前とかも気をつかいたかったので、その時に大変参考になりました。
tonari-it.com

JavaScriptってuniq的なのないんですね。こちらの記事に載っているものをそのまま使わせていただきました。
qiita.com