オムロン環境センサ Broadcaster Modeのアドバタイジングデータをでパースするnode moduleを書いた

# はじめに

[オムロン環境センサ](https://www.omron.co.jp/ecb/product-info/sensor/iot-sensor/environmental-sensor)とRaspberry Piがちょっと環境データをモニタリングするのに便利なんだけど、node.jsでやりたくてアドバタイジングデータをパースする簡単なモジュールを書いた。

これを試すには、まず環境センサをBroadcaster modeに設定する必要があります。

[Omron 環境センサ(2jcie-bl01)の設定をBroadcasterに変更してアドバタイズパケットから情報を取得してみるテストまで](https://qiita.com/komde/items/7209b36159da69ae79d2)

を参考にBroadcaster modeに変更してください。変更すると環境センサのデバイス識別名称が`Env`から`EP`に変わります。

ちなみに、Beacon modeでのデータ受信に関しては [futomi/node-omron-envsensor](https://github.com/futomi/node-omron-envsensor) が公開されているのでこちらを使いましょう。こっちのほうがよくできてます。

# omron-env-sensor.js

```omron-env-sensor.js
function OmronEnv() {
  /* pass */
};

OmronEnv.prototype._litlleEndialize = function(v) {
  if(v.length !== 4) {
    throw new Error('invalid data length. data length must 4');
  }
  return v.substring(2,4) + v.substring(0,2);
};

OmronEnv.prototype._numberize4byte = function(v) {
  //console.info(v);
  if(v.length !== 4) {
    throw new Error('invalid data length. data length must 4');
  }
  return parseInt(this._litlleEndialize(v), 16); // / 100
};

OmronEnv.prototype._numberize2byte = function(v) {
  //console.info(v);
  if(v.length !== 2) {
    throw new Error('invalid data length. data length must 2');
  }
  return parseInt(v, 16);
};

OmronEnv.prototype._parseData = function(v) {
  if(v.length !== 44) {
    throw new Error('invalid data length. packet data length must 44');
  }
  var data = {
    "companyId": this._numberize4byte(v.substring(0, 4)),
    "no": this._numberize2byte(v.substring(4, 6)),
    "temp": this._numberize4byte(v.substring(6, 10)) / 100,
    "hum": this._numberize4byte(v.substring(10, 14)) / 100,
    "light": this._numberize4byte(v.substring(14, 18)),
    "uv": this._numberize4byte(v.substring(18, 22)) / 100,
    "pressure": this._numberize4byte(v.substring(22, 26)) / 10,
    "sound": this._numberize4byte(v.substring(26, 30)) / 100,
    "disconf": this._numberize4byte(v.substring(30, 34)) / 100,
    "heat": this._numberize4byte(v.substring(34, 38)) / 100,
    "rfu": this._numberize4byte(v.substring(38, 42)),
    "battery": this._numberize2byte(v.substring(42, 44)) 
  };
  return data;
};

OmronEnv.prototype.parse = function(v) {
  var packet = v || null;
  if(!v) {
    throw new Error('data is empty');
  }
  return parsedData = this._parseData(v);
};

module.exports = OmronEnv;
```

なんかいろいろテキトーな感じだけど動くのは動きます。

# Raspberry Pi + nobleでデータを受信してみる

```index.js
'use strict';

const noble = require('noble');
const OmronEnv = require('./omron-env-sensor');

const NAME = 'EP';
const ADDRESS = '[DEVICE ADDRESS]';
const INTERVAL_MILLISEC = 10000;

const sensor = new OmronEnv();

//discovered BLE device
const discovered = (peripheral) => {
  const device = {
    name: peripheral.advertisement.localName,
    uuid: peripheral.uuid,
    rssi: peripheral.rssi
  };
  const d = new Date();
  if(NAME === device.name && ADDRESS === device.uuid) {
    const envData = sensor.parse(peripheral.advertisement.manufacturerData.toString('hex'));
    console.log(JSON.stringify(envData));
  }
}

//BLE scan start
const scanStart = () => {
  setInterval(() => { noble.startScanning(); }, INTERVAL_MILLISEC);
  noble.on('discover', discovered);
}

if(noble.state === 'poweredOn'){
  scanStart();
}else{
  noble.on('stateChange', scanStart);
}
```

`[DEVICE ADDRESS]` のところにお持ちの環境センサのアドレスに置き換えてください。
BLE Scannerなど取得できる`AA:BB:CC:11:22:33`のようなアドレスです。これを`aabbcc112233`のようにセミコロンを抜いて入力してください。

`index.js`を上書き保存して、以下のように実行すると数秒おきにデータが表示されるのが確認できます。

```
node index.js

{"companyId":725,"no":191,"temp":26.6,"hum":60.15,"light":271,"uv":0.02,"pressure":1010.3,"sound":51.33,"disconf":75.08,"heat":24,"rfu":0,"battery":196}
{"companyId":725,"no":192,"temp":26.48,"hum":60.12,"light":274,"uv":0.02,"pressure":1010.3,"sound":49.16,"disconf":74.91,"heat":23.89,"rfu":0,"battery":196}
{"companyId":725,"no":192,"temp":26.48,"hum":60.12,"light":274,"uv":0.02,"pressure":1010.3,"sound":49.16,"disconf":74.91,"heat":23.89,"rfu":0,"battery":196}
{"companyId":725,"no":193,"temp":26.37,"hum":60.12,"light":271,"uv":0.02,"pressure":1010.4,"sound":44.95,"disconf":74.75,"heat":23.78,"rfu":0,"battery":196}
{"companyId":725,"no":193,"temp":26.37,"hum":60.12,"light":271,"uv":0.02,"pressure":1010.4,"sound":44.95,"disconf":74.75,"heat":23.78,"rfu":0,"battery":196}
{"companyId":725,"no":193,"temp":26.37,"hum":60.12,"light":271,"uv":0.02,"pressure":1010.4,"sound":44.95,"disconf":74.75,"heat":23.78,"rfu":0,"battery":196}
{"companyId":725,"no":194,"temp":26.24,"hum":60.11,"light":271,"uv":0.02,"pressure":1010.2,"sound":54.01,"disconf":74.57,"heat":23.67,"rfu":0,"battery":196}
{"companyId":725,"no":194,"temp":26.24,"hum":60.11,"light":271,"uv":0.02,"pressure":1010.2,"sound":54.01,"disconf":74.57,"heat":23.67,"rfu":0,"battery":196}
{"companyId":725,"no":195,"temp":26.12,"hum":60.14,"light":136,"uv":0.01,"pressure":1010.3,"sound":53.49,"disconf":74.4,"heat":23.56,"rfu":0,"battery":196}
```

動くサンプルをこちらに置いておきます。

https://github.com/bathtimefish/omron-env-sensor-raspi-noble-example

# まとめ

オムロン環境センサ + node.js + Raspberry Piでかなりお手軽にデータが取れるのでいろんな実験に使えると思います。