Machinistとobnizで温湿度データを記録してみる

IIJさんのMachinistなるものを知ったので、obnizで使ってみました
そしてついでにMachinis javascript sdkなるものを**勝手に**作ってます


## Machinistとは

[Machinist](https://machinist.iij.jp)はいわゆるデータ保存サービスです
クラウド上にデータを保存します。
![スクリーンショット 2019-01-28 19.24.03.png](https://qiita-image-store.s3.amazonaws.com/0/227015/8d4bc483-a9e9-865c-eba2-aab40d900919.png)

データと言っても、動画からテキストまでいろいろありますが、Machinistは数値データに特化しています。「センサーデータ、ビジネスの KPI」とHPトップに書いてある通り、数字データが簡単に扱えるようになっています。IoT向けですね。

データ保存後はグラフ化したり、条件によってアラームメールを飛ばしたりできるようです


類似サービスだと[ambient](https://ambidata.io)ですね


## obnizとは

obnizはWeb技術でIoTをやるボードです。
![スクリーンショット 2019-01-28 19.24.46.png](https://qiita-image-store.s3.amazonaws.com/0/227015/6414e792-6a92-2c32-4d2c-75d6b76f689e.png)

IoT系はだいたいC言語を描かなきゃいけないことが多いですが、JavaScriptやpythonなどの言語でIoTをすることができます。
今回はこれとMachinistを組み合わせてみました。


# 温度をとって上げてみる

### Machinist/obnizの準備

それぞれ公式を見ながら会員登録等をします

- Machinist [1. アカウントの登録](https://machinist.iij.jp/getting-started/getting_started/sign_up.html)
- obniz [クイックスタート](https://obniz.io/doc/quickstart)


### Machinistのデータ構造を理解する

MachinistにはAgentやmetricという概念？が出てきます。

Agentが何かと言うと、送信元デバイスのようです。
metricやnamespaceも出てきて、こんがらがるんですが、全体構成としてはこの様になってそうでした

```text

Machinist クラウド
 L Agent 
 |   L Namespace 
 |   |  L Metric 
 |   |  |  L data 
 |   |  |  L data 
 |   |  |
 |   |  L Metric 
 |   |     L data
 |   |     L data
 |   | 
 |   L Namespace 
 |        .
 |        .
 L Agent
    .
    .
    .

```

Metricにデータが入って、それをまとめるNamespaceがあって、さらにそれをまとめるAgentがあります

データ構成イメージはこうなっていますが、クラウド上では横断的にフィルタリングや検索ができるので、どういう構成が良いかは結構悩みそうです。
（たとえば、Agentをまたいで同じMetric名でフィルタリング等ができます）

ただ、ここで混乱したのが、データ構造がこうなっていても、API上は一つのmetricに複数データを入れて更新できないAPIになっています。
API上だけで行くと、複数データを更新したい場合は、2つmetricを作る・・という不思議な構成でした。


### Machinistにデータを送ってみる

MachinistのGetting Startedを見てるとCurlでデータを送信しています。Curlとか触るのが嫌だったので、[javascriptでラッピングしました](https://github.com/9wick/machinist.js)

**API_KEY**は各自のものに書き換えてください。
Machinistログイン→プロフィールから取得できます



```javascript
//初期化
const machinist = new Machinist('Home', 'API_KEY');

//データを追加
let random = Math.floor(Math.random() * 10 + 20);
machinist.addMetric('temperature', random, {
  namespace: 'Environment Sensor',
});
console.log(`data : ${random}`);

//データを送信
machinist
  .post()
  .then(res => res.json())
  .then(json => {
    console.log(json);
  });
```

まず、`new Machinist('Home', 'API_KEY');`でMachinistオブジェクトを作っています。
`Home`がAgentの名前で、`API_KEY`はMachinistのwebサイトから取得するAPIキーです

そのHome(Agent)に`temperature`というMetricを追加しています。
namespaceを`Environment Sensor`にしていますが、省略すると`Default`になるようです。



```text
Machinist クラウド
 L Home(Agent)
     L Environment Sensor(Namespace) 
        L temperature (Metric) 
           L data 
           L data 
```

これでWeb上からデータを見るとポツンと追加されています

![スクリーンショット 2019-01-28 19.54.13.png](https://qiita-image-store.s3.amazonaws.com/0/227015/1fd824b7-4a19-6c25-5006-75c196b54ebd.png)


# obnizで温度を取って入れてみる

[SHT31](https://obniz.io/sdk/parts/SHT31/README.md?iframe=false)というセンサを使っています
温湿度がデジタルで取得できる便利なセンサーです

`API_KEY`と`OBNIZ_ID_HERE`をそれぞれ書き換えてください

```javascript


const machinist = new Machinist('Obniz', 'API_KEY');
const obniz = new Obniz('OBNIZ_ID_HERE');

obniz.onconnect = async () => {
  let sensor = obniz.wired('SHT31', {
    vcc: 0,
    sda: 1,
    scl: 2,
    adr: 3,
    gnd: 4,
    addressmode: 5,
  });

  while (1) {
    let temp = await sensor.getTempWait();
    let humd = await sensor.getHumdWait();
    console.log('temperature:' + temp + '   humidity:' + humd);

    machinist.addMetric('temperature', temp, {
      namespace: 'SHT31',
    });
    machinist.addMetric('humidity', humd, {
      namespace: 'SHT31',
    });

    machinist
      .post()
      .then(res => res.json())
      .then(json => {
        console.log(json);
      });
    await obniz.wait(60000);
  }
};

```


今回は温度と湿度があったので、構成はこちらのようにしています。


```text
Machinist クラウド
 L Obniz(Agent)
     L SHT31(Namespace) 
        L temperature (Metric) 
           L data 
           L data 
        L humidity (Metric) 
           L data 
           L data 
```

こんなふうにデータが取れました！
カスタムチャートを使ってグラフを重ねています。

![スクリーンショット 2019-01-28 20.04.10.png](https://qiita-image-store.s3.amazonaws.com/0/227015/020edbe1-2ee0-4a08-52de-1c510a35085d.png)



# 途中で困ったこと

１秒おきにデータを取ってみたら、うまく反映されませんでした。
なぜかな・・・とずっと悩んでいたらSDKの中にこんな記述がありました

![スクリーンショット 2019-01-28 20.04.59.png](https://qiita-image-store.s3.amazonaws.com/0/227015/a033aca6-0db2-53fb-061f-a9fe6fd11cfd.png)



これ、以下の条件のときは上書きされるようです

- 同じAgentName
- 同じNamespace
- 同じMetricName
- 同じ時刻(1分未満切り捨て？)

つまり、1分よりも短い間隔の場合はデータをとっても保存されません。（前のデータが消えます）
Machinistはロングスパンで使うを想定しているようですね





# まとめ

MachinistはMetricとかAgentとかの概念理解がすこし躓くかも知れませんが、そこを乗り越えれば簡単に可視化できて楽しそうです