SORACOM LTE-Mボタンのデータにタグ情報をつける

# はじめに

2020/11/12に開催されたSORACOM UG Online #2にて、SORACOM LTE-M Button for Enterprise(通称しろボタン)から送られるデータにタグ情報つけたい、という話をされていました。それは以前はできなかったのですが、現在はデータをSORACOMプラットフォーム内で加工できるSORACOM Orbitで対応可能になっています。

対応するWASMを作ったので紹介しておきます。

# 使い方

こちらのGitHubのリポジトリに簡単な対応コードを置いておきました。
https://github.com/1stship/AddTagsSoralet
これをビルドしても良いのですが、幸いSORACOM OrbitおよびWASMはコンパイル済みの生成物をアップロードすれば動作するようになっていますので、使うだけなら各自の環境でビルドする必要はありません。

以下に手順を記載いたします。

1. WASMをダウンロード
2. Soralet作成、WASMアップロード
3. SIMグループ作成、設定
4. SIMにグループとタグを設定

それぞれ説明します。

## 1. WASMをダウンロード

以下のURLからaddtags.wasmをダウンロードします。
https://github.com/1stship/AddTagsSoralet/releases/download/0.0.1/addtags.wasm

## 2. Soralet作成、WASMアップロード

基本的には以下のページに記載されている手順です。
https://dev.soracom.io/jp/orbit/deployment/

Soralet管理を開く
![スクリーンショット 2020-11-14 23.17.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/261fe7a8-b859-a994-fb9d-19ddfeb8d152.png)

新規作成をクリックし、適当なSORALET IDを入力して作成をクリックする
![スクリーンショット 2020-11-14 23.21.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/a547d592-59eb-d060-e7a0-80f237b67d0d.png)

新しいWASMをアップロードをクリックし、ファイルを選択をクリックしダウンロードしたWASMを選択し、アップロードをクリックする
![スクリーンショット 2020-11-14 23.28.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/e8a96d63-c3d2-4e68-dfdc-4ba1e053601c.png)

SoraletとWASMの準備はこれで終わりです。

## 3. SIMグループ作成、設定

基本的には以下のページに記載されている手順です。
https://dev.soracom.io/jp/orbit/running/

SIMグループを選択、もしくは新規作成します。
![スクリーンショット 2020-11-14 23.35.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/c9c986ac-8462-e819-c90c-b5b2d792834f.png)

SORACOM Air for Cellular設定のメタデータをONにします。
![スクリーンショット 2020-11-14 23.37.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/b5e96fca-1257-e88a-d720-9517ffe7517e.png)

SORACOM Air for Cellular設定のバイナリパーサーをONにし、フォーマットに@buttonを指定して保存します。
![スクリーンショット 2020-11-14 23.39.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/b6156e3e-2c98-0ac0-5be7-17d669f2c3d3.png)

SORACOM OrbitをONにし、CODE SRNにてアップロードしたSORALET、VERSIONは$LATESTとして選択します。DIRECTIONはUplinkにチェック、メタデータをONにして保存します。
![スクリーンショット 2020-11-14 23.41.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/017b9e70-791d-8432-3046-ee0e6dcea6d2.png)

連携するアプリケーションサービス(Beam/Funnel/Funk/Harvest Dataのいずれか)をONにします。今回はひとまずHarvest DataをONにします。
![スクリーンショット 2020-11-14 23.47.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/868fb119-4548-371d-e409-764900470ef4.png)

SIMグループの設定はこれで終わりです。

## 4. SIMにグループとタグを設定

SIM管理画面にて対象のボタンのSIMをチェックし、詳細をクリックしてダイアログを表示する。ダイアログにてグループを3. にて設定したグループに変更する。「tags」というタグを追加し、その中にボタンデータに追加したいタグ名をカンマ区切りで設定する。その他必要なタグを設定する。
![スクリーンショット 2020-11-14 23.54.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/8d84b8a2-7988-d3b7-0b82-2b732bc1b0f0.png)

使い勝手を考えると設定されているタグ全てが自動的にデータにつくようにしたかったのですが、SORACOM OrbitのSDKではタグ名を指定して取得する方法しか提供されていなかったため、ひとまず取得すべきタグを指定する方法としました。また、SIM名をデータに追加したい場合は「name」というタグ名を指定すればよいです。

これで設定は終了です。

# 動作確認

ボタンをシングルクリックしてHarvest Dataを確認すると、ボタンデータと一緒に指定したDSNとLocationが入っていることが確認できました。
![スクリーンショット 2020-11-15 0.04.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/d4b85443-06a4-a720-f6e3-f39df1d7c541.png)

# コード

WASMのコードは以下になります。
詳細はGitHubのリポジトリをご確認ください。
https://github.com/1stship/AddTagsSoralet

```cpp
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>

#include <emscripten.h>
#include "soracom/orbit.h"

#include "nlohmann/json.hpp"
using nlohmann::json;

int32_t uplink_body();

extern "C" {

EMSCRIPTEN_KEEPALIVE
int32_t uplink() {
    return uplink_body();
}

}

std::string get_tag(const std::string& tag_name) {
    const char* tag_value = NULL;
    size_t tag_value_len = 0;
    int32_t err = soracom_get_tag_value(tag_name.c_str(), tag_name.size(), &tag_value, &tag_value_len);
    if (err < 0) {
        return "";
    }

    return std::string(tag_value);
}

std::vector<std::string> split(std::string& input, char delimiter)
{
    std::istringstream stream(input);
    std::string field;
    std::vector<std::string> result;
    while (getline(stream, field, delimiter)) {
        result.push_back(field);
    }
    return result;
}

int32_t uplink_body() {
    const char* buf = NULL;
    size_t siz = 0;
    int32_t err = soracom_get_input_buffer_as_string(&buf, &siz);
    if (err < 0) {
        return err;
    }
    json j = json::parse(buf);
    soracom_release_input_buffer(buf);

    std::string tagNames = get_tag("tags");
    std::vector<std::string> tags = split(tagNames, ',');

    for (int i = 0; i < tags.size(); i++){
        std::string tagName = tags.at(i);
        std::string tagValue = get_tag(tagName);
        j[tagName] = tagValue;
    }

    std::string output = j.dump();
    soracom_set_json_output(output.c_str(), output.size());

    return 0;
}
```

今回はとりあえずタグだけ入れていますが、コードを追加すればIMSI、ユーザーデータ、簡易位置測位機能の位置をデータに入れることも可能です。
また、ボタン以外のデバイスでも同じように使えます。やっていることはJSONに追加しているだけなので。

# おわりに

SORACOM Orbitで今までできなかった色々なことができるようになりましたね。
また、汎用的な用途であれば自分でコード書かなくても、だれかが用意したWASMをそのまま使う、というやり方もできそうです。
無料ではないのでその点はご注意を(料金はこちらでご確認ください。 https://soracom.jp/services/orbit/price/)