iOSアプリと連携させて使えるデバイスたち

第3回1,600万色の表現力をもつLED電球「hue」連携するiOSアプリをつくる その1:基礎編

hueとは

「Philips hue」は、1,600万色を超える色彩表現が可能なLED電球です。iOS、MacOS X、Android用のSDKが用意されており、スマートフォンアプリから制御することが可能です。

Philips hue
Philips hue

点けたり消したり、色を変えたりできるアプリが用意されている、というだけでなくて、SDKが用意されている、というところがポイントです。

たとえばiOS SDKがあるということは、位置情報やWeb APIなど、iOSデバイスで利用できるあらゆる機能と連携できることを意味します。

一例を挙げますと、undaというビデオメッセージングアプリを提供するスタートアップでは、オフィスでhueを次のように利用していました。

undaでの使用例
undaでの使用例

写真だけではわかりませんが、こちら、undaに新しいユーザが増えるたびに光るようになっています。ビデオメッセージが送られたときはオレンジ色に光ります。解析サービスや管理画面にアクセスしなくても、アプリがどのくらい広がっていて、使われているかが一目瞭然で、非常におもしろい事例ではないでしょうか。

Web APIだけでなく、iOSと連携する他のデバイスと組み合わせて使用することも可能なので、たとえば目標距離以上ランニングしないと明かりが消えないとか、WithingsのWiFi体重計と組み合わせて食べ過ぎると赤いランプが光るといった可視化にも使えますし、そもそも普通の電球は色をhueのように自在に変えられないので、そこだけでも店舗でのディスプレイやライブの演出等の場面でニーズがありそうです。

ちなみにhueはE26という一般的な電球と同様の規格に則っているので、E26口金を持つ従来の照明器具に取り付け可能な点もポイントです。

今回の「その1」では、HueSDKを導入したプロジェクトの作成方法から、基本的な機能の実装方法を一通り説明し、次回「その2」で、hueとiOSデバイスの様々な機能を連携させた応用事例の実装方法を説明します。

購入方法

日本国内における正規輸入品はアップルストアで購入可能です。

スターターセット以外に、ランプ単体も販売されていますが、使用にはブリッジが必要なので、まず最初はスターターセットを購入することになります。

⁠2014年1月27日追記⁠

2014年1月26日より、Amazonでも日本仕様正規品が購入できるようになりました。

  • Amazon.co.jp: Philips hue(ヒュー) スターターセット [フラストレーションフリーパッケージ(FFP)]: パソコン・周辺機器
  • hue以外に必要なもの

    E26電球を取り付けられる器具が必要です。家庭にE26口金を持つ照明器具がない場合は、コード付きソケットが安価で購入できるのでおすすめです。

    また、有線LANポートを持つWi-Fiルータが必要です。有線LANポートのないPocket Wi-Fi端末等では試せないのでご注意ください。そういった場合には、有線LANポートを持つ無線LAN中継機を使うという手もあります。

    まずはプログラミングなしで試してみる

    AppStoreからダウンロードできる公式アプリがよくできており、セットアップ(ブリッジとの接続)から色のコントロール、タイマーからの制御、GPSと連携したOn/Offなど一通りの機能が体験できるようになっています。

    公式アプリの実行画面
    公式アプリの実行画面

    対応アプリの実装準備

    ①SDK一式を取得する

    hueのデベロッパーサイト、もしくはGitHubリポジトリから最新バージョンのSDKをダウンロードします。

    ②プロジェクトを作成する

    よくあるSDKの導入方法としては、HueSDK_iOS.framework をプロジェクトに追加して、依存フレームワークをリンクして……となるのですが、hueの場合はエンドユーザがアプリを使用する際に、ブリッジとアプリを接続する手順を踏んでもらう必要があり、それらの内部処理やユーザインタフェースを自前で実装するには少々煩雑な実装をする必要があります。

    まず手っ取り早くhueをコントロールするアプリを自作したい場合には、SDK一式の中に入っている、QuickStartApp_iOSというプロジェクトを使用するのが近道です。

    "QuickStartApp_iOS"はブリッジとアプリを接続するまでの最低限の機能が実装されているだけのプロジェクトです。

    ブリッジ接続に必要な処理/UIが実装済み
    ブリッジ接続に必要な処理/UIが実装済み

    まずはこれを複製・リネームし、不要なテスト用UIパーツ(Randomize LightボタンやIPアドレス表示用のラベル等)を削除します。ディレクトリを移動させて使用する場合は、HueSDK_iOS.frameworkとLumberjack(フォルダごと)を追加しなおします。

    これで、hue対応アプリを作成する準備は完了です(ブリッジを探して接続するところまでの機能が既にできている状態⁠⁠。

    ライトの色相、彩度、明度を制御する

    hueのライトの色を変えたり、明るさを変えたり、といった制御は非常にシンプルです。

  1. ライトのオブジェクト(PHLightオブジェクト)を取得する
  2. ライトの色相や彩度等といった状態のオブジェクト(PHLightState)を作成する
  3. 1で取得したライトオブジェクトに、2で作成した状態オブジェクトを送信する

の3ステップです。

// PHLightオブジェクトを取得
PHBridgeResourcesCache *cache = [PHBridgeResourcesReader readBridgeResourcesCache];
PHLight *light = [cache.lights.allValues firstObject];

// PHLightStateオブジェクトの設定
PHLightState *lightState = [[PHLightState alloc] init];
[lightState setHue:@10000];
[lightState setBrightness:@100];
[lightState setSaturation:@254];

// ライト(PHLightオブジェクト)に新しい状態(PHLightStateオブジェクト)を送信
id bridgeSendAPI = [[[PHOverallFactory alloc] init] bridgeSendAPI];
[bridgeSendAPI updateLightStateForId:light.identifier
                       withLighState:lightState
                   completionHandler:^(NSArray *errors)
 {
     // 送信完了時の処理
 }];

上記では、簡単のためライトが1つだけの場合を想定したコードになっていますが、ライトが3つある場合は、cache.lights.allValuesに3つのPHLightオブジェクトが入ってきます。

hue(色相⁠⁠、saturation(彩度⁠⁠、brightness(明度)はそれぞれ以下の範囲で設定できます。

  • hue: 0 - 65535(0~360度に相当する)
  • saturation: 0(白⁠⁠ - 254(もっとも鮮やか)
  • brightness: 0 ⁠もっとも暗い⁠⁠ - 254(もっとも明るい)

ライトの状態を取得する

ライトの状態を取得するには、

  1. ライトのオブジェクト(PHLightオブジェクト)を取得する
  2. 1のlightStateプロパティよりライトの状態のオブジェクト(PHLightStateオブジェクト)を取得する

と非常にシンプルですが、そこから取得できる色情報は、CIE 1931 表色系(XYZ表色系)のため、そのままではUIColorオブジェクトを生成できません。

そこで、HueSDKに用意されているユーティリティクラス PHUtilities を使用して変換します。

CGPoint xyColor = CGPointMake([light.lightState.x floatValue], [light.lightState.y floatValue]);
UIColor *color = [PHUtilities colorFromXY:xyColor
                                 forModel:light.modelNumber];

これで、ライトの現在の色をUIView等に反映することができます。

ライトをOn/Offする

On/Offの制御も、PHLightStateプロパティを使用するだけです。

// PHLightオブジェクトを取得
PHBridgeResourcesCache *cache = [PHBridgeResourcesReader readBridgeResourcesCache];
PHLight *light = [cache.lights.allValues firstObject];

// 現在のon/off状態を取得
BOOL isOn = light.lightState.on.boolValue;

// PHLightStateオブジェクトの設定
PHLightState *lightState = [[PHLightState alloc] init];
[lightState setOnBool:!isOn];

// ライト(PHLightオブジェクト)に状態(PHLightStateオブジェクト)を送信
id bridgeSendAPI = [[[PHOverallFactory alloc] init] bridgeSendAPI];
[bridgeSendAPI updateLightStateForId:light.identifier
                       withLighState:lightState
                   completionHandler:^(NSArray *errors)
 {
     // 送信完了時の処理
 }];

上記コードでは、現在の状態を取得して、on/offをトグルさせています。

エフェクトモード

PHLightStateのeffectプロパティに、エフェクトモードを指定することができます。

現状では以下の値が定義されており、

typedef enum {
    EFFECT_UNKNOWN, // It is unknown what the current effect value is
    EFFECT_NONE, // No effect active
    EFFECT_COLORLOOP // Colorloop effect (loop through colors whith current saturation and brightness)
} PHLightEffectMode;

実質的にエフェクトとして効果があるものは"EFFECT_COLORLOOP"のみとなります。EFFECT_COLORLOOPは、ライトの色相がゆっくりと変化するエフェクトです。

EFFECT_COLORLOOPとEFFECT_NONEをトグルさせるコードは次のようになります(繰り返しになるので、ライトオブジェクトの取得やライトへの状態送信は省略します⁠⁠。

// 現在のエフェクトモードを取得
PHLightEffectMode currentMode = light.lightState.effect;

// PHLightStateオブジェクトの設定
PHLightState *lightState = [[PHLightState alloc] init];
lightState.effect = currentMode != EFFECT_COLORLOOP ? EFFECT_COLORLOOP : EFFECT_NONE;

アラートモード

PHLightStateのalertModeプロパティに値を指定することで、アラートのようにライトを明滅/点滅させることができます。

現状でのPHLightAlertModeの定義は次のようになっており、

typedef enum {
    ALERT_UNKNOWN, // It is unkown what the current alert value is
    ALERT_NONE, // No alert active
    ALERT_SELECT, // Select alert (1 breath cycle) is active
    ALERT_LSELECT // Select alert (30 seconds of breath cycles) is active
} PHLightAlertMode;

ALERT_SELECTは1回だけ明滅するモード、ALERT_LSELECTは30秒間明滅するモードです。

アラートなし→ALERT_SELECT→ALERT_LSELECTとトグルさせるコードを示します。

PHLightState *lightState = [[PHLightState alloc] init];
switch (light.lightState.alert) {
    case ALERT_SELECT:
        lightState.alert = ALERT_LSELECT;
        break;

    case ALERT_LSELECT:
        lightState.alert = ALERT_NONE;
        break;
        
    default:
        lightState.alert = ALERT_SELECT;
        break;
}

スケジューリング

n秒後に状態を変化させる

n秒後にoffにする、といったスケジューリングは、PHLightStateのtransitionTimeプロパティに値をセットするだけです。

たとえば5秒後にoffにしたい場合は、次のようなコードになります。

PHLightState *lightState = [[PHLightState alloc] init];
[lightState setTransitionTime:@(50)];   // 5秒後に
[lightState setOnBool:NO];              // offにする

transitionTimeに渡す値は100ms単位です。すなわち、10を渡すと1sを意味します。

日時を指定する

NSDateオブジェクトを使用して日時を指定してライトの状態を変化させるには、PHScheduleクラスを使用します。

初めて出てくるクラスですが、PHScheduleのstateプロパティに、変化させたいライトの状態(PHLightState)を指定するだけなので非常に簡単です。

// PHLightオブジェクトを取得
PHBridgeResourcesCache *cache = [PHBridgeResourcesReader readBridgeResourcesCache];
PHLight *light = [cache.lights.allValues firstObject];

// PHLightStateオブジェクトを生成
PHLightState *lightState = [[PHLightState alloc] init];
lightState.alert = ALERT_LSELECT;

// PHScheduleオブジェクトを生成
PHSchedule *schedule = [[PHSchedule alloc] init];
schedule.date = [NSDate dateWithTimeInterval:60.0
                                   sinceDate:[NSDate date]];;
schedule.lightIdentifier = light.identifier;
schedule.state = lightState;

// スケジュールを送信
id bridgeSendAPI = [[[PHOverallFactory alloc] init] bridgeSendAPI];
[bridgeSendAPI createSchedule:schedule
            completionHandler:
 ^(NSString *scheduleIdentifier, NSArray *errors)
 {
     // 送信完了時の処理
 }];

上記は、現在時刻より60秒後にライトを明滅させるサンプルですが、PHScheduleでは日時をNSDateで指定できるので、NSDatePickerを使用して「◯月○日◯時○分にライトの状態を変化させる」といった指定も簡単にできます。

まとめ

自作iOSアプリから自由に制御できるライト『hue⁠⁠ をを紹介しました。E26という「普通の電球と同じように使える」規格であることと、iOS SDKにより「連携iOSアプリを自作できる」ことにより、Web APIや、他のiOS連携デバイスと組み合わせて使用できるので、非常に多くの可能性を秘めているデバイスだと思います。

今回はさまざまな対応アプリを実装するにあたって基本となるライトの制御方法を説明しました。次回は、今回の基礎編を踏まえた応用編として、iOS7の新機能+Parse+hueを使ったアプリの実装方法を説明する予定です。お楽しみに!

おすすめ記事

記事・ニュース一覧