18
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

IoTLTAdvent Calendar 2020

Day 1

12月なのでクリスマスソングにノるテンアゲなキーボードliteを実装!【WebHID API】 #iotlt

Last updated at Posted at 2020-12-01

この記事はIoTLTアドベントカレンダー1日目です!(先に断っておきますが自作キーボード話ではないです) 先日のIoTLT vol69で話したネタをアップデートした感じです。
関係ないけどついに、この季節がやってきましたか〜 2020年めちゃ早い

IoTLT vol69 https://iotlt.connpass.com/event/192582/

テンション爆上がりなキーボードがこちら

毎年アドベントカレンダーネタでクリスマスっぽい話をやろうかと思ってたけど、全然やれてなかったので今回はクリスマス曲に合わせてみました。

記事の後半に実際に試せる(MacBookProでしか試してませんが)ページのURLを記載してますので是非手元でも試してみてください!

ちなみに再生してる曲はこちらから

https://www.youtube.com/watch?v=eYhkSC3gRno

なんとブラウザでキーボードバックライトの制御

Webブラウザからキーボードバックライトを制御出来ています。

ブラウザからハードウェアが制御できるAPIは色々と試して来てますが、今回は特に面白いですね。

WebHID API - Nintendo Switchも動かせるよ

HIDはhuman interface devicesの略です。様々なヒューマンインターフェイスデバイスをJavaSciprtで制御出来るAPIです。

参考記事から引用: ヒューマン インターフェース デバイス(HID)には、新しすぎる、古すぎる、あまりにも一般的でないなどの理由で、システムのデバイス ドライバーからアクセスできないロングテールなものがあります。WebHID API は、デバイス固有のロジックを JavaScript で実装する方法を提供することで、この問題を解決します。

ヒューマンインターフェイスデバイスと言われてもよく分からないと思いますが、 **Nintendo Switchのコントローラー(Joy-Con)**や冒頭のデモ動画のような キーボードのバックライトの制御が出来ます。

詳細は参考記事を読んでみてください。

利用はChrome v86以上かつ、現状オリジントライアル

WebHID APIは現時点だと、Google Chrome v86以上で対応しています。

他のブラウザの対応状況はCan I Useを見て確認しましょう。


2020/12/1現在 まだ全然対応してない......
https://caniuse.com/?search=webhid

見てみると全然対応してないですね、最新版のChromeでもアップデートしただけでは使えず、オリジントライアルという利用するオリジン(利用するサイト的な)の登録作業をし、利用するユーザーのChromeのフラグ設定を変えてやっと利用出来ます。

Gamepad APIとの違いは?

Gamepad APIというものが既存で存在しましたが、Nintendo SwitchのJoy-Conが使えるとなると、このAPIとの違いは?と思う人もいるかもしれません。(この辺のハードウェア制御系のブラウザAPIをウォッチしてる人が少なさそうですが苦笑)

間違ってるかもですが僕が見ている印象だと、Gamepad APIはインプットのみでWebHID APIの方がやれることは多そうな印象でした。

  • Gamepad API
    • デバイス -> ブラウザ のインプットのみ
    • ゲームパッドのみ
  • WebHID API
    • デバイス <-> ブラウザ でインプットとアウトプット両方
    • ゲームパッド以外も対応

上位互換というよりかは、Gamepad APIはゲームパッドからのインプットに特化してる気がします。ちゃんと調べ切れてないので、認識間違ってたらコメント下さい。

WebHID APIを利用してみよう

では実際にWebHID APIを利用してみましょう。

事前準備

最初にちょっと準備が必要です。

クライアント(ブラウザ)側

フラグを確認する必要があります。chrome://flags/にアドレスバーからアクセスしま、#experimental-web-platform-featuresのフラグをenableにしましょう。

サーバー側、オリジンの申請

WebHID APIは、現状オリジントライアルというステータスで、利用するオリジンをGoogleに申請する必要があります。

こちらからオリジントライアル申請します。

ドメインだけでなく、オリジンなのでちゃんとhttps://も入れましょう。

  • パスは不要です。
    • 例えばhttps://hogehoge.com/huga/index.htmlで利用したい場合はhttps://hogehoge.comを登録すれば大丈夫です。
  • SSLがマストです。
    • httpは使えません、httpsがマストです。

無事に登録できると次のページでトークンが発行されます。

利用するページのHTMLファイルのmetaタグに以下のような指定をし、発行されたトークンを指定することでWebHID APIが利用出来ます。

<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
補足: npxで気軽にサーバー起動とトンネリング

オリジンの登録ということは、基本ホスティング環境ということになりますが、毎回デプロイしなおすのは手間なので、最近はserveとngrokの二つのコマンドをnpx経由でインストールせずに実行して手軽に試してます。

  • ローカルサーバー起動
$ npx serve -l 4444
  • トンネリングサーバー起動
$ npx ngrok http 4444

ngrokで発行されたオリジンをオリジントライアルに登録するとデプロイなどせずに手軽に試せます

コードの実装

index.htmlscript.jsを作成しました。

HTML側 - トークンの指定

先ほども紹介したように、index.htmlのhead内に以下を記載しましょう。

<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">

TOKEN_GOES_HEREの箇所は登録して発行されたトークンです。

JavaScript側 - navigator.hid

script.jsは以下のコードで実行してみます。

利用できる状態だと、navigator.hidが利用出来ます。

if ("hid" in navigator) {
    // The WebHID API is supported.
    console.log(`HIDが使えるよ`);
} else {
    console.log(`HIDが使えません`);
}

コンソールにHIDが使えるよと表示されればOKです。

https://~~で登録してるのにブラウザで確認するときにhttp://~~になってるなど登録した条件と違う場合は動作しないので注意しましょう。

Nintendo Switchのコントローラーで試す

そのまま実行すると怒られるのでボタンを追加して、ボタンクリックからスタートするようにします。

Uncaught (in promise) DOMException: Failed to execute 'requestDevice' on 'HID': Must be handling a user gesture to show a permission request.

web.devのサンプルコードからそのままという感じですが、Nintendo SwitchのJoy-ConはvendorIdproductIdが↓のような値なので指定しましょう。

参考: https://web.dev/hid/

// Filter on devices with the Nintendo Switch Joy-Con USB Vendor/Product IDs.
const filters = [
    {
      vendorId: 0x057e, // Nintendo Co., Ltd
      productId: 0x2006 // Joy-Con Left
    },
    {
      vendorId: 0x057e, // Nintendo Co., Ltd
      productId: 0x2007 // Joy-Con Right
    }
];
  
const main = async () => {
    // Prompt user to select a Joy-Con device.
    const [device] = await navigator.hid.requestDevice({ filters });
};


if ("hid" in navigator) {
    // The WebHID API is supported.
    console.log(`HIDが使えるよ`);
    const btn = document.querySelector(`button`);
    btn.addEventListener('click', main);
}else{
    console.log(`HIDが使えません`);
}

Webサイトにアクセスし、スタートボタンを押すと接続済みのJoy-ConがHIDとして認識されます。

また、このような実装まで繋げてあげると、 Joy-Conのバイブレーション機能を利用出来ます。

// First, send a command to enable vibration.
// Magical bytes come from https://github.com/mzyy94/joycon-toolweb
const enableVibrationData = [1, 0, 1, 64, 64, 0, 1, 64, 64, 0x48, 0x01];
await device.sendReport(0x01, new Uint8Array(enableVibrationData));

// Then, send a command to make the Joy-Con device rumble.
// Actual bytes are available in the sample below.
const rumbleData = [ /* ... */ ];
await device.sendReport(0x10, new Uint8Array(rumbleData));

参考: https://web.dev/hid/#send-output-reports

device.sendReport()でデータ配列を送ってバイブを制御しています。

デモはこちらのIoTLT vol69の様子を

ここのデータを変えて試してみたいですね。

キーボードバックライトで試す

同じようなアクセスの仕方で、キーボードのバックライトをJavaScriptから制御できます。

スクリーンショット 2020-12-01 20.52.28.png

vendorIdなどのパラメータも参考記事を元に指定します。

const [device] = await navigator.hid.requestDevice({
  filters: [{ vendorId: 0x05ac, usage: 0x0f, usagePage: 0xff00 }]
});

リクエストするとKeyboard Backlightの許可を求められます。

// Blink!
const reportId = 1;
for (let i = 0; i < 10; i++) {
  // Turn off
  await device.sendFeatureReport(reportId, Uint32Array.from([0, 0]));
  await waitFor(100);
  // Turn on
  await device.sendFeatureReport(reportId, Uint32Array.from([512, 0]));
  await waitFor(100);
}

音楽に合わせてキーボード光らせるのはこちらで試せます

最後ですが、ここまで試して、キーボードを光らせることが出来たので、音楽にノらせてパリピ感のある演出をしてみたいなと突発的に思いました。これが最初のデモになります。

Izm Logさんのブログを参考に、ビート検出のコードを利用させてもらい、 ビート検出時にキーボードを光らせる というプログラムを作ってみましたが、けっこういい感じの反応になりました。

P5.jsでAudio Visualizerを作ってみた!【ビート検知】- Izm Log

デモ動画の最後にも載せてますが、指パッチンでの反応もいい感じです。

スクリーンショット 2020-12-02 19.05.51.png

MacBookProでしか試せてませんが、こちら↓で試せます。

https://mystifying-newton-aedc2e.netlify.app/

  • マイクの利用を許可する
  • リクエストのボタンを押す
  • デバイス利用の許可を求められるので、Keyboard Backlightを選択
    • (MacBookPro以外の人はここでデバイスが表示されないかも)
  • オープンのボタンを押す
  • このページを開きながら、何か音楽を流す
    • この時、別タブでYoutubeを長そうとすると、このページの処理が止まってしまうので、一つのPC内で試す際は別タブではなく別ウィンドウで開くようにしましょう。このページがアクティブになってる状態にして下さい。

まとめ

色々と書きましたが、Chrome v86から利用できるようになったWebHID APIを利用してみたという記事です。

まだGoogle公式のサンプルを少しいじったくらいしか試せてませんが、キーボードのバックライトをいじれるのはけっこう楽しいです。

Nintendo Switchのコントローラーもまだまだ遊びきれてないのでまた少し触ってみたいなぁ

前回のIoTLT vol69の時の様子はこちらのYoutubeでも観れるのでぜひご覧ください!そしてチャンネル登録も是非!

https://www.youtube.com/watch?v=Jynrd0VbIig&t=11s

次回は12/15にIoTLTを実施しますのでこちらもよろしくお願いします!

明日は@3yaka4さんによるねこIoT的な何かの記事です!
楽しみですね〜 :)

少し早いですが、今年もありがとうございました!来年もよろしくお願いします!

それでは!

18
6
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
18
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?