Central: より高度な条件付きスキャン

より高度な条件付きスキャン

binaryフィルタを使用する

Advertisement/Scan Responseのbinaryの部分一致でフィルタを掛けることができます。
たとえば、

  • Flags

    LE General Discoverable Mode

    Simultaneous LE and BR/EDR to Same Device Capable (Controller)

    Simultaneous LE and BR/EDR to Same Device Capable (Host)

  • Local Name

    "Sample"

の情報を持ったadvertisementは次のような配列になります。

// Javascript Example

[0x02, 0x01, 0x1a, 0x07, 0x09, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65]

最初の [0x02, 0x01, 0x1a] がFlags情報、その後の[0x07, 0x09, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65]がLocalNameです。

こちらのFlagsを持ったadvertisementのみを検索したい場合は、[0x02, 0x01, 0x1a]のデータをフィルタ条件にして、
こちらのように書くことができます。

// Javascript Full Example

var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {
  await obniz.ble.initWait();
  var binaryFilter = [0x02, 0x01, 0x0a];
  var target = {
    binary: [binaryFilter]
  };

  obniz.ble.scan.onfind = async function(peripheral){
   console.log(peripheral)
  };

  obniz.ble.scan.onfinish = function(){
   console.log("scan timeout!")
  };

  await obniz.ble.scan.startWait(target, {filterOnDevice:true});
}


binaryフィルタ使用時は、デバイス側でフィルタリングをする必要がありますので、
filterOnDeviceオプションをtrueにしています。
下の「デバイスでフィルタリングをして通信量を削減する」の項目も参照ください

binaryフィルタでは、部分一致も可能なので、localNameにamplを含むデバイスを検索することもできます。

"Sample"がLocalNameのときのadvertisementは
[0x07, 0x09, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65]でした。
これのampl部分は[0x61, 0x6d, 0x70, 0x6c]となりますので、こちらを条件にセットします。

// Javascript Full Example

var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {
  await obniz.ble.initWait();
  var binaryFilter = [0x61, 0x6d, 0x70, 0x6c]; //ample
  var target = {
    binary: [binaryFilter]  
  };

  obniz.ble.scan.onfind = async function(peripheral){
   console.log(peripheral)
  };

  obniz.ble.scan.onfinish = function(){
   console.log("scan timeout!")
  };

  await obniz.ble.scan.startWait(target, {filterOnDevice:true});
}


この場合、めったにかぶらないとは思いますが、advertisementの他の情報(UUIDなど)に[0x61, 0x6d, 0x70, 0x6c]の配列が出た場合、
そちらも該当しますのでご注意ください。

複数の条件を組み合わせる

フィルタは複数の条件を指定することもできます。
その際、条件はすべてOR検索となります。デバイスの絞り込みのために条件を複数記載するのではなく、
複数デバイスを一度に検索するためにご利用ください。

localNameが"Blank"、もしくは"Beacon"であるデバイスを検索するには、
次のように条件をArrayで囲って複数記載します。

// Javascript Full Example

var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {
  await obniz.ble.initWait();
  var target = {
    localName: ["Blank", "Beacon"]  //scan Blank *OR* Beacon
  };

  obniz.ble.scan.onfind = async function(peripheral){
    console.log(peripheral.localName)
  };

  obniz.ble.scan.onfinish = async function(peripherals, error){
    console.log("scan timeout!")
  };

  await obniz.ble.scan.startWait(target);
}

同じlocalNameでの検索だけでなく、UUID等、他の検索条件を追加することもできます。

次のように記載すると、下記条件いずれかに該当したものが取得できます。
すべてOR検索となりますのでご注意ください。

  • localNameが"Blank"
  • localNameが"Beacon"
  • Service UUIDが1111
  • Service UUIDが2222
  • binaryで[0x02, 0x01, 0x1a] を含む
  • binaryで[0x61, 0x6d, 0x70, 0x6c] を含む
// Javascript Full Example

var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {
  await obniz.ble.initWait();

  var target = {
    localName: ["Blank", "Beacon"], 
    uuids: ["1111", "2222"] ,
    binary: [[0x02, 0x01, 0x1a], [0x61, 0x6d, 0x70, 0x6c]]
  };

  obniz.ble.scan.onfind = async function(peripheral){
    console.log(peripheral.localName)
  };

  obniz.ble.scan.onfinish = async function(peripherals, error){
    console.log("scan timeout!")
  };

  await obniz.ble.scan.startWait(target);
}

デバイスでフィルタリングをして通信量を削減する

BLEのフィルタリングは、何も指定しなければSDK(obnizjs)で実行されます。
つまり、obnizOSからSDKまでは情報が届いており、それをSDKがフィルタリングしてonfindが呼ばれます。

filterOnDevice設定をONにすることで、SDKまで通信を発生させずに、obnizOS内でフィルタリングを行うことができます。

// Javascript Full Example

var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {
  await obniz.ble.initWait();
  var binaryFilter = [0x02, 0x01, 0x0a];
  var target = {
    binary: [binaryFilter]
  };

  obniz.ble.scan.onfind = async function(peripheral){
   console.log(peripheral)
  };

  obniz.ble.scan.onfinish = function(){
   console.log("scan timeout!")
  };

  await obniz.ble.scan.startWait(target, {filterOnDevice:true});
}