照明を制御[Processing -> Philips hue]_その3


開発環境


言語

- Processing 3.1.1

eclipseを使用し、core.jarをインポートした環境でコーディングしているため、ProcessingのIDEでは実行できません。

参考URL

http://hiroyukitsuda.com/archives/1721

- java 1.8.0_91

Processingで使用しているバージョン

API

- Apache HttpComponets Http Client 4.5.2

https://hc.apache.org/httpcomponents-client-ga/index.html

 

maven pom.xml

        <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.2</version>
        </dependency>

 

 

JSONObject 20160810

https://mvnrepository.com/artifact/org.json/json

 

maven pom.xml

        <dependency>
                <groupId>org.json</groupId>
                <artifactId>json</artifactId>
                <version>20160810</version>
        </dependency>

照明

- Philips Hue スターターセット v2

OS

- macOS sierra 10.12.2


Apache HttpComponentsのHttpClientを利用してPhillips APIへ連携


JAVAでHttpClientを実装

上述のApache HttpComponets Http Client 4.5.2を利用します。

 

- コンストラクタ

HTTPClientを生成

- GETメソッド

指定したURLにGETリクエストを送信し、レスポンスコードが200か判定し、レスポンスの内容を返す

- PUTメソッド

指定したURLに、パラメータを付与しPUT送信し、レスポンスコードが200か判定し、

レスポンスの内容をコンソールに出力

コード

package http;

import java.util.List;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;

public class Http {
        
        HttpClient client;
        
        public Http() {
                //ソケットタイムアウトに3秒を設定
                int socketTimeout = 3000;
                //コネクションタイムアウトに3秒を設定
                int connectionTimeout = 3000;
                //ユーザエージェント
                String userAgent = "processing_app";
                
                //設定を反映
                RequestConfig requestConfig = RequestConfig.custom()
                                .setSocketTimeout(socketTimeout)
                                .setConnectTimeout(connectionTimeout)
                                .build();
                
                //ヘッダー情報
                List<Header> headers = new ArrayList<Header>();
                headers.add(new BasicHeader("Accept-Charset","utf-8"));
                headers.add(new BasicHeader("Accept-Language","ja, en;q=0.8"));
                headers.add(new BasicHeader("User-Agent",userAgent));

                //HTTPクライアント生成
                client = HttpClientBuilder.create()
                                .setDefaultRequestConfig(requestConfig)
                                .setDefaultHeaders(headers).build();
        }
        
        public String httpGet(String url) {
                String responseStr = "";
                HttpGet getMethod = new HttpGet(url);

                try {
                        HttpResponse response = client.execute(getMethod);
                        int statusCode = response.getStatusLine().getStatusCode();
                        if(statusCode == HttpStatus.SC_OK){
                                HttpEntity entity = response.getEntity();
                                responseStr = EntityUtils.toString(entity,StandardCharsets.UTF_8);
                        }else{
                                System.out.println("failed access");
                        }
                } catch (ClientProtocolException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                }
                return responseStr;
        }
        
        public void httpPut(String url,String param) {
                HttpPut request = new HttpPut(url);
                StringEntity params = new StringEntity(param,"UTF-8");
                params.setContentType("application/json");
                request.addHeader("content-type", "application/json");
                request.addHeader("Accept", "*/*");
                request.addHeader("Accept-Encoding", "gzip,deflate,sdch");
                request.addHeader("Accept-Language", "en-US,en;q=0.8");
                request.setEntity(params);
                HttpResponse response;
                try {
                        response = client.execute(request);
                        int statusCode = response.getStatusLine().getStatusCode();
                        if(statusCode == HttpStatus.SC_OK){
                                HttpEntity entity = response.getEntity();
                                System.out.println(EntityUtils.toString(entity,StandardCharsets.UTF_8));
                        }
                } catch (ClientProtocolException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
}

ProcessingよりHTTPClientを使用し、hue APIへ連携

照明を制御[Processing -> Philips hue]_その2で作成したカラーパレットにコード追加し

hue APIと通信します。

1.setupメソッドでHttpClientを生成し、HueのIPアドレスを取得

 

        public void setup() {
//-----省略--------------------------------------------
                //httpClientを生成
                http = new Http();
                
                //hueのIPアドレスを取得
                hueIPaddress = getIPAddress();
                println(hueIPaddress);
        }

2.IPアドレス取得するメソッドを作成

https://www.meethue.com/api/nupnpに対して、

GETリクエストでレスポンスを受信します。

 

レスポンス内容 

[{"id":"xxxxxxxxxxxxxxxx","internalipaddress":"192.168.0.13"}]

「internalipaddress」キーにIPアドレスを設定されているのでJSONObjectを使用し取得します。

 

参照

照明を制御[Processing -> Philips hue]_その1

        public String getIPAddress() {
                String response = http.httpGet(
                                "https://www.meethue.com/api/nupnp");
                JSONArray jsonArray = new JSONArray(response);
                JSONObject jsonObject = jsonArray.getJSONObject(0);
                return jsonObject.getString("internalipaddress");
        }

3.PUTメソッドでライトを点灯

マウスでクリックした色を取得し、Phillips Hue APIに対応するJSON形式に整形し

PUT送信します。

        public void mousePressed() {
//-----省略--------------------------------------------
                //HSBカラーの形式に変換
                //色相をhueの色相範囲にマッピング
                int hue =  (int)map(hue(color), 0, 360, 0, 65535);
                //彩度を設定
                int saturation = (int)saturation(color);
                //輝度を設定
                int brightness = (int)brightness(color);

                //JSON形式に整形
                hueLight(lightnum, true, hue, saturation, brightness);
//-----省略--------------------------------------------
        }

次のURLに対して、ライト点灯に必要な色相、彩度、輝度を送信します。

http://{hueIPアドレス}/api/{ユーザ名}/lights/{電球のID}/state

 

詳細のレイアウトについては、その1の照明を制御を参照

照明を制御[Processing -> Philips hue]_その1

 

        //JSONのレイアウトに整形
        public void hueLight(int lightnum,boolean on,int hue,int saturation,int brightness) {
                jsonObject = new JSONObject();
                jsonObject.put("on", on);
                jsonObject.put("hue", hue);
                jsonObject.put("sat", saturation);
                jsonObject.put("bri", brightness);
                println(jsonObject.toString());
                String url = "http://" + hueIPaddress + "/api/" + hueUser + 
                                "/lights/" + lightnum + "/state";
                println(url);
                http.httpPut(url,jsonObject.toString()+"\r\n");
        }

結果

コード

package colorPalette;

import org.json.JSONArray;
import org.json.JSONObject;

import http.Http;
import processing.core.PApplet;

public class HSBcolorPalette extends PApplet{
        
        //半径の長さ
        int radius = 250;
        //角度の増加量
        int segmentCount = 360;
        //HSBカラーの彩度
        int saturation = 254;
        //HSBカラーの明度
        int brightness = 254;
        
        //lightナンバー
        int lightnum = 1;
        
        //Http client
        Http http;
        
        //hue APIのIPアドレス
        String hueIPaddress;
        //hue APIのユーザ名
        String hueUser = "bqpn9A3MgqjglZ-oKpfHyOgA2sRsIJs4qOu7RvKH";
        
        //hue連携用のJSONオブジェクト
        JSONObject jsonObject;
        
        public void settings() {
                size(600, 600);
        }
        
        public void setup() {
                noStroke();
                //背景色に黒色を指定
                background(0);
                
                //httpClientを生成
                http = new Http();
                
                //hueのIPアドレスを取得
                hueIPaddress = getIPAddress();
                println(hueIPaddress);
        }
        
        public void draw() {

                //カラーモードをHSBモードで指定
                //hue:色相を360°円周の範囲
                //Saturation:hueの彩度の範囲
                //brightness:hueの輝度の範囲
                colorMode(HSB,360,254,254);
                
                //角度の増加量
                float angleStep = 360/segmentCount;
                
                beginShape(TRIANGLE_FAN);
                
                //頂点を中心に設定
                vertex(width/2,height/2);
                for(float angle=0;angle<=360;angle+=angleStep){
                        float vx = width/2 + cos(radians(angle))*radius;
                        float vy = height/2 + sin(radians(angle))*radius;
                        vertex(vx,vy);
                        //angleの値を色相に設定
                        fill(angle,saturation,brightness);
                }
                endShape();
        }

        public void mousePressed() {
                
                //色情報を配列pixelsとして読み込む
                loadPixels();
                //マウスの座標位置を取得
                int x = constrain(mouseX, 0, width-1);
                int y = constrain(mouseY, 0, height-1);
                
                //マウスクリックした位置の色を取得
                int color = pixels[y*width + x];

                //HSBカラーの形式に変換
                //色相をhueの色相範囲にマッピング
                int hue =  (int)map(hue(color), 0, 360, 0, 65535);
                //彩度を設定
                int saturation = (int)saturation(color);
                //輝度を設定
                int brightness = (int)brightness(color);

                //JSON形式に整形
                hueLight(lightnum, true, hue, saturation, brightness);

                //背景色をマウスクリックした色に設定
                background(color);
        }
        
        //JSONのレイアウトに整形
        public void hueLight(int lightnum,boolean on,int hue,int saturation,int brightness) {
                jsonObject = new JSONObject();
                jsonObject.put("on", on);
                jsonObject.put("hue", hue);
                jsonObject.put("sat", saturation);
                jsonObject.put("bri", brightness);
                println(jsonObject.toString());
                String url = "http://" + hueIPaddress + "/api/" + hueUser + 
                                "/lights/" + lightnum + "/state";
                println(url);
                http.httpPut(url,jsonObject.toString()+"\r\n");
        }
        
        public void keyPressed() {
                
                //輝度を変更
                if(keyCode == RIGHT) brightness += 10;
                if(keyCode == LEFT) brightness -= 10;
                brightness = max(brightness,0);
                brightness = min(brightness,254);
                //彩度を変更
                if(keyCode == UP) saturation += 10;
                if(keyCode == DOWN) saturation -= 10;
                saturation = max(saturation,0);
                saturation = min(saturation,254);
                //角度の増加量を変更
                if(key == 'a') segmentCount += 10;
                if(key == 'd') segmentCount -= 10;
                segmentCount = min(segmentCount,360);
                segmentCount = max(segmentCount,1);
                
                //制御するlightを設定
                if(key == '1') lightnum = 1;
                if(key == '2') lightnum = 2;
                if(key == '3') lightnum = 3;
                
        }
        
        public String getIPAddress() {
                String response = http.httpGet(
                                "https://www.meethue.com/api/nupnp");
                JSONArray jsonArray = new JSONArray(response);
                JSONObject jsonObject = jsonArray.getJSONObject(0);
                return jsonObject.getString("internalipaddress");
        }
        
        public static void main(String[] args) {
                PApplet.main(HSBcolorPalette.class.getName());
        }
}