SACとiPhoneで自分の行動記録を自動レポーティングしてみた

この記事は <a href="https://qiita.com/tags/chillsap">#chillSAP</a> <a href="https://note.com/chillsap/n/n62740563aee0">夏の自由研究2022</a>、8/26の記事として執筆しています。
 
## 夏休みということで、志賀高原に旅行に行きました。
![IMG-4021.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782616/fa6be570-c342-9f48-b00c-b8986af40e5c.jpeg)
8月の志賀高原。このような湿地や池が多く見られ、高原のため涼しいので、歩いているとかなり気持ちいいです。
散歩をしていてふと、自分の歩いた記録を残して後から見たいなと思い、表題のものを作るに至りました。(散歩しながらiPhoneで作っていたら池に落ちそうになったのは内緒です)
最近は便利なスマホアプリも存在してそうですが、いいんです、SACの練習なので(笑)。SACを使うことが目的です。
## つくったもの
SAP Analytics CloudのTrial環境を用いてこのようなレポートを作りました。志賀高原で自分が歩いたルートが可視化できました！
（位置情報送信の頻度をもっと上げれば、もう少しなめらかなルートになります）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782616/47751689-e31a-6eaa-bfcf-3a43f0235062.png)
特長は、次になります。
* 自分のiPhoneから定期的に飛ばした位置情報や歩数のデータを可視化していること
* データソースとはLive接続していないものの、importをスケジューリングすることで、ほぼリアルタイムでデータが更新されること

## しくみ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782616/bec71ed1-4b2e-d6d9-a916-401d12e06871.png)

今回は手軽さからGoogleスプレッドシートをデータソースとしました。データの書き込みもGoogle App Scriptを使うことで簡単に行えます。

1. iPhoneのショートカット機能を利用して、位置情報や歩数のデータを持たせたPOSTリクエストをGASに送信します。なお、iPhoneのオートメーション機能を用いて、定期的に自動送信されるようにしておきます。
2. GASはリクエストを受け取ると、Googleスプレッドシートにデータを書き込み、同時にiPhoneに結果をレスポンスします。
3. SAC上には、Googleスプレッドシートをデータソースとしたモデルを構築しており、そのモデル上にSACにおけるレポート機能であるストーリーが作られています。SACは、スケジューリングに従って定期的にGoogleスプレッドシートのデータをモデルにimportし、ストーリーを自動更新します。

## つくりかた
### Googleスプレッドシート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782616/a759a5c1-ee3a-edda-c69e-8be9f5d00c24.png)

このようなフォーマットで用意しました。
タイムスタンプ、緯度経度、歩数がGASにより書き込まれます。残りの列は関数で導出させるようにしています。

### SAC
##### 1. モデルの構築
Googleスプレッドシートのデータをimportしモデルを構築します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782616/0c6f731f-a021-e828-4e02-e79d785a124d.png)
SACでは、Googleアカウントと接続し、Googleドライブのデータをデータソースとして選択できます。
詳細は割愛しますが、今回は緯度経度を用いて地図に表示させたいので、Location Dimensionを作っておきます。

モデルを生成したら、データを定期的に自動importさせるために、Data managementワークスペースでimportのスケジューリングを設定します。
毎時のデータ更新が、最も頻度の高いオプションのようですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782616/f0ff1979-f1a8-d5cf-cdd8-ced9b2822204.png)

##### 2. ストーリーの作成
作成したモデルを基に、ストーリー機能を使ってレポートを作成します。
やはり地図をトップに持ってきたい！ということでGeomapを追加します。今回は行動履歴を軌跡として可視化したいため、Flowレイヤを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782616/38c3bc15-598e-deec-b893-c1062c4a5661.png)
他にも、色々とグラフやインジケータを置いてみました。
5k歩や20k歩をマイルストーンとして、しきい値や基準線を引いてみました。二万歩は遠いですね…泣
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782616/07171735-e24e-b867-2c1e-1b150fadbf65.png)


### GAS
下記のようにコーディングしてデプロイしました。
こちらの記事を参考にさせて頂きました！！

https://yumanoblog.com/iphone-gas-spreadsheet/

コードの内容としては、POSTリクエストをトリガに作動するdoPost関数が、JSON形式で送信されてきたデータを整形してあらかじめ作成しておいたGoogleスプレッドシートに書き込んでいくというものです。
デプロイ時のWebapp urlは、iPhoneからPOSTリクエストを送る際に必要ですので控えておきます。
```javascript:
function doPost(e) {
  // iPhone（ショートカット）から送られてきた位置情報を取得
  let params = JSON.parse(e.postData.getDataAsString());
  let longitudeData = params.location.longitude;
  let latitudeData = params.location.latitude;
  let walkcountData = params.walkcount.walkcount;
  // ショートカットに返すメッセージを格納する為の変数
  let result = {};
  let output = ContentService.createTextOutput();
  output.setMimeType(ContentService.MimeType.JSON);

  // 位置情報が問題なく送られてきてるかの判定
  if (longitudeData){
    result = {
      "success" : {
        "message" : "スプレッドシートへの記録が完了しました"
      }
    };
    // 位置情報があればスプレッドシートへ記録する
    addLog( JSON.stringify({longitude: longitudeData,latitude:latitudeData,walkcount: walkcountData}) );
  } else {
    result = {
      "error": {
        "message": "データがありません"
      }
    };
  }

  // ショートカットにメッセージを返す
  output.setContent(JSON.stringify(result));
  return output;
}

function addLog(text) {
  // 記録するスプレッドシートを指定
  let spreadsheetId = "xxxxxxxxxxxxxxxxx"; // スプレッドシートID
  let sheetName     = "xxxxxxx"; // スプレッドシート名
  let spreadsheet   = SpreadsheetApp.openById(spreadsheetId);
  let sheet         = spreadsheet.getSheetByName(sheetName);
  // ショートカットから送信された位置情報をスプレッドシートに記録
  let info = JSON.parse(text)
  let today = new Date()
  sheet.appendRow([Utilities.formatDate(today,'JST','yyyy-MM-dd HH:mm:ss'),info.longitude,info.latitude,info.walkcount]);
  let lastRow = sheet.getLastRow();
  let copyRange = sheet.getRange(lastRow - 1, 5, 1, 20);
  let pasteRange = sheet.getRange(lastRow   , 5, 1, 20);
  copyRange.copyTo(pasteRange);
  let range = sheet.getDataRange();
  range.setHorizontalAlignment("left"); // 文字を左揃えに統一
}
```
### iPhone

iPhoneのショートカット機能を利用して、GASにデータを送信します。
ショートカットの内容は以下です。GPSから位置情報を、ヘルスケアアプリから歩数のデータを取得し、先ほど作成したGASのWebアプリに送信しています。かなり直感的に作成することが出来ました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782616/8267ed24-eff5-9a5f-17a3-23330592300a.png)
なお、iPhoneのオートメーション機能を利用すると、設定した時刻にショートカットを自動実行させることが出来ます。今回は15分間隔で実行するように設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782616/4dd447b0-2cde-36f2-ec4a-6212c22923f0.png)

## まとめ
・SACのストーリー機能を用いることで、見やすくキレイなレポートを直感的かつ簡単に作成できる。
・SACはGoogle Drive含め多様なデータソースと接続させることが可能
・Live接続を行わなくてもimport接続で定期importをスケジュールすることで、ある程度リアルタイムなデータ更新が可能
・身近なデータを収集するにはiPhoneのショートカット機能が便利

良い夏休みとなりました。それでは。