IoTデータの可視化サービス「Ambient」を試す（Node.js のパッケージを利用）

以前からサービスについて知っていたものの、クラウドサービスでのデータ可視化はあまりやってこなかったのもあり、まだ利用をしたことはなかった [IoTデータ可視化サービスの「Ambient」](https://ambidata.io/)。
（これまでは、HTML+JavaScript でグラフ描画ライブラリを使っての可視化をやってた）

今回、よく自分が利用しているデバイス・サービスで利用する場合はどうすれば使えるのかを見てみたり、実際に Node.js のパッケージを使ってデータの送信と可視化の部分を試してみたりしました（送ったデータはランダムに生成したダミーデータを利用）。

## Ambient の概要
既に [Qiita でもタグ](https://qiita.com/tags/ambient)があり、記事もいくつも書かれていたりしますが、自分の理解を深めるためにも以下の公式ページをざっくり見ていって、その内容をメモしてみました。

●Ambient – IoTデータ可視化サービス
　https://ambidata.io/

![構成図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/aba03141-bc49-4a3a-35f7-079691465fc4.jpeg)

可視化の例として、公式ページのトップに以下のような事例が出ています。
![可視化の例.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/a6436341-c197-0ab8-968a-d56142ed7da1.jpeg)

### 利用するための方法（情報を見てみる＆チャネルを作成してみる）
Ambient を使うためのおおまかな手順は、以下の公式のチュートリアル（その中の1つ目）に書かれています。

●Ambientを使ってみる – Ambient
　https://ambidata.io/docs/gettingstarted/

【利用するための手順】
1. ユーザー登録(無料)
2. チャネル生成
3. マイコン側プログラミング
4. データー送信
5. 可視化(グラフ化)

#### ユーザ登録とチャネル作成

最初は公式サイト上でユーザ登録を行い、その後は可視化対象となるデータを管理するための「チャネル」を作成するところまでは、公式サイト上で操作を行っていけば良さそうです。

以下は、サイト上で「チャネルを作る」ボタンを押した後の状態です。
![Ambient_チャネル一覧.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/b19f8421-7e7a-cec8-a279-564ccb3131e1.jpeg)

チャネルが 1つ追加され、データ送信などに使うキーなどが発行されました。

#### マイコン側プログラミング
記事の途中で書いた手順では「マイコン側プログラミング」という項目で書かれてますが、公式情報の別のページ（以下のページ）を見ると、複数のテキストプログラミング言語・ビジュアルプログラミング環境からデータの送信を行えるようです。

●ライブラリー/リファレンス – Ambient
　https://ambidata.io/refs/

- 上記のページに掲載されているもの
   - Arduino / C++
   - mbed / C++
   - Python / MicroPython
   - node.js
   - Node-RED

また、M5Stackシリーズをビジュアルプログラミングで扱える UIFlow についても、GitHub で公開された独自ブロックを使うとデータの送信を行えるようです。

●UIFlow（Blockly）でAmbientにデータを送る – Ambient
　https://ambidata.io/samples/m5stack/uiflow/
●GitHub - AmbientDataInc/UIFlow
　https://github.com/AmbientDataInc/UIFlow

自分が個人的によく利用しそうな方向だと「UIFlow・Node-RED・Node.js」あたりになりそうです。

#### データ送信・可視化
データ送信元として様々な環境が利用できる中で、今回は Node.js を使ってマイコンを利用せずに試してみようと思います。

●node.jsライブラリー ambient-lib – Ambient
　https://ambidata.io/refs/node-js/

## Ambient を試す
現時点までで、 Ambient上でチャネルを作成するところまでは試しました。
チャネル作成時に発行されたキー等の情報を使い、Node.js から可視化用のデータを送ってみようと思います。

### Node.js で簡単なお試しまで
[公式の情報](https://ambidata.io/refs/node-js/)を見つつ、パッケージのインストールから始めていきます。

#### パッケージのインストール
```bash
$ npm install ambient-lib
```

#### プログラムからデータを送る
ライブラリの読み込みや接続・データ送信を行う処理は、以下のように書くようです。

```javascript
// ライブラリの読み込み
var ambient = require('ambient-lib');
```

```javascript
// Ambientへの接続
ambient.connect(チャネルId, ライトキー[, リードキー[, ユーザーキー]]);
// Ambientへのデータ送信
ambient.send(data, callback(err, res, body));
```

データ送信に関しては、例えば上記の `data` の部分に `var data = {d1: 1.1, d2: 2.2};` という形などで指定するようです。2つのデータを送る場合のサンプルとして、以下の内容が公式に書かれていました。

```javascript
ambient.send({d1: 1.1, d2: 2.2}, function(err, res, body) {
  if (err) {
    console.log(err);
  }
  console.log(res.statusCode);
});
```

上記の情報を活用しつつ、とりあえず `d1` のみに 1回だけ数値を送る、ということをやってみます。
プログラムは以下のとおりで、 `ambient.connect` では「チャネルId・ライトキー」の 2つのみを指定しました。 `d1` に送る数値は `1.1` を指定しています。

```javascript
const ambient = require("ambient-lib");

ambient.connect(【ご自身のチャネルId】, "【ご自身のライトキー】");

ambient.send({ d1: 1.1 }, function (err, res, body) {
  if (err) {
    console.log(err);
  }
  console.log(res.statusCode);
});
```

上記を実行してみた後に Ambient のチャネルを見てみると、以下の画像のような表示がされていました。うまく数値を送信することができていそうです。
![値を1つだけ送ってみる.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/5b7efa8e-80f1-5140-4c4b-78a966153930.jpeg)

### Node.js でのお試し（続き）
#### Node.js でプログラムを書く
無事にデータを送ることができているようなので、次に連続したデータ送信を行ってみます。何かセンサー付きのデバイスから値を取得する方法もありますが、今回は簡単に試せるように Node.js上でセンサーの値に見立てた乱数を生成して、それを送信するという形にしてみています。

先ほどと別のチャネルを作り、以下の Node.js のプログラムを使ってデータを送ってみました。今回のプログラムでは、 `d1` と `d2` の 2種類のデータを送るようにしてみました（※ 送信する値は乱数で生成）。

```javascript
const ambient = require("ambient-lib");

ambient.connect(【ご自身のチャネルId】, "【ご自身のライトキー】");

const intervalFunc = function () {
  ambient.send({ d1: Math.random() * 100, d2: Math.random() * 70 }, function (err, res, body) {
    if (err) {
      console.log(err);
    }
    console.log(res.statusCode);
  });
};

setInterval(intervalFunc, 5500);
```

データの送信間隔についてですが、以下の公式情報を見ると **「送信から次の送信まではチャネルごとに最低5秒空ける必要があります。それより短い間隔で送信したものは無視されます」** とあるため、5秒より少しだけ長い間隔を設定しました。

●諸元/制限 – Ambient
　https://ambidata.io/refs/spec/

また、1日に登録可能なデータ数の制限について **「1チャネルあたり1日3,000件までデーターを登録できます。平均すると28.8秒に1回のペースです。」** と書かれているため、1日じゅうデータを送る場合はデータの送信間隔をさらに長くする必要があるようです。

#### チャネルで 2つのデータを同一のグラフ内に表示させてみる
以下の公式情報の「チャートのカスタマイズ」の部分を参照しながら、グラフの表示方法を 1つのグラフ内で 2つのデータを同時に表示する形にしてみました。

●チャネルとチャートのカスタマイズ – Ambient
　https://ambidata.io/docs/customize/

表示方法の設定変更を行った後に、先ほどのプログラムをしばらくの間実行し続けると、以下のグラフが描画されました。
![2種類のデータをグラフ化.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/0f2bf01b-38f6-28dd-5091-00a71609cbff.jpeg)

## まとめ
今回、IoTデータ可視化サービスの「Ambient」を使った数値データのグラフ化を行ってみました。

記事内でふれていたように、UIFlow・Node-RED や Node.js以外の他のプログラミング言語でも利用できるようなので、今後は何らか特定のデバイスを使ってセンサーで取得した値をグラフ化するようなこともやってみようと思います。