Morning Girl

Web API, Windows, C#, .NET, Dynamics 365/CRM etc..

Tesla API のデータをリアルタイムで可視化:Azure LogicApps & Power BI ストリーミングデータセット

f:id:sugimomoto:20201130205742p:plain

先日開催された .NET ラボで Tesla APIのセッションを行ったのですが、その中で Tesla API のデータをリアルタイムで分析するセッションが好評でした!

dotnetlab.connpass.com

以下のツイートでも動画を公開しています。

内部的には Azure のローコードサービス・iPaaS である LogicAppsと BIツール・Power BI を利用しているので、特に難しい処理は意識せず実現できるようになっています。

というわけで、この記事ではその作り方を紹介します!

ちなみに Web API アドベントカレンダー1日目の記事です!

qiita.com

なぜこんなことをしたの?

f:id:sugimomoto:20201130210229p:plain

Tesla API では、取得できるデータの中に「車両の現時点」のデータ、例えば速度やパワー・シフトレバーの状態・緯度・経度といった情報が含まれています。

これらの情報が APIリクエストを行ったタイミングの情報が取得できるのですが、果たしてどのくらいリアルタイムに取得できるものなのかとても気になっていました。(Teslaもどのくらいリアルタイムでデータを集めてるんだろう? みたいなところも含めて)

もちろんひたすらAPIを叩くこともできるのですが、運転しながら実際に可視化することで、そのリアルタイム性を体感してみようという、のが目的です。

必要なもの

Tesla APIカスタムコネクタはあっても無くても大丈夫ですが、あるとやりやすいと思います。

Tesla 本体はこちらから入手できます。 :)

どうやってやるの?

Microsoftが提供する BIツール Power BI にはIoTなどのデータを取得してリアルタイムで可視化するためのストリーミングデータセットという仕組みがあります。

docs.microsoft.com

f:id:sugimomoto:20201130204747p:plain

ストリーミングデータセットは、構成すると自動的にデータを取り込むためのAPIエンドポイントが構成されるのでここにひたすらTeslaAPIから取得したデータをPOSTしていくというシンプルなものです。

f:id:sugimomoto:20201130204758p:plain

このAPIエンドポイントに対して、LogicAppsを使って毎秒毎に取得したTeslaのデータをリクエストしていく、という仕組みになります。

Power BI ストリーミングデータセットの作成

まず最初に Power BIのストリーミングデータセットを構成しましょう。

https://docs.microsoft.com/ja-jp/power-bi/connect-data/service-real-time-streaming

Power BIサービスの画面にログインして、任意のワークスペースを選択し「ストリーミング データセット」を作成します。

f:id:sugimomoto:20201130204805p:plain

ストリーミングデータセットは3種類のアプローチがありますが、今回はAPI経由でリクエストするので、一番左のAPIを選択して、次へ進みます。

f:id:sugimomoto:20201130204811p:plain

次の画面ではデータセット名と取得する対象のデータ項目を定義します。

f:id:sugimomoto:20201130204816p:plain

ここで、Teslaから流し込むデータの項目と、分析軸となるTimestampなどを定義します。

私は今回以下のように項目を定義しました。

f:id:sugimomoto:20201130204821p:plain

ちなみにMaxとMinは速度メーターを表示するための固定値を突っ込むために構成しています。

最終的にリクエストする際のJSONフォーマットは以下のようになります。

[
    {
        "battery_level": 98.6,
        "latitude": 98.6,
        "longitude": 98.6,
        "power": 98.6,
        "speed": 98.6,
        "timestamp": "2020-11-30T11:06:07.624Z",
        "max": 98.6,
        "min": 98.6,
        "shift": "AAAAA555555"
    }
]

なお履歴データを元にレポート形式でビジュアライズする場合は「履歴データの解析」をチェックする必要があります。

構成が完了すると、リクエストするためのURLが表示されるので、これを使ってLogicAppsを構成します。

f:id:sugimomoto:20201130204828p:plain

Power BI ダッシュボードの構成

次に取得したストリーミングデータを表示する Power BI ダッシュボードを構成します。

できることがそんなに多いわけではないので、このあたりは実際にデータを流しながら、微調整していくのがおすすめです。

f:id:sugimomoto:20201130204837p:plain

私が勉強会で公開したグラフは以下のようなものになっています。

https://cdatajbuilds.s3-ap-northeast-1.amazonaws.com/sugimototest/tesla.gif

左の棒グラフや線グラフは「軸:timestamp」「値:speed」で、表示する時間枠を「最後:1分」にしています。1秒間隔のデータをリアルタイムで見たいときには、この設定がいいみたいです。

f:id:sugimomoto:20201130204842p:plain

スピードゲージは固定値のminとmaxを与えることで、振り幅の大きさを制御できます。動画では、minが0、maxは80を指定していました。

f:id:sugimomoto:20201130204847p:plain

シフトレバーの状態を示すグラフは1秒間隔のグラフにして、常に最新のシフトが表示されるようにしました。軸にはShiftを指定して、値はデータが入っているものであれば、なんでもいい感じです。

動画ではわかりづらいですが、P・R・N・Dでちゃんとカラーリングが切り替わります。

f:id:sugimomoto:20201130204853p:plain

LogicApps の作成

続いてLogicAppsを構成します。

全体像はこんな感じになっています。

NO 概要 コネクタ・アクション
1 スケジュール起動 スケジュールトリガー
2 Tesla Vehicle Data の取得 Tesla API カスタムコネクタ:Vehicle Dataアクション
3 現在時刻の取得 現在の時刻アクション
4 選択:リクエストデータの構成 選択アクション
5 Power BI へのリクエス HTTPアクション

f:id:sugimomoto:20201130204859p:plain

前述の通り、今回はTesla APIを使うにあたって、Tesla APIのカスタムコネクタを利用しています。カスタムコネクタの利用方法については下記Blogを参考にしてみてください。

https://kageura.hatenadiary.jp/entry/teslacustomconnector

f:id:sugimomoto:20201130204905p:plain

最初はスケジュールトリガーです。シンプルに1秒に1回起動する設定です。ただし、テストする際には、有効化する必要があるので、そのまま失敗してしまう恐れがあります。実際にフローが出来上がってから、1秒に1回の頻度にすると良いでしょう。(私も大変なことになりました)

f:id:sugimomoto:20201130204909p:plain

続いてTesla から車両の現在情報を取得します。Vehicle Dataアクションで対象の車両IDを指定することで取得できます。なお、項目がものすごく多いので、予め接続テストを行って、あたりを付けておくことがおすすめです。

f:id:sugimomoto:20201130204915p:plain

次に Power BIの分析軸として利用する時刻情報を取得します。

f:id:sugimomoto:20201130204920p:plain

続いて「選択」アクションを使って、取得したテスラのデータや現在時刻のデータを元にリクエストするべきJSONデータの構成を作成します。

色んな構成アプローチがあるかと思いますが、PowerApps・Automate界隈で有名なHiro先生 に教えてもらったこのアプローチが見通しもよくて、取り回しもしやすいです。

f:id:sugimomoto:20201130204928p:plain

一度本文を配列に突っ込んで、無理やり配列化し、マップ部分で必要な項目を定義し、Vehicle Dataをマッピングしていきます。(今見返すと、item()から値を取り出してすら居ないので、本文突っ込む必要性すら無かったな・・・?)

なお、speedに関しては、元のTesla APIのデータがマイル換算で取れるため、1.6を掛けてkm/hに直しています。

            "リクエストデータの構成": {
                "inputs": {
                    "from": [
                        "@body('Vehicle_Data')"
                    ],
                    "select": {
                        "battery_level": "@body('Vehicle_Data')?['response']?['charge_state']?['battery_level']",
                        "latitude": "@body('Vehicle_Data')?['response']?['drive_state']?['latitude']",
                        "longitude": "@body('Vehicle_Data')?['response']?['drive_state']?['longitude']",
                        "max": "80",
                        "min": "0",
                        "power": "@body('Vehicle_Data')?['response']?['drive_state']?['power']",
                        "shift": "@body('Vehicle_Data')?['response']?['drive_state']?['shift_state']",
                        "speed": "@mul(body('Vehicle_Data')?['response']?['drive_state']?['speed'],1.60934)",
                        "timestamp": "@body('現在の時刻')"
                    }
                },
                "runAfter": {
                    "現在の時刻": [
                        "Succeeded"
                    ]
                },
                "type": "Select"
            }

あとは、先程取得した Power BIのストリーミングデータセットのURLにHTTPコネクタを利用してデータをPOSTするだけです。

Content-Typeは「application/json」で、本文に選択アクションで構成したデータを登録しましょう。

f:id:sugimomoto:20201130204934p:plain

以上で構成は完了です。

実行

あとはLogicAppsを「有効」にすることで、ストリーミングが開始されます。

f:id:sugimomoto:20201130204939p:plain

なお、付けっぱなしにするといつまで経ってもTeslaがスリープ状態にならないので注意しましょう!

参考

qiita.com