【解説】スマート電球HueのAPIをNodejsで呼び出してみた!プログラムからHueを操作する方法
こんにちは!しずかなかずしです。
スマート電球という、スマホで操作できる電球があるのをご存知ですか?
そして、フィリップスのHueというスマート電球は、プログラミングで自由に操作できるって知っていましたか?
こういうのIoTというのです。
そうなんです。IoTってすごいのです。
本日は、HueのAPIをプログラムから操作する解説をしていきたいと思います。
Hueスマート電球とは
スマート電球というものがあります。普通の電球のように見えて、実は賢いのでスマート電球。
世は、IoT(Internet of Things: もののインターネット)が流行っています。モノとモノがインターネットを介してつながる世界です。
今までもパソコン同士がインターネットで繋がってたじゃん、という方もいるかも知れません。
でも、そういう意味ではないのです。電球とかコンセントとか、掃除機(!)とか単品機能のモノがインターネットアドレスを持ちます。そして、ネットワークを介してそれぞれの機能が有機的に影響し合いながら便利なことができる世の中です。
本日は、IoTの機器の中でもちょっとイカしたフィリップス(Philips)のHueという電球を取り上げます。
「フィリップスって、むかしソニーと一緒にCDを開発した、あのフィリップですか??」という方、イエスですが、想い出が古いですね。今や、フィリップスはIoT最先端企業。Hueは、「IoTといえば、Hue」と言えるほど代表的なデバイスなんです。
Hueは普通の電球に使うE26ソケットに差し込んで使うものです。
もちろんLED電球として光るのですが、単なる電球色ではなく、さまざまな色で発色する機能を持っています。その色はどのように変えるかと言うと、スマホのアプリから操作して変更できます。ネット経由で操作できるのです。
最初に使ったときはちょっと感動しますよ。
そのネットワークで動作するための電源をどこから取るかと言うと電球のE26ソケットです。なので、例えばご自宅のどこかの電球をこのHue電球に取り替えることは可能なのですが、照明用のスイッチは常時オンの状態にしておく必要があります。スイッチはオンですが、スマホから「消す」事ができるのです。
Philips Hue(ヒュー)スターターセットv3 スマートLEDライト 【Amazon Alexa、Google Home、Apple HomeKit、LINE対応】
APIでプログラムから操作してみよう
フィリップスはAPIを開発者向けに公開しています。
Webベース(JSONベース)のAPIでHTTPプロトコルを使って操作できます。SDKもあるようですが、APIは、HTTP+JSONなので、JavascriptやPythonなどから簡単に操作できますね。
ちょっと実験をして見たいと思います。
広告
HueのAPIの仕組み
スマート電球Hueは、実は電球だけでは動作しません。
下記のように、「ブリッジ」と呼ばれれる中間装置が必要です。Hueを購入するときには、電球だけでも購入できますが、まずは、ブリッジとセットになったパッケージを購入するのが良いででしょう。
操作するには、以下の2つの段階が必要になります。
- ホームネットワークから「ブリッジ」を探す
- 「ブリッジ」からHTTP+JSONでUsernameを得る
- 「ブリッジ」経由でHTTP+JSONを呼び出し電球を操作する
それぞれ説明していきます。
ブリッジをホームネットワークから探すには?
まずは、ホームネットワークにあるブリッジのアドレスを得る必要があります。いわゆる、デバイス「ディスカバリ(discovery)」という手順です。
なんらかの方法で、操作対象となるブリッジのIPアドレスを見つけなければなりません。
フィリップスの開発者サイトには、ディスカバリについて詳しく書かれています。
フィリップスの開発者向けサイト: Hue Bridge Discovery
上記のページにあるやり方をざっと整理しますと、以下の方法のようにブリッジのIPアドレスがアドレスを見つけるのに複数の方法が用意されています。
- UPnPで探す: SSDP(simple service discovery protocol)を使って、マルチキャストに応答するブリッジからIPアドレスを取得します。
- N-UPnPで探す: ブリッジは、定期的にフィリップスのサーバに「生きてますよ」メッセージを投げるようです。その中にローカルのIPアドレスが含まれていて、https://discovery.meethue.com にアクセスすることでそれがJsonで得られます。
- IP scanで探す: ホームネットワークのIPアドレスをスキャンしてブリッジを探します(時間がかかります)
- 手動でIPアドレスを設定する: 使っている人自身がブリッジのIPアドレスを決めているような場合は、それを使います。
- mDNSで探す: multicast DNSを使って取得するHueのホスト名からIPアドレスを割り出します。
製品化レベルのアプリケーションでは上記のフローを一通りトライしてみて、アドレスを解決するようにガイドラインにはフローチャートが書かれています。
ただ、今回は実験レベルなので、もっとも簡単に実装できそうなN-UPnPでの方法をご説明します。
N-UPnPでブリッジを探す
この方法では、ブラウザで、https://discovery.meethue.comにアクセスすると、以下のようにJSONでIDと、internalipaddressが返ってきます。複数ブリッジが存在するケースを想定して、リスト形式になっています。
[{"id":"XXXXXXX","internalipaddress":"10.0.0.11"}]
ちょっとしたJavaScriptのプログラムを書くと、こんな風にブリッジのアドレスがとれます。
var request = require('request');
request.get({ url: "https://discovery.meethue.com/" },
function (error, response, body) {
if (!error) {
var myhue = JSON.parse(body);
console.log('ipaddress: ' + myhue[0].internalipaddress);
}
}
);
このスクリプトをNode.Jsで実行すると、以下の様のにアドレスが取得できます。(上記スクリプトがtest_hue_discover.jsに記載されています)
kazushi$ nodejs test_hue_discovery.js
ipaddress: 10.0.0.11
広告
開発者向けのツールを操る
IPアドレスがわかったら、Webブラウザで、そのアドレスのページを開くことが出来ます。(ここでは、上記のブリッジを探した結果として、ブリッジのローカルのIPアドレスが10.0.0.11だとわかった場合を想定てしいます)
http://10.0.0.11/debug/clip.html
これをブラウザで叩くとブリッジの開発者向けの画面が出てきます。
HTTP+JSONでUsernameを得る
さて、次に行うことは、上記の開発者向け画面を使って、Usernameというものを得ることです。ブリッジはさまざまなアプリケーションがブリッジにつながることを想定して、電球を操作するAPIのURLをユーザ毎に用意する仕組みになっているようです。
例えば、電球の情報を得るためには、
https://<bridge ip address>/api/<username>/lights
のように、APIのURLをにusernameを指定する必要があります。username(ユーザ名)とは名ばかりで、アルファベットと数字・記号の複雑なIDです。このIDはブリッジがクライアント(アプリ)毎に生成するので、それを一番最初に取得する必要があります。
実際の方法です。
まず、URLとして、以下を入力し、
/api/newdeveloper
画面上のPOSTボタンを押します。
このような感じで、unauthorized userというエラーが表示されます。(Command Responseの枠に表示されるのがブリッジからのレスポンスです)
ここで、おもむろに、ブリッジ本体の「丸い」ボタン(画面上のボタンではなく、本物のボタンのことです)を押します。
次に、以下を入力し、
/api
画面上のPOSTボタンを押します。
successとなり、"username"として、謎の文字列が返ってきます。以降、Hueの電球を操作するときに使うURLにはこのUsernameが必須になりますので、書き留めておいてください。
HTTP+JSONで電球を操作する
これでいよいよ、電球を操作する準備ができました。
まずは、ブリッジに紐付いている電球の情報を取得してみましょう。以下を入力して
/api/IEEFt3GjndPzYURRIVwDlz42NCiJIuHbd-UMTh07/lights
画面上のGETボタンを押します。/api/と/lightsの間の謎な文字列が、先程の工程でブリッジから取得したUsername文字列です。
以降、この文字列をURLに含めてAPIを呼び出すことになります。
電球が光っていない("state"の"on"がfalseになっている)事がわかります。
Node.jsでHueのAPI呼んでみよう
では、この辺りから、Node.jsのプログラムでHue電球のAPIを呼んでみることにします。APIの仕様は、以下にあります。
フィリップス開発者向けサイト: Hue API – 1. Lights API (英語)
最もシンプルにNode.jsで、On/offするには以下のようなプログラムで可能です。
var request = require('request');
var command = {on: false};
command.on = true;
command.bri = 50;
command.hue = 1200;
request.put({
url: "http://10.0.0.11/api/IEEFt3GjndPzYURRIVwDlz42NCiJIuHbd-UMTh07/lights/2/state",
headers: {
'Content-Type':'application/json'
},
body: JSON.stringify(command)
},
function (error, response, body) {
console.log(body);
}
);
上記のプログラムの解説を簡単にします。
'request’というのは、Node.jsでHTTPを使うモジュールです。request.put()としている部分(8行目)は、実際にHTTPのリクエストを出しています。リクエストを出す先の"url"で指定しているURL。ここが1番目のポイントになりますが、API仕様で以下のようなURLの説明を見てみてください。
http://<bridge IP address/api/<username>/lights/2/state
これは2番目の電球のstateを操作するURLをになります。2のところを1にすれば1番目の電球の操作するURLになります。簡単かつ、よくできていますね。
2番目のポイントは、commandと書いている変数です。
12行目にJSON.stringify()でJSON形式の文字列に変換して、HTTP requestのbodyに指定しています。JSON(JavaScript Object Notation)形式なので、JavaScriptで扱うには非常に便利。commandオブジェクトのフィールドにAPIが定義しているパラメータをそのまま使って操作することが出来ます。
上記のAPI説明ページに一覧があります。その中のいくつかを抜粋して以下で説明します。
名前 | タイプ | 意味 |
on | bool | trueで電球がつく、falseで電球が消える |
bri | uint8 | 1から254までの値で明るさを表現(明度) |
hue | uint16 | 0から65535の範囲で色相を表現 |
sat | uint8 | 0から254の範囲で彩度を表現 |
xy | floatの配列 | [0.5,0.5]のように0から1の浮動小数点配列で、CIE色空間の座標を表現 |
colormode | string | 色の指定が、hsでHue,Satuationのモード。xyでXY座標系のモード指定 |
ですので、上のcommandの変数のフィールドを追加して、 例えばcommand.xy = [0.5, 0.5]のように記載すると、そのままサーバに値を送れる、という訳です。(JSONって便利!)
広告
Hue電球の色の指定しよう
色の指定はいくつか方法がありますが"xy"というフィールドで指定してみましょう。xyはCIE色空間の座標値、ということなので、Wikipediaにある色空間の2次元マップから、適当にxとyの値を取り出してみます。Wikipedia: CIE 1931 色空間
ざっくり、座標から、[0.7, 0.3]くらいが赤っぽい色だってことがわかります。ですので、例えば、command = {on: true, bri: 128, xy:[0.7, 0.3]} みたいに記載すると、赤で明るさが半分ぐらいで光ってくれます。
別のやり方として、RGBから変換する方法もフィリップスの開発者向けサイトにあります。
フィリップス開発者向けサイト: Color Conversion Formulas RGB to XY and back(英語)
ただ、値がHue電球の色域(gamut)からはみ出ちゃったときの処理が面倒そうです。Hueは電球だけではなく、いろんな製品があってそれらをサポートするように作ろうとすると、各製品がサポートしている色域を考慮してね、ということでした。
セキュリティ対策もばっちり
話は変わりますが、2020年2月にHue ブリッジに脆弱性が見つかったことがニュースになりました。
しかし、さすがは大手のフィリップ。あっという間に解決。ネットにつながるHueブリッジは、自動的に更新プログラムでアップデート。ユーザが知らぬ間に対策されているいう状況です。セキュリティ対策もばっちり、という記事も合わせてごらんください。
まとめ
- スマート電球HueをNode.jsを使って、JavaScriptで操作してみました。電球のオフ・オンだけではなく、色もAPIで変えられます
- 電球のAPIはWebベースで、HTTP+JSONなので、JavaScriptから簡単にパラメータを指定して呼び出すことが可能です
- 準備として、ブリッジのIPアドレスの取得、続いて、APIを呼び出すためのUsernameという謎の文字列の取得が必要です
- 電球の色の指定はちょっとめんどくさい。CIE色空間を使って見ましょう
- IoT大手のフィリップスの商品だけあって、セキュリティ対策もばっちり
Philips Hue(ヒュー)スターターセットv3 スマートLEDライト 【Amazon Alexa、Google Home、Apple HomeKit、LINE対応】