LoginSignup
4
0

More than 3 years have passed since last update.

SwitchBot温湿度計のデータを Web Bluetooth API で取得する:【未完】準備や試行錯誤のメモ

Last updated at Posted at 2021-05-16

この記事は、以下の記事の続きで、あれこれ試した内容などのメモです。
 ●SwitchBot温湿度計を Web Bluetooth API でスキャンする【試行錯誤中】 - Qiita
  https://qiita.com/youtoy/items/e28a10866dd0050251c0
なお、思ったように進まなかった部分があり、今回の記事でも完結はしていない状況です。

Web Bluetooth API でのスキャン(前回の記事の内容)

前回の記事では、例えば以下のような処理で SwitchBot温湿度計 をスキャンできるところまでは確認していました。

// パターン1
navigator.bluetooth.requestDevice({filters: [{ services: ["cba20d00-224d-11e6-9fb8-0002a5d5c51b"] }]});
// パターン2
navigator.bluetooth.requestDevice({filters: [{ name: ["WoSensorTH"] }]});
// パターン3
navigator.bluetooth.requestDevice({filters: [{ namePrefix: ["WoSensor"] }]});

温湿度データを取得するための前準備

さて、ここまでは「過去に利用した Web Bluetooth API の仕組みを使って、とりあえずスキャンして検出できるところまで試せた」という状況でした。

その後、この続きをやろうと調べたりしていると「もしかしたら今まで行っていた BLEデバイスとの間でのデータ送受信とは異なるやり方が必要かも?」という状況になってきました。具体的には、以下にも記載された「Web Bluetooth Scanning」に関わる部分です。
 ●Web Bluetooth Scanning
  https://webbluetoothcg.github.io/web-bluetooth/scanning.html

スキャン関連の情報・サンプルを見直してみる

追加で調べた情報の中に、以下の「Scanning API の仕様」と Chrome での対応状況の話が出てきました。

●web-bluetooth/implementation-status.md at main · WebBluetoothCG/web-bluetooth
 https://github.com/WebBluetoothCG/web-bluetooth/blob/main/implementation-status.md#scanning-api
Scanning API.jpg

2つ目のリンク先の内容(上の画像の内容)を見てみると、Android・Mac の Chrome で chrome://flags/#enable-experimental-web-platform-features を有効にすると使えるスキャン関連の処理があるようです。

スキャン関連の処理をコンソール上で実行してみる

自分が普段使っている Mac の Chrome で続きを進めていきます。

Chrome で chrome://flags/#enable-experimental-web-platform-features を開き、該当項目が Disable になっているのを Enable に変更してみました。そして、ブラウザの再起動を促されるのでそれに従います。
機能の有効か.jpg

上で URL を載せていた「Web Bluetooth Scanning」の中の「1.1. Examples」を見てみると、以下のような処理が書いてあります。
Web Bluetooth Scanning の例

これを参考にして、Chrome の開発者ツールのコンソールで実行するための簡単な処理を書いてみました。やったことは、スキャンをしている部分の一部を取り出して、フィルター設定の部分を前回利用したもの(SwitchBot温湿度計の名前を記載したもの)に変えただけです。

navigator.bluetooth.requestLEScan({
  filters: [{ name: ["WoSensorTH"] }],
  keepRepeatedDevices: true
})

そして、開発者ツールのコンソールで実行してみると、エラーはでないことが確認できました。
機能の有効化した後(実行OK).jpg

ちなみに、 chrome://flags/#enable-experimental-web-platform-features を Disable の状態で同じことをやると、「navigator.bluetooth.requestLEScan って関数はない」というにエラーがでます。
機能の有効化をする前(実行不可).jpg

さて、スキャン用の処理を実行する方法は見つかったものの、スキャン結果が空白になっている気がします。もしかしたら UUID とか別の設定を使わないとダメなのかな、とか思いつつ、いったんフィルターを行わず検出できる全てのデバイスを対象にスキャンしてみました。

navigator.bluetooth.requestLEScan({ acceptAllAdvertisements: true })

そのために上記を実行してみたのですが、またデバイスが 1つも検出されないような...

OS(デバイス)を変えてスキャン関連の処理をコンソール上で実行してみる

ここで試しに、別の Windows 10 のマシンで実行してみることにました。

上で見つけていた情報によると、Windows であれば chrome://flags/#enable-experimental-web-platform-features が Disable でも OK なのかな、と思ったのですがエラーがでたので Mac と同様に Enable にして試しました。

Chrome の開発者ツールのコンソールで navigator.bluetooth.requestLEScan({ acceptAllAdvertisements: true }) を実行すると、スキャン結果の表示部分にたくさん情報が表示されました。

そこで、今度は以下の UUID でフィルタする設定で実行してみました。

navigator.bluetooth.requestLEScan({
  filters: [{ services: ["cba20d00-224d-11e6-9fb8-0002a5d5c51b"] }],
  keepRepeatedDevices: true
})

無事、1台分の情報が出てきたのを確認できました。
Windowsで試した場合.jpg

しかし、この後の続きでいろいろやっていると動作が不安定な感じが...
(スキャンを実行した後の許可を求めるダイアログが出なくなったり、何度かやり直してると表示されたり、というような挙動に)

OS(デバイス)を変えてスキャン関連の処理を実行する

さらに OS というかデバイスを変更してみます。
スキャン関連の情報を調べていて以下の Android を使った事例があったので、Androidスマホを使って試してみます。
 ●Web Bluetooth を使ってみよう!その1 - 芳和システムデザイン
  https://houwa-js.co.jp/exe/2021/03/20210316/

Androidスマホだと開発者コンソールであれこれやるのが厳しそうなので、HTMLファイルに書いてそれを実行する形にします(Netlify を使ったりしつつ)。具体的には、以下の内容のファイルを作りました。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Web Bluetooth API によるスキャン</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.css"
    />
  </head>
  <body>
    <section class="section">
      <div class="container">
        <h1 class="title">操作用ボタン</h1>
        <div class="buttons" style="margin-top: 1.5rem">
          <button
            class="button is-success is-light"
            type="button"
            onclick="onStartButtonClick()"
          >
            スキャン
          </button>
        </div>
      </div>
    </section>

    <script>
      async function onStartButtonClick() {
        await navigator.bluetooth.requestLEScan({
          filters: [{ services: ["cba20d00-224d-11e6-9fb8-0002a5d5c51b"] }],
          keepRepeatedDevices: true,
        });
      }
    </script>
  </body>
</html>

こちらを Web上にアップして Androidスマホで実行したところ、文字が薄くて非常に見づらいですが、以下のように 1つだけスキャン結果が出てきました。
スマホでのスキャン結果

温湿度データを取得するための下準備

この後は Androidスマホ上で処理を実行する形で続きを進めてみます。

PC の Chrome と Androidスマホの Chrome を連携させる

その際、Androidスマホ上の Chrome のコンソールへの出力を確認できるように、以下の仕組みを利用することにします。
 ●Remote debug Android devices - Chrome Developers
  https://developer.chrome.com/docs/devtools/remote-debugging/
とりあえず上記の仕組みのさわりの部分だけ書いておくと、以下のようになります。

  1. PC と接続した Androidスマホを、PC から USBデバッグできる状態にする
  2. PC と Androidスマホをつないだ状態で、PC で Chrome を開く
    3. PC の Chrome で chrome://inspect#devices を開く

上記の手順3 で開いたページで「Discover USB devices」にチェックが入っていれば、USB で接続した Androidスマホ(※ USBデバッグの設定がされているもの)を PC上から操作できたりします。
PCのChromeでAndroidスマホのChromeを操作.jpg

試行錯誤していたら思った以上にメモの内容が増えてしまったのもあり、この続きは別の記事にしようと思います。

まとめ

SwitchBot温湿度計のデータを Web Bluetooth API で取得するには、前回の記事で試していた navigator.bluetooth.requestDevice( ではなく、 navigator.bluetooth.requestLEScan を利用する形になりそうというのが分かりました。

さらに、 navigator.bluetooth.requestLEScan を利用するためには Chrome で chrome://flags/#enable-experimental-web-platform-features を有効にする必要があることが分かり、いろいろ試していると自分の環境(Mac、Windows、Android)では Android 以外の OS で navigator.bluetooth.requestLEScan が意図した通りに動かなそうである状況のように見えました。

進捗はあったものの今回の記事で完結せず、次こそは完結編にできればと思います。
(知見はいろいろ得られた気がするので、その点は良いかな)

【追記】 次で完結!

試行錯誤を続けて書いた次の記事で、ようやく温湿度の値を BLE経由で得ることができました。
 ●SwitchBot温湿度計のデータを Web Bluetooth API で取得する【完結編】 - Qiita
  https://qiita.com/youtoy/items/8e3cca2172e2c4806846

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0