package org.thingml.tradfri; import java.util.ArrayList; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.californium.core.CoapResponse; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class LightBulb { private ArrayList<TradfriBulbListener> listners = new ArrayList<TradfriBulbListener>(); public void addLightBulbListner(TradfriBulbListener l) { listners.add(l); } public void removeLightBulbListner(TradfriBulbListener l) { listners.remove(l); } public void clearLightBulbListners() { listners.clear(); } private TradfriGateway gateway; // Immutable information private int id; private String name; private JSONObject jsonObject; public JSONObject getJsonObject() { return jsonObject; } public int getId() { return id; } public String getName() { return name; } public String getType() { return type; } public boolean isOnline() { return online; } public boolean isOn() { return on; } public void setOn(boolean on) { try { JSONObject json = new JSONObject(); JSONObject settings = new JSONObject(); JSONArray array = new JSONArray(); array.put(settings); json.put(TradfriConstants.LIGHT, array); settings.put(TradfriConstants.ONOFF, (on)?1:0); String payload = json.toString(); gateway.set(TradfriConstants.DEVICES + "/" + this.getId(), payload); } catch (JSONException ex) { Logger.getLogger(TradfriGateway.class.getName()).log(Level.SEVERE, null, ex); } this.on = on; } public int getIntensity() { return intensity; } public void setIntensity(int intensity) { try { JSONObject json = new JSONObject(); JSONObject settings = new JSONObject(); JSONArray array = new JSONArray(); array.put(settings); json.put(TradfriConstants.LIGHT, array); settings.put(TradfriConstants.DIMMER, intensity); settings.put(TradfriConstants.TRANSITION_TIME, 5); String payload = json.toString(); gateway.set(TradfriConstants.DEVICES + "/" + this.getId(), payload); } catch (JSONException ex) { Logger.getLogger(TradfriGateway.class.getName()).log(Level.SEVERE, null, ex); } this.intensity = intensity; } public String getColor() { return color; } public void sendJSONPayload(String json) { gateway.set(TradfriConstants.DEVICES + "/" + this.getId(), json); } public void setRGBColor(int r, int g, int b) { double red = r; double green = g; double blue = b; // gamma correction red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92); green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92); blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); // Wide RGB D65 conversion // math inspiration: http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html double X = red * 0.664511 + green * 0.154324 + blue * 0.162028; double Y = red * 0.283881 + green * 0.668433 + blue * 0.047685; double Z = red * 0.000088 + green * 0.072310 + blue * 0.986039; // calculate the xy values from XYZ double x = (X / (X + Y + Z)); double y = (Y / (X + Y + Z)); int xyX = (int) (x * 65535 + 0.5); int xyY = (int) (y * 65535 + 0.5); try { JSONObject json = new JSONObject(); JSONObject settings = new JSONObject(); JSONArray array = new JSONArray(); array.put(settings); json.put(TradfriConstants.LIGHT, array); settings.put(TradfriConstants.COLOR_X, xyX); settings.put(TradfriConstants.COLOR_Y, xyY); settings.put(TradfriConstants.TRANSITION_TIME, 5); String payload = json.toString(); gateway.set(TradfriConstants.DEVICES + "/" + this.getId(), payload); } catch (JSONException ex) { Logger.getLogger(TradfriGateway.class.getName()).log(Level.SEVERE, null, ex); } } public void setColor(String color) { try { JSONObject json = new JSONObject(); JSONObject settings = new JSONObject(); JSONArray array = new JSONArray(); array.put(settings); json.put(TradfriConstants.LIGHT, array); settings.put(TradfriConstants.COLOR, color); settings.put(TradfriConstants.TRANSITION_TIME, 5); String payload = json.toString(); gateway.set(TradfriConstants.DEVICES + "/" + this.getId(), payload); } catch (JSONException ex) { Logger.getLogger(TradfriGateway.class.getName()).log(Level.SEVERE, null, ex); } this.color = color; } private String manufacturer; private String type; private String firmware; // Status private boolean online; // State of the bulb private boolean on; private int intensity; private String color; // Dates private Date dateInstalled; private Date dateLastSeen; public String getFirmware() { return firmware; } public Date getDateInstalled() { return dateInstalled; } public Date getDateLastSeen() { return dateLastSeen; } public LightBulb(int id, TradfriGateway gateway) { this.id = id; this.gateway = gateway; } public LightBulb(int id, TradfriGateway gateway, CoapResponse response) { this.id = id; this.gateway = gateway; if (response != null) parseResponse(response); } protected void updateBulb() { CoapResponse response = gateway.get(TradfriConstants.DEVICES + "/" + id); if (response != null) parseResponse(response); } protected void parseResponse(CoapResponse response) { boolean updateListeners = false; gateway.getLogger().log(Level.INFO, response.getResponseText()); try { JSONObject json = new JSONObject(response.getResponseText()); jsonObject = json; String new_name = json.getString(TradfriConstants.NAME); if (name == null || !name.equals(new_name)) updateListeners = true; name = new_name; dateInstalled = new Date(json.getLong(TradfriConstants.DATE_INSTALLED)*1000); dateLastSeen = new Date(json.getLong(TradfriConstants.DATE_LAST_SEEN)*1000); boolean new_online = json.getInt(TradfriConstants.DEVICE_REACHABLE) != 0; if (new_online != online) updateListeners = true; online = new_online; manufacturer = json.getJSONObject("3").getString("0"); type = json.getJSONObject("3").getString("1"); firmware = json.getJSONObject("3").getString("3"); JSONObject light = json.getJSONArray(TradfriConstants.LIGHT).getJSONObject(0); if (light.has(TradfriConstants.ONOFF) && light.has(TradfriConstants.DIMMER)) { boolean new_on = (light.getInt(TradfriConstants.ONOFF) != 0); int new_intensity = light.getInt(TradfriConstants.DIMMER); if (on != new_on) updateListeners = true; if (intensity != new_intensity) updateListeners = true; on = new_on; intensity = new_intensity; } else { if (online) updateListeners = true; online = false; } if (light.has(TradfriConstants.COLOR)) { String new_color = light.getString(TradfriConstants.COLOR); if (color == null || !color.equals(new_color)) updateListeners = true; color = new_color; } } catch (JSONException e) { System.err.println("Cannot update bulb info: error parsing the response from the gateway."); e.printStackTrace(); } if (updateListeners) { for (TradfriBulbListener l : listners) l.bulb_state_changed(this); } } public String toString() { String result = "[BULB " + id + "]"; if (online) result += "\ton:" + on + "\tdim:" + intensity + "\tcolor:" + color; else result += " ********** OFFLINE *********** "; result += "\ttype: " + type + "\tname: " + name; return result; } }