PixelaでIIJmioのデータ残量を可視化する

この記事は、[ラクス Advent Calendar 2022](https://qiita.com/advent-calendar/2022/rakus) の20日目です。昨日は、 @rs_tukki の [WSLでKaliLinuxを構築してみる【2022年度最新版】](https://qiita.com/rs_tukki/items/dc38b6efed5938f82a80) でした。今年もいよいよ大詰めですね :christmas_tree: 

## 背景

家族のスマホ用に [IIJmio](https://www.iijmio.jp/) の回線をいくつか契約しています。ただ、契約を一元化しているため、ID/PASSを共有しないと私以外がデータ残量を確認できないというちょっとした不便さを抱えていました。特に困ってはいなかったので放っておいたのですが、先日Wi-FiがOFFになっていたのか急激にギガが減っているトラブルがあり、これはちょうどいいネタだということで今日にいたります。

この記事では、IIJmioが公開しているAPIを使ってSIMのデータ残量を取得し、[Pixela](https://pixe.la/) を使って可視化することで、IIJmioにログインしなくてもデータ残量を確認できるようにすることを目指します[^1]。

[^1]: そもそも可視化ではなく、残量を監視してしきい値を超えたら通知してほしいというツッコミは…（略

## IIJmioからデータ残量を取得する

[IIJmioクーポンスイッチAPI](https://www.iijmio.jp/hdd/coupon/mioponapi.html) を使って、データ残量を取得します。利用方法はすでに先人の分かりやすい記事があるので、そちらを参考にしてください。

https://xyk.hatenablog.com/entry/2014/01/15/191856

1. デベロッパIDの取得
    * デベロッパコンソールにログインして、デベロッパIDを取得
1. アプリの登録
    * 同じくデベロッパコンソールで、APIを利用するアプリとコールバックURLを登録
1. アクセストークンの取得
    * OAuthのImplicit Grant Flowでアクセストークンを取得
1. データ残量の取得
    ```sh
    $ curl https://api.iijmio.jp/mobile/d/v2/coupon/ \
          -H 'X-IIJmio-Developer: <DEVELOPER_ID>' \
          -H 'X-IIJmio-Authorization: <API_TOKEN>'
    ```

:::note warn
注意：実際には、レスポンスJSONに（回線, 月）ごとの利用可能データ量が含まれているため、 `jq` コマンドなどでいい感じに抽出してやる必要があります。

```sh
$ echo ${RESULT}
{
  "returnCode": "OK",
  "couponInfo": [
    {
      "hddServiceCode": "hdc12345678",
      "coupon": [
        {
          "volume": 640,
          "expire": "202212",
          "type": "bundle"
        },
        {
          "volume": 3000,
          "expire": "202301",
          "type": "bundle"
        },
    ...
$ echo ${RESULT} | jq '[.couponInfo[0].coupon[].volume] | add'
3640
``` 
:::


## Pixelaを使って可視化する

次に、データを可視化するためのPixelaを準備していきます。Pixelaは、GitHubでおなじみの草が生えていくグラフを、APIを使って簡単に作成できるWebサービスです。

https://pixe.la/

1. [アカウントの作成](https://docs.pixe.la/entry/post-user)
    * Pixelaは、アカウント発行自体もAPI経由で実施します（トークン文字列はこちらが指定）。おもしろいですね
    ```sh
    $ curl -X POST https://pixe.la/v1/users \
           -d '{"token":"<TOKEN>", "username":"oohira", "agreeTermsOfService":"yes", "notMinor":"yes"}'
    ``` 
1. [グラフの新規作成](https://docs.pixe.la/entry/post-graph)
    * グラフ名のほかに色や単位などを指定します。色が和名（`shibafu` や `momiji`、`ichou`など）になっているのが粋です
    ```sh
    $ curl -X POST https://pixe.la/v1/users/oohira/graphs \
           -H 'X-USER-TOKEN: <TOKEN>' \
           -d '{"id":"available-giga","name":"available-giga","unit":"MB","type":"int","color":"shibafu","timezone":"Asia/Tokyo"}'
    $ open https://pixe.la/v1/users/oohira/graphs/available-giga
    ```
1. [データのプロット](https://docs.pixe.la/entry/post-pixel)
    * 日付と値を含むJSONを送信するだけでその日のデータを簡単にプロットできます。
    ```sh
    $ curl -X POST https://pixe.la/v1/users/oohira/graphs/available-giga \  
           -H 'X-USER-TOKEN: <TOKEN>' \
           -d '{"date":"20221220","quantity":"3640"}'
    ```

:::note warn
注意：これもおもしろいのですが、Pixelaは無料ユーザーだと一部のAPIが25%の割合で失敗します。データプロットしようとして、`isRejected: true` が返ってきた場合は、リトライする必要があるので注意してください。
```json
{
  "message":"Please retry this request. Your request for some APIs will be rejected 25% of the time because you are not a Pixela supporter. If you are interested in being a Pixela supporter, please see: https://github.com/a-know/Pixela/wiki/How-to-support-Pixela-by-Patreon-%EF%BC%8F-Use-Limited-Features",
  "isSuccess":false,
  "isRejected":true
}
```
:::

というわけで、GitHub ActionsなりGitLab CIなりcronなりを使って、日次でIIJmioのデータ残量取得 → Pixelaへのプロットを繰り返すと、こんな感じで草が生えていきます。

* [oohira/available-giga | Pixela](https://pixe.la/v1/users/oohira/graphs/available-giga.html)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33668/c1d5967e-01e3-9f1d-2468-11fad5f25883.png)

たしかに11/24あたりにデータ残量ががくっと減って、12月に入るとギガが回復しているのが折れ線グラフから分かります。が、草の方はデータ残量を可視化するにはイマイチかもしれないですね。コミットやランニング、読書など、やれた日／やれなかった日がはっきり出るような活動の方がマッチしそうです。

## 補足：歩数も可視化してみる

データ残量の可視化が思ったよりインパクトないぞ？ということに焦って、データポイント数が多そうなものも可視化してみます。1年分のデータが溜まっていそうなものということで、iPhoneのヘルスケアデータを書き出し、歩数を抽出してグラフ化します。なお、ヘルスケアデータを抽出するWeb APIは提供されていないので、以下のグラフはリアルタイムに更新されません。

* [oohira/walking | Pixela](https://pixe.la/v1/users/oohira/graphs/walking.html)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33668/169b8a4c-74cf-0a01-220b-a2f9570a9bae.png)

8月の活動量が減っているのが分かりやすく表れていますが、それ以外はそこまででもないでしょうか。よく言われる1日1万歩にAvgが届いていないぞとか、とは言っても今年Total 280万歩も歩いていてチリツモだなとか。

:::note warn
注意：iPhoneのヘルスケアアプリから歩数を抽出する方法はここでは説明しません。必要な場合は、Webの情報を参考にしてください。エクスポートしたデータはXMLファイルなので、以下のような行を抽出して日付単位で自分で集計してやる必要がある、という点だけお伝えしておきます。面倒…
```xml
 <Record type="HKQuantityTypeIdentifierStepCount" sourceName="iPhone" ...  unit="count" creationDate="2022-12-17 22:08:16 +0900" startDate="2022-12-17 21:52:40 +0900" endDate="2022-12-17 21:52:50 +0900" value="18"/>
```
:::

## まとめ

この記事では、PixelaとIIJmioのAPIを使ってスマホのデータ残量を可視化する方法を紹介しました。こうやってAPIを提供してもらえるのは非常にありがたいですね。特に、Pixelaは今回紹介したAPI以外にも、

* API呼び出しのたびにカウントを+1する `/increment` API
* 1回目と2回目のAPI呼び出しまでの時間を計測する `/stopwatch` API
 
などもあり、工夫次第で色々な時系列データを見える化できる可能性を感じられたので、自分の道具箱に加えておきたいなと思いました。

## 参考情報

* [Pixela API Document](https://docs.pixe.la/)
* [IIJmioクーポンスイッチAPI](https://www.iijmio.jp/hdd/coupon/mioponapi.html)