Webブラウザの世界から始めるIoT入門 #gigttt


## この資料について

* [こちらのイベント](https://giginc.connpass.com/event/120576/)での発表資料です。
* 基本的には、現時点でmacOSのChromeで(v72)試せる内容になってます。他のブラウザでは試してません。
* Webエンジニアだったり、WebディレクターだったりWeb業界の人向けです。
* 過去にも同じようなネタやったことあるけど、割と状況変わったりするので再度調査も兼ねてまとめました。
* IoTってタイトルで言ってますけど、IoTっぽいことって言った方が正しいです。IoTとは〜みたいなことを知りたい人は誰かビジネスサイドの人のそういう資料を見ましょう。個人的にはIoTとは〜みたいな問いはここでは~~どうでもいい~~各々の解釈で良いと思っています。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">IoTは何でも良い！<br> <a href="https://twitter.com/hashtag/gigttt?src=hash&amp;ref_src=twsrc%5Etfw">#gigttt</a></p>&mdash; Mt (@devemt) <a href="https://twitter.com/devemt/status/1108326152878223361?ref_src=twsrc%5Etfw">2019年3月20日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

> うーん、誰かに怒られるのかなぁ

---

## 自己紹介

<img src="https://qiita-image-store.s3.amazonaws.com/0/35387/profile-images/1473686705">

* 名前: [n0bisuke](https://twitter.com/n0bisuke)
* 所属: [dotstudio](http://dotstud.io)
* コミュニティなど: [IoTLT](http://iotlt.connpass.com) / [Microsoft MVP](https://mvp.microsoft.com/ja-jp/) / [LINE API Experts](https://engineering.linecorp.com/ja/blog/announcing-the-line-api-experts-2018-q1/)
* 少し前に作ったもの
	* [IoTでポケモンマスターに俺はなる！ #iotlt](https://qiita.com/n0bisuke/items/027ac51527a499b5d19f)
		* <img src="https://camo.qiitausercontent.com/479cc9dc64ab9f2a5e4ceb31442068a45cb80677/68747470733a2f2f692e6779617a6f2e636f6d2f38306438376164376466633965313332363966656632653933653637353639642e676966" width="200px">
	* [CROSS MEで黒髪のメガネ女子とマッチングするデバイスをAIとIoTを駆使して作った話 #iotlt](https://qiita.com/n0bisuke/items/1dcc9f9eed8d33c68981)
		* <img src="https://camo.qiitausercontent.com/08453cedcdc1032ee7fd905e6e10a0ce348714b6/68747470733a2f2f692e6779617a6f2e636f6d2f66303265656437383964663030353738313065386136393266653961336234322e676966" width="200px">

---

## 今回言いたいこと

* ブラウザのAPIでけっこう物理世界の何かを動かすことは出来る
* JavaScriptから入ってNode.jsまでいくとさらに広がる
* 細かい仕様とか深いところまで知らなくてもIoTっぽい内容に触れることは出来る

---

## 有名どころAPI

有名どころってのは主観です。

---

### WebBluetooth

* WebブラウザのJavaScriptから外部のBluetoothデバイスとの接続が行えるAPI
* `avigator.bluetooth.requestDevice()`でBluetoothデバイスにアクセスできる
* 深くなるので後述1

---

### WebUSB

* WebブラウザのJavaScriptからUSBデバイスへ"直接"アクセスできる技術
* `navigator.usb.requestDevice()`でUSBデバイスにアクセスできる
* 深くなるので後述2

---

### WebRTC

* Webブラウザで、映像や音声の双方向通信が行える技術
* `navigator.getUserMedia()`でカメラやマイクなどのデバイスにアクセスできる

> <img src="https://i.gyazo.com/27821d5b885bae9fda1696b96aeacd4d.png" width="400px">
> 図にあるようにP2Pで通信が行われる

---

## デバイス制御形

基本的には↑同様にWebブラウザ上のJavaScriptで制御できるAPIです。

---

### GamePad API

* Webブラウザで、PCに接続しているGamePad(ゲームコントローラ)の情報を取得することができます
* `navigator.getGamepads()`でゲームパッドの情報にアクセスできる
* Nintendo SwitchのコントローラをPCに接続して利用することも出来ます。アツい。
	* [Nintendo SwitchのコントローラでGamepad APIを試す](https://routecompass.net/switch-game-api/)

---

### Web MIDI API

* Webブラウザで、PCに接続しているMIDIデバイスの信号を扱うことができます。
* `navigator.requestMIDIAccess()`でMIDIデバイスにアクセスができる
* Web MIDIで信号を受けて、Web Audio APIで音を鳴らすといった連携がよく使われるイメージです。
	* [ブラウザ × MIDI？Web MIDI APIを使ってMIDIデバイスの入力を取ってみよう](https://liginc.co.jp/199990)

---

### Keyboard API

* Webブラウザで、PCに接続しているキーボードの情報を取得することができます。
* `navigator.keyboard`にキーボードの情報が入ってきます。

```js
navigator.keyboard.getLayoutMap().then(res => console.log(res))
```

> <img src="https://i.gyazo.com/0daba7c133c359fe4092ab68c2bb0235.png" width="400px">
> 僕が使ってるキーボードは48キーなんでしょう。

---

### Battery Status API

* Webブラウザで、デバイスのバッテリー情報を知ることが出来ます。
* `navigator.getButtery()`でバッテリー情報にアクセス出来ます。

```js
navigator.getBattery().then(v => console.log(v));
```

> <img src="https://i.gyazo.com/69b8f712be4384ca300c032e8a39a0b8.png" width="400px">

* フル充電じゃないと見れないサイトとか作れそう
* 電池の残りが少ない時にしか見れないキャンペーンとか

---

### Vibration API

* Webブラウザ側から、ページにアクセスしているデバイスを振動させます。バイブ機能。
* `navigator.vibrate()`でバイブ機能にアクセス出来ます。
* アダルトサイトを見ていて飛ばされた先にある怪しげなサイトで出るアラートなどはこれです。（たぶん言い切っていい思う。）

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">☑︎Vibration API<br>navigator.vibrate()<br><br>「エロサイトを見ている時に怪しい広告を踏むと&quot;このデバイスはウイルスに感染しています&quot;って表示されて、スマホがバイブレーションするときあるじゃないですか。アレです」<a href="https://twitter.com/hashtag/gigttt?src=hash&amp;ref_src=twsrc%5Etfw">#gigttt</a></p>&mdash; 内田一良（じきる）編集者 (@kazzikill) <a href="https://twitter.com/kazzikill/status/1108331944280899585?ref_src=twsrc%5Etfw">2019年3月20日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

---

## センシング形API

主にスマートフォンについているセンサにアクセスするAPIです。

### Geolocation API

* Webブラウザで、デバイスのGPS機能にアクセスすることが出来ます。いわゆる位置情報。
* `navigator.geolocation`でデバイスの位置情報にアクセスします。
* 市民権を得ていて、よく使われているイメージなので説明は省略。

---

### devicemotion イベント

* Webブラウザで、デバイスの加速度の値にアクセスすることが出来ます。加速度センサ。
* `window.addEventListener("devicemotion", res => console.log(res.acceleration));`でアクセスできる
	* navigatorオブジェクトに紐づいてないからここまでの流れで見ると少し異色
* その他、傾き(重力加速度)や回転値も取得できる。

---

## その他パラメータでアクセスできる機能逆引き

なんちゃらAPIみたいに市民権得てるネタ(メソッド)ではなく、ちょっとした値が取れるよ（プロパティ）くらいのものです。

---

### Webサイトを見ているデバイスが接続しているネットワーク情報を知る - `navigator.connection`

```js
console.log(navigator.connection);
```

> <img src="https://i.gyazo.com/83702ec11dd54153a89c268f913a7b11.png" width="400px">

* 回線の速度によって表示を変えたりに使えそう
	* 重いサイトであれば、速度が遅くなってるのでWiFiに接続してから試してね〜みたいな
	* インスタレーションっぽいサイトだったらパーティクルの数を制限してあげたり
	* 動画や画像を使うサイトであれば画質の調整をしたり

---

### Webサイトを見ているデバイスのCPUや性能情報

* 活用ポイントは先ほどのネットワーク情報と同様なイメージ
* PCスペックが低い人には買い替えを促す販促など

---

#### CPUの種類を知る - `navigator.platform`

```js
console.log(navigator.platform);
```

```
-> "MacIntel"
```

---

#### CPUのコア数を知る - `navigator.hardwareConcurrency`

```js
console.log(navigator.hardwareConcurrency);
```

```
-> 4
```

> CPUのコアが4つ

---

#### メモリを知る - `navigator.deviceMemory`

```js
console.log(navigator.deviceMemory);
```

```
-> 8
```

> 8Gのメモリってことですね。

---

### デバイスがオンラインかオフラインか - `navigator.onLine`

* デバイスがネットワークに繋がっていてオンラインならtrue、オフラインならfalseが返ってきます。
* true/falseの真偽値が返ってくるだけでシンプル

---

### デバイスがどれくらい同時タップ可能か - `Navigator.maxTouchPoints`

* Webブラウザから、デバイス（主にスマートフォン）の同時タップ数を知ることができる

---

### その他、名前はそれっぽいけど違かった子たち

> 全然調べてないから違かったらコメントください。

* navigator.locks
	* プロセスのロック的な話っぽい
* navigator.sendBeacon
	* いわゆるビーコンデバイスみたいな話ではなく、簡単なパケットを送る的なものっぽい

---

## 少し深くなっていく話

冒頭に紹介だけしたAPIに関して少し掘り下げて紹介

---

### WebBluetooth

* demo https://www.instagram.com/p/BtF5px2DxAP/
	* BLE対応の電球をブラウザから制御しています。
* [2019年2月版 JavaScript/Node.jsでBluetoothを触れるライブラリやAPIをまとめてみた](https://qiita.com/n0bisuke/items/67044681dec529c08191)の前半の方
	* WebBluetoothは現状ではPCのChromeとOperaで利用できるのと、AndroidのChromeで利用可能
* [話題のWebBluetoothでGenuino101をブラウザからリモートコントロールしてみよう](https://dotstud.io/blog/web-bluetooth-remote-blink/)
	* デバイス連携のアプリ開発（JavaやSwift）をやらなくとも、Webブラウザ（JavaScript）でBLEデバイスにアクセスできるようになるので、アプリ開発のコストが下がり、BLEデバイスがよりインターネットに繋がりやすくなる未来が示唆された。

---

### WebUSB

* [WebUSBを使ってブラウザのJavaScriptからArduinoを制御してみよう！](https://qiita.com/n0bisuke/items/b5a90ead155097dce484)
* WebBluetooth同様に、USBデバイス連携のドライバ開発(多分CとかC++)をやらなくとも、Webブラウザ（JavaScript）でUSBデバイスにアクセスできるようになるので、開発のコストが下がり、USBデバイスがよりインターネットに繋がりやすくなる未来が示唆された。

---

## Node.js方面に降りていく

* Node.jsはブラウザ以外でもJavaScriptを実行できるようにした実行環境
* ハードウェアに近いレイヤーになるので、より色々なデバイスの機能を扱える
* [2019年2月版 JavaScript/Node.jsでBluetoothを触れるライブラリやAPIをまとめてみた](https://qiita.com/n0bisuke/items/67044681dec529c08191)の後半の方の話

---

## Webサービスの話

その他、WebサービスのみでIoTっぽいことがやれそうな周辺サービス

---

### enebular

* https://www.enebular.com/ja/index.html
* IoTアプリケーション(プロトタイプ)をノンコーディングで作れるサービス
* 無料
* NodeREDを内包していてノード(機能毎のブロック)を組み合わせることでWebやデバイス連携のアプリケーションが組める

![](https://i.gyazo.com/3d23ea915dfbe05f2c175ad89f2b99c5.png)

---

### SkyWay

* https://webrtc.ecl.ntt.com/
* WebRTCをいい感じに使いやすくしてくれるサービス
* 無料

---

## まとめ

↑にも載せたまとめくらいですが、

* ブラウザのAPIでけっこう物理世界の何かを動かすことは出来る
* JavaScriptから入ってNode.jsまでいくとさらに広がる
* 細かい仕様とか深いところまで知らなくてもIoTっぽい内容に触れることは出来る

ってことが言いたかったです。

ブラウザ側からアクセスできることが増えると、セキュリティリスクが高くなるとはよく言われますが、その分開発のハードルは下がり、WebエンジニアやWeb制作者がやれる表現も増えていきます。

Web側の人からの目線では、PCやスマホの画面の中だけの話じゃなくて現実世界にアクセスする方法(API)が増えてきたな、どう活用しようって感じの手段の一つとして頭のどこかに残れば幸いです。

それでは！