SORACOM Orbit試してみた 〜SORACOM GPS マルチユニット編〜

今日(7/14)は一日ソラコムな一日だった人です。

---

今日(7/14)は[SORACOM Discovery 2020](https://www.discovery.soracom.jp/)でした。
リポーター枠で申し込んだこともあり、有給をいただいて、一日ソラコムざんまいでした。

SORACOM 5G(正式名称は違うはず)、IPOするかも、サブスクリプションコンテナなど、色々発表がある中、
新サービスは2つ登場しました。

- [SORACOM **O**rbit](https://blog.soracom.jp/blog/2020/07/14/soracom-orbit/)
- [SORACOM **P**eek](https://blog.soracom.jp/blog/2020/07/14/peek/)

個人的には、SORACOM Orbitにちょっと気になりましたので、
基調講演後、紹介動画([新サービス 「SORACOM Orbit」- IoT通信経路でデバイスとクラウドの差分を吸収 -](https://youtu.be/m303PK3OGAA))を見つつ、試してみました。

---

Orbitについては、[ブログ](https://blog.soracom.jp/blog/2020/07/14/soracom-orbit/)が公開されているので、詳細はそちらを参照していただきたいですが、

デバイスから、SORACOMプラットフォーム上に送られてきたデータをFunk、Beamなどのサービスに渡す前に、データのカスタマイズできる機能と認識してます。(違ったらごめんなさい。)
似たような機能としては、バイナリパーサーという機能がありますが、それをユーザー独自に実装できる機能(ブログ内では**すごいバイナリパーサー**と書かれてます)となるのではないでしょうか。

[開発者ガイド](https://dev.soracom.io/jp/orbit/what-is-orbit/)がすでに公開されているので、
まず、それで、開発環境のセットアップを行います。

開発者ガイド内に、[サンプルコード](https://s3-ap-northeast-1.amazonaws.com/soracom-files/orbit/orbit-development-environment.zip)もあるので、それもダウンロードします。

VS CodeのRemote Containersを使っているのですが、ちゃんと読んでなかったのですが、AWSJの西谷さんがいいって[ブログ](https://www.keisuke69.net/entry/2020/06/04/145719)で書いていたやつですねー。

現状、以下の3つの言語で使えるということで、

- AssemblyScript
- Rust
- C/C++

AssemblyScriptで試していたのですが、
一通りためしたところ(ローカルでのビルド、テスト、デプロイ、CLIでのテスト実行)で、デバイスの操作サンプルないなってことに気づき(GPSマルチユニット使ったら、エラー吐きまくりw)、
一旦落ち着いて、デモ動画と同じく、C++のコードで試すことにしました。

上記のサンプルコードをダウンロードし、解答すると、このような構造になっています。
![VS Codeで表示した状態](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/c861745a-6f0b-63a8-8aef-83046238c8f5.png)

サンプルコードは**orbit-sdk-c**のexamples/gps-multi-unitにありましたので、
main.cppの中身を
実際、Remote Containersを使う、**c**ディレクトリのsrc/main.cppにコピーします。
あと、nkohmann/json.hppもc/srcに配置します。
(最初忘れてコンパイルエラーになるので、焦った人です)

あとは、ビルドのコマンドを叩いて、WASMにコンパイルします。

![スクリーンショット 2020-07-14 23.43.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/a12a4654-e14a-4eaf-72e2-bfdb71de349a.png)

Wanringがでますが実行には問題ないということで無視します。

アップロードする手段としては、
- コンソール
- CLI
- VS Code上でアップロード

とあったので、とりあえずコンソールで実施しました。

- 新規作成ボタンをクリック

![スクリーンショット 2020-07-14 23.51.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/87c3156d-7667-bd35-54c4-3115e09b8484.png)

- IDと概要を入力。概要はなくても問題なしです。

![スクリーンショット 2020-07-14 23.52.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/5ccfa62e-4c3d-1f2c-4aad-83e7a73cdf5c.png)

- 空のsoralet(SORACOM + Appletの造語かな)ができるので、ビルドしたWASMをアップロードするために、新しいWASMをアップロードをクリック。

![スクリーンショット 2020-07-14 23.52.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/410e0980-934d-1b07-8948-a32a3b571db9.png)

ローカルでビルドしたファイルを選択して、
![スクリーンショット 2020-07-14 23.52.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/d8c5277c-afd8-9e3c-d437-e8bf145846a7.png)

アップロードボタンをクリック
![スクリーンショット 2020-07-14 23.52.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/111dce64-e55c-026a-8213-68fb2a378158.png)

こんな感じでできればOKです。
~~**REFERRED GROUPS** にSIMグループ名すでに入ってますが、すでにOrbitの設定してあるからですね。~~
2020/07/20 この件、問い合わせたところ、修正されたので、画像差し替え
<img width="1600" alt="solaret-new.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/0a139441-b4db-86c5-0d7b-cd2ad0b817ad.png">


SIMグループ側も設定します。
これはすでに設定済みの状況ですが、
![スクリーンショット 2020-07-14 23.58.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/b74d42de-d9a2-0f63-d465-591e7c80e14f.png)

CODE SRNは右の歯車ボタンを押すと、SORALETの一覧とSORALETのバージョンを指定するダイアログが出てきます。
![スクリーンショット 2020-07-14 23.58.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/4016c3d7-ac49-4583-7275-3149cc5f66ba.png)

SORALETのバージョンは、 LATESTもしくはバージョンの指定ができます。
最初はバージョン固定にしていたのですが、
ちょっとトライアンドエラーしていた最中にLATEST指定にしてしまいました。
実際運用するときは、バージョン指定した方がいいでしょうね。

DERECTIONはとりあえずデバイスからのデータの変更を加えたかったので、**Uplink**のみ有効にしてます。
メタデータサービスは有効にしている場合はONにします。
GPSマルチユニットの場合、センサーデータ用のフォーマット用のユーザーデータが設定されているので、それが出てきますね。
簡易位置情報はPlan-Kなどの簡易位置測位機能に対応しているSIMからの場合に有効にするといいらしいです。
自分はPlan-Dなので、とりあえず無効にしてあります。

設定したところで、おもむろにGPSマルチユニットのボタンをポチー。。。
[GPSマルチユニットSORACOM Edition 使ってみて、だいたい1ヶ月経ちました。](https://qiita.com/keni_w/items/24784a8155b5b0b0fb09)
でSlackに通知するようにしているので、待ちますが。。。来ない。

Orbitのログを見ると、GPSマルチユニットからはデータがきていて、動作はしているようです。
![スクリーンショット 2020-07-15 0.09.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/d597c1ba-6e57-8c1b-0a8c-967986a993f9.png)

困ったときはエラーログってことで、エラーログを見てみると、エラー吐いてます！
![スクリーンショット 2020-07-15 0.08.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/0f0fa4cc-22e7-3972-5f27-fc6c33a6ec00.png)

一体なんだろ。。。と、
サンプルソースをみます。。。
そして気づく。。。
あ、位置情報取れないとダメなところあるな。。。
ってことで、
GPSマルチユニットを外に置いて、ボタンを押します。
ドキドキ、通知きたーw

![_20200715_001828.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/4f74a98e-94d3-dc0f-b429-e93535f33e78.jpeg)


Harvestのログを見ても、ちゃんときています。
![スクリーンショット 2020-07-15 0.29.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/c497cffe-b248-255e-acb5-0f6ab8b0e2c5.png)
※試行錯誤の中、Tagに**center_lat**、**center_lon**、**radius**って値、設定しないとダメなんかなーって設定してたりしていたので、**distance_in_km**が出てますが、最終的にはエラーとは無関係でした。

SIMの名前(Tags.name)からのデータも取れていますし、Lambdaのログを見ても、eventオブジェクトの中にnameが入ってきてます。

```
{
    "bat": 3,
    "distance_in_km": (略),
    "humi": 76.1,
    "imsi": "(略)",
    "inside_area": 0,
    "lat": (略),
    "lon": (略),
    "name": "GPSマルチユニット用SIM",
    "rs": 4,
    "temp": 26.2,
    "type": 1,
    "user_data": "(略)",
    "x": 0,
    "y": 0,
    "z": -1024
}
```
せっかくなので、Lambda側のソース、ちょっといじって、event.nameを出してみました。
![_20200715_001848.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/63854774-adb5-8824-f45d-c47267e5af75.jpeg)

SIMって書いてあるのに、デバイス名っておかしくねっていうツッコミはなしでお願いします！

ということで、Orbitを設定して、データを追加して、Lambda側まで送られることを確認できました。

----

明日以降、このソースをIoTボタンに対応させてみようかなと思います。

RustのサンプルはどうもIoTボタンに対応しているようですが、Rust初めて＆写経ばかりになってしまうので。。。w

そして、気づいたんです。。。自分がソラコムサンタにお願いした対応ができてるんじゃってことに。。。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E3%81%97%E3%82%8D%E3%83%9C%E3%82%BF%E3%83%B3?src=hash&amp;ref_src=twsrc%5Etfw">#しろボタン</a> と <a href="https://twitter.com/hashtag/%E3%83%92%E3%82%B2%E3%83%9C%E3%82%BF%E3%83%B3?src=hash&amp;ref_src=twsrc%5Etfw">#ヒゲボタン</a> で、Funk使って、Lambdaとか呼び出すときに、SIMのタグ(名前とか)の情報送れないかしら。。。<a href="https://twitter.com/hashtag/soracom?src=hash&amp;ref_src=twsrc%5Etfw">#soracom</a></p>&mdash; Kenichiro Wada (@Keni_W) <a href="https://twitter.com/Keni_W/status/1263653576330506240?ref_src=twsrc%5Etfw">May 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

この辺も試してみたいと思います。

---

2020/07/20追記
Soralet新規登録時に、**REFERRED GROUPS** にSIMグループ名が入ってしまうのは、どうも不具合だったようです。
ソラコムさんのサポートに問い合わせたところ、本日対応されたのとのことです！
ってことで、画像差し替えました。
サポートの皆さん早急なありがとうございます！

---

2020/08/05 追記
>あ、位置情報取れないとダメなところあるな。。。

っていうのを今更ながら対応してみました。
って言っても、null判定入れただけですが(汗)

```c++

    if (j["lat"] != nullptr && j["lon"] != nullptr) {
        double lat = j.value("lat", 256.0);
        double lon = j.value("lon", 256.0);
        if ((center_lat >= -90) && (center_lon >= -180) && (lat >= -90) && (lon >= -180) && (radius > 0)) {
            soracom_log("center: %f, %f\npos: %f, %f\n", center_lat, center_lon, lat, lon);
            double distance = calc_distance_in_km(center_lat, center_lon, lat, lon);
            j["distance_in_km"] = distance;
            if (distance <= radius) {
                j["inside_area"] = 1;
            }
        }
```
まあ、ごっそり消せばいいって話もあったのですが、それはどうなんだろうとw