Showing preview only (355K chars total). Download the full file or copy to clipboard to get everything.
Repository: SteveyO/Hue-Emulator
Branch: master
Commit: cf55ade25681
Files: 69
Total size: 334.4 KB
Directory structure:
gitextract_j346hbtz/
├── .classpath
├── .gitignore
├── .project
├── CHANGELOG.md
├── HueEmulator-v0.1.jar
├── HueEmulator-v0.2.jar
├── HueEmulator-v0.3.jar
├── HueEmulator-v0.4.jar
├── HueEmulator-v0.5.jar
├── HueEmulator-v0.6.jar
├── HueEmulator-v0.7.jar
├── HueEmulator-v0.8.jar
├── README.md
├── libs/
│ ├── jackson-core-asl-1.9.12.jar
│ ├── jackson-mapper-asl-1.9.12.jar
│ └── junit-4.11.jar
├── resources/
│ ├── config-3bulbs.json
│ └── description.xml
├── src/
│ ├── com/
│ │ └── hueemulator/
│ │ ├── emulator/
│ │ │ ├── Constants.java
│ │ │ ├── Controller.java
│ │ │ ├── Emulator.java
│ │ │ ├── HueEmulator.java
│ │ │ ├── Model.java
│ │ │ ├── PHScheduleTimer.java
│ │ │ └── PHScheduleTimerManager.java
│ │ ├── gui/
│ │ │ ├── About.java
│ │ │ ├── GraphicsPanel.java
│ │ │ ├── Help.java
│ │ │ ├── HueMenuBar.java
│ │ │ ├── LightsFrame.java
│ │ │ ├── PropertiesFrame.java
│ │ │ └── View.java
│ │ ├── model/
│ │ │ ├── PHBody.java
│ │ │ ├── PHBridgeConfiguration.java
│ │ │ ├── PHCommand.java
│ │ │ ├── PHConfig.java
│ │ │ ├── PHGroupsEntry.java
│ │ │ ├── PHLight.java
│ │ │ ├── PHLightState.java
│ │ │ ├── PHScenesEntry.java
│ │ │ ├── PHSchedulesEntry.java
│ │ │ ├── PHSwupdate.java
│ │ │ └── PHWhitelistEntry.java
│ │ ├── server/
│ │ │ ├── MyApiHandler.java
│ │ │ ├── MyRootHandler.java
│ │ │ ├── Server.java
│ │ │ ├── UPNPServer.java
│ │ │ └── handlers/
│ │ │ ├── ConfigurationAPI.java
│ │ │ ├── GroupsAPI.java
│ │ │ ├── LightsAPI.java
│ │ │ ├── ScenesAPI.java
│ │ │ └── SchedulesAPI.java
│ │ └── utils/
│ │ ├── HueColor.java
│ │ ├── OpenFileFilter.java
│ │ ├── PHUtilitiesHelper.java
│ │ ├── PointF.java
│ │ └── Utils.java
│ └── org/
│ └── json/
│ ├── JSONArray.java
│ ├── JSONException.java
│ ├── JSONObject.java
│ ├── JSONString.java
│ └── JSONTokener.java
└── tests/
└── com/
└── hueemulator/
├── emulator/
│ ├── HttpTester.java
│ └── TestEmulator.java
├── lighting/
│ └── utils/
│ └── TestUtils.java
└── server/
└── handlers/
├── TestConfigurationAPI.java
├── TestGroupsAPI.java
├── TestLightsAPI.java
└── TestSchedulesAPI.java
================================================
FILE CONTENTS
================================================
================================================
FILE: .classpath
================================================
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="tests"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="libs/jackson-core-asl-1.9.12.jar"/>
<classpathentry kind="lib" path="libs/jackson-mapper-asl-1.9.12.jar"/>
<classpathentry kind="lib" path="libs/junit-4.11.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
================================================
FILE: .gitignore
================================================
/bin
================================================
FILE: .project
================================================
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>hueemulator</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
================================================
FILE: CHANGELOG.md
================================================
Hue-Emulator Changelog
============
v0.8 (18-March-2018)
* Merged in the 4 open pull requests.
v0.7 (04-December-2015)
* Fixed bug with JSON Response when deleting groups.
* Get Groups and Get Schedules now returns full (more) JSON. Full schedules response is still missing some fields though.
v0.6 (01-December-2015)
* Cherry picked some of the UPUP Handling code (by bwssystems). In particular now have 2 web contexts so can display the bridge description.xml file at the correct URL.
* Added another 'Small Bulbs' graphical view so you can now see many (50+) more bulbs in the emulator.
* Added Uniqueid in lights
* Removed all Philips logos from the bulb graphics, so am no free to choose my own license for the emulator.
* Added 'Add Hue Lux Bulb' option.
New Features:
---
* Removed possibility to create Custom WhiteList Entries + Added Randomly Generated Username. This change was done because in December 2015/January 2016 the Philips Bridge will no longer accept Custom Whitelist Entries, so I want developers to get into the habit of using the Randomly Generated Username.
v0.5 (02-September-2015)
New Features:
---
* Removed possibility to create Custom WhiteList Entries + Added Randomly Generated Username. This change was done because in December 2015/January 2016 the Philips Bridge will no longer accept Custom Whitelist Entries, so I want developers to get into the habit of using the Randomly Generated Username.
New Features:
---
* Can now load and save different bridge JSON configs (e.g. for testing with different number of bulbs).
* Removed out-dated help web pages. API docs should be viewed on: http://www.developers.meethue.com/philips-hue-api
v0.3 (23-January-2015)
New Features:
---
* Retrieving the lights now retrieves the full lights resource as per 1.3 bridges.
Bug Fixes:
---
* Retrieving lights resource doesn't retrieve a LightIdentifer: null and TransitionTime: null anymore, these have been removed.
v0.2 (01-December-2014)
New Features:
---
* UPNP Server. 1st attempt. If you run the Emulator on Port 80 (if not blocked) some hue apps now work out of the box :-)
* Added Create User + Pushlink functionality (you must click the bridge icon to simulate pushlinking)
* Started Scenes implementation. Get Scenes and Create Scenes functionality added + recall scenes. Not 100% tested.
* Can now configure which JSON Strings to show in console (i.e. Requests, Responses, Full Config).
* Re-ordered some of the JSON to be more consistent with a hue bridge
Bug Fixes:
---
* Software version is now a string (not an integer).
* Clear console should now work.
* Added transition time (attribute only, not bulb transitions).
================================================
FILE: README.md
================================================
Hue-Emulator
============
The Hue Emulator is a Bridge Emulator for the Philips Hue - Personal Wireless System.
It allows developers who don't have access to a Philips Hue system (i.e. A Bridge + Hue Light Bulbs) to write hue apps.
For more information visit the main project page:
http://steveyo.github.io/Hue-Emulator
<img src="screenshot.png" />
Note: As some of you may have noticed, this project is no longer maintained so bear this in mind before using! Steve!
================================================
FILE: resources/config-3bulbs.json
================================================
{
"lights": {
"1": {
"state": {
"on": true,
"bri": 254,
"hue": 4444,
"sat": 254,
"xy": [0.0000, 0.0000],
"ct": 0,
"alert": "none",
"effect": "none",
"colormode": "hs",
"reachable": true
},
"type": "Extended color light",
"name": "Hue Lamp 1",
"modelid": "LCT001",
"swversion": "65003148",
"uniqueid": "00:17:88:01:00:d4:12:08-0a",
"pointsymbol": {
"1": "none",
"2": "none",
"3": "none",
"4": "none",
"5": "none",
"6": "none",
"7": "none",
"8": "none"
}
},
"2": {
"state": {
"on": true,
"bri": 254,
"hue": 23536,
"sat": 144,
"xy": [0.3460, 0.3568],
"ct": 201,
"alert": "none",
"effect": "none",
"colormode": "hs",
"reachable": true
},
"type": "Extended color light",
"name": "Hue Lamp 2",
"modelid": "LCT001",
"swversion": "65003148",
"uniqueid": "00:17:88:01:00:d4:12:08-0b",
"pointsymbol": {
"1": "none",
"2": "none",
"3": "none",
"4": "none",
"5": "none",
"6": "none",
"7": "none",
"8": "none"
}
},
"3": {
"state": {
"on": true,
"bri": 254,
"hue": 65136,
"sat": 254,
"xy": [0.3460, 0.3568],
"ct": 201,
"alert": "none",
"effect": "none",
"colormode": "hs",
"reachable": true
},
"type": "Extended color light",
"name": "Hue Lamp 3",
"modelid": "LCT001",
"swversion": "65003148",
"uniqueid": "00:17:88:01:00:d4:12:08-0c",
"pointsymbol": {
"1": "none",
"2": "none",
"3": "none",
"4": "none",
"5": "none",
"6": "none",
"7": "none",
"8": "none"
}
}
},
"groups": {
"1": {
"action": {
"on": true,
"bri": 254,
"hue": 33536,
"sat": 144,
"xy": [0.3460, 0.3568],
"ct": 201,
"effect": "none",
"colormode": "xy"
},
"lights": ["1", "2"],
"name": "Group 1"
}
},
"config": {
"name": "Philips hue",
"mac": "00:00:88:00:bb:ee",
"bridgeid": "000088FFFE00BBEE",
"modelid": "BSB001",
"dhcp": true,
"ipaddress": "192.168.2.213:8000",
"netmask": "255.255.255.0",
"gateway": "192.168.2.1",
"proxyaddress": "",
"proxyport": 0,
"UTC": "2012-10-29T12:05:00",
"whitelist": {
"newdeveloper": {
"last use date": "2012-10-29T12:00:00",
"create date": "2012-10-29T12:00:00",
"name": "test user"
}
},
"swversion": "01005215",
"swupdate": {
"updatestate": 0,
"url": "",
"text": "",
"notify": false
},
"linkbutton": false,
"portalservices": false
},
"schedules": {
"1": {
"name": "schedule",
"description": "",
"command": {
"address": "/api/newdeveloper/groups/0/action",
"body": {
"on": true
},
"method": "PUT"
},
"time": "2012-10-29T12:00:00"
}
},
"scenes": {
}
}
================================================
FILE: resources/description.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<URLBase>http://##URLBASE##</URLBase>
<device>
<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>
<friendlyName>Philips hue (##URLBASE##)</friendlyName>
<manufacturer>Royal Philips Electronics</manufacturer>
<manufacturerURL>http://www.philips.com</manufacturerURL>
<modelDescription>Philips hue Personal Wireless Lighting
</modelDescription>
<modelName>Philips hue bridge 2015</modelName>
<modelNumber>929000226503</modelNumber>
<modelURL>http://www.meethue.com</modelURL>
<serialNumber>0017880ae670</serialNumber>
<UDN>uuid:2f402f80-da50-11e1-9b23-0017880ae670</UDN>
<presentationURL>index.html</presentationURL>
<iconList>
<icon>
<mimetype>image/png</mimetype>
<height>48</height>
<width>48</width>
<depth>24</depth>
<url>hue_logo_0.png</url>
</icon>
<icon>
<mimetype>image/png</mimetype>
<height>120</height>
<width>120</width>
<depth>24</depth>
<url>hue_logo_3.png</url>
</icon>
</iconList>
</device>
</root>
================================================
FILE: src/com/hueemulator/emulator/Constants.java
================================================
package com.hueemulator.emulator;
public class Constants {
public static String EMULATOR_VERSION = "v0.6";
public static final String MODEL_ID_COLOR_BULB = "LCT001";
public static final String MODEL_ID_LUX_BULB = "LWB004";
public static final String LIGHT_TYPE_LUX_BULB = "Dimmable light";
public static final String LIGHT_FRAME_LARGE = "LARGE";
public static final String LIGHT_FRAME_SMALL = "SMALL";
}
================================================
FILE: src/com/hueemulator/emulator/Controller.java
================================================
package com.hueemulator.emulator;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import com.hueemulator.gui.View;
import com.hueemulator.model.PHBridgeConfiguration;
import com.hueemulator.model.PHLight;
import com.hueemulator.model.PHLightState;
import com.hueemulator.utils.OpenFileFilter;
import com.hueemulator.utils.Utils;
public class Controller {
// Start up the Emulator
private Emulator emulator;
private Model model;
private View view;
public String consoleText="";
private DateFormat inputFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss");
private String ipAddress;
private MutableAttributeSet sas;
private StyleContext context;
public boolean hasBridgeBeenPushLinked=false;
public Controller(Model model, View view, String fileName){
this.model = model;
this.view = view;
this.sas = new SimpleAttributeSet();
this.context = new StyleContext();
this.context.addStyle("test", null);
emulator = new Emulator(this, fileName);
String introText = "Welcome to the Hue Emulator. Choose a port and click the Start Button";
addTextToConsole(introText, Color.YELLOW, true);
}
public void addPropertiesListeners() {
view.getPropertiesFrame().getIncludeTime().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean isSelected = view.getPropertiesFrame().getIncludeTime().isSelected();
model.setShowConsoleTime(isSelected);
}
});
}
public void addMenuListeners(){
// Add Listeners For Stop and Start Buttons.
view.getMenuBar().getStartButton().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
emulator.startServers();
view.getMenuBar().getStartButton().setEnabled(false);
view.getMenuBar().getStopButton().setEnabled(true);
}
});
view.getMenuBar().getStopButton().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
emulator.stopServer();
view.getMenuBar().getStartButton().setEnabled(true);
view.getMenuBar().getStopButton().setEnabled(false);
}
});
view.getMenuBar().getClearConsoleMenuItem().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
clearConsole();
addTextToConsole("Console Cleared", Color.WHITE, true);
}
});
view.getMenuBar().getViewGraphicsMenuItems().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if (view.getMenuBar().getViewGraphicsMenuItems().isSelected()) {
view.getGraphicsPanel().setVisible(true);
}
else {
view.getGraphicsPanel().setVisible(false);
}
}
});
view.getMenuBar().getLoadConfigMenuItem().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
final JFileChooser fc = new JFileChooser();
fc.addChoosableFileFilter(new OpenFileFilter("json","JSON Config file") );
//In response to a button click:
int returnVal = fc.showOpenDialog(view.getMenuBar());
if (returnVal == JFileChooser.APPROVE_OPTION) {
String fileName = fc.getSelectedFile().getAbsoluteFile().getAbsolutePath();
boolean loadedNewConfig = emulator.loadConfiguration(fileName);
if (loadedNewConfig) {
view.getGraphicsPanel().repaint();
repaintBulbs();
}
else {
JOptionPane.showMessageDialog(view.getConsole(), "Config file (" + fileName + ") could not be loaded. Is it a valid config.json file?");
}
}
}
});
view.getMenuBar().getSaveConfigMenuItem().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
final JFileChooser fc = new JFileChooser();
fc.addChoosableFileFilter(new OpenFileFilter("json","JSON Config file") );
//In response to a button click:
int returnVal = fc.showSaveDialog(view.getMenuBar());
if (returnVal == JFileChooser.APPROVE_OPTION) {
String fileName = fc.getSelectedFile().getAbsoluteFile().getAbsolutePath();
String extension = "";
int i = fileName.lastIndexOf('.');
if (i > 0) {
extension = fileName.substring(i);
}
if (!extension.equals("") && !extension.equals(".json")) {
JOptionPane.showMessageDialog(view.getConsole(), "Please save the with a .json file extension, or leave blank.");
}
else {
if (extension.equals(""))fileName += ".json";
ObjectMapper mapper = new ObjectMapper();
try {
mapper.writeValue(new File(fileName), model.getBridgeConfiguration());
} catch (JsonGenerationException e1) {
e1.printStackTrace();
} catch (JsonMappingException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
});
view.getMenuBar().getAboutMenuItem().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
view.getAbout().setLocation(300,300);
view.getAbout().setVisible(true);
}
});
view.getMenuBar().getHelpMenuItem().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
view.getHelp().setLocation(300,300);
view.getHelp().setVisible(true);
}
});
}
public Controller() {
}
public void addTextToConsole(String text, Color textColour, boolean appendText) {
if (view==null) {
return; // No View for JUnit tests, so this is null.
}
Date currentDate = new Date();
String dateString = inputFormat.format(currentDate);
if (!model.isShowConsoleTime()) { // Don't show date string if user has de-selected it (in propertiesFrame)
dateString="";
}
if (appendText) { // Can now be disabled in menus
append(dateString, text, textColour, view.getConsole());
}
repaintBulbs();
}
public void repaintBulbs() {
// Repaint the Light Bulbs after Every Command.
view.getGraphicsPanel().repaint();
// Repaint the Separate Frame version (showing large bulbs), if this is being used.
if (view.getMenuBar().getLargeLightFrame() != null) {
view.getMenuBar().getLargeLightFrame().repaint();
}
if (view.getMenuBar().getSmallLightFrame() != null) {
view.getMenuBar().getSmallLightFrame().repaint();
}
}
/**
* When the emulator starts we should update the Bridge Config with the IP Address and PORT this Emulator is running on.
* This is needed as JSON responses are sent using the IP Address.
*
* @throws UnknownHostException
*/
public void setIPAddress() throws UnknownHostException {
PHBridgeConfiguration bridgeConfiguration = model.getBridgeConfiguration();
InetAddress ip = InetAddress.getLocalHost();
String ipAddressAndPort = ip.getHostAddress() + ":" + view.getMenuBar().getPort().getText();
bridgeConfiguration.getConfig().setIpaddress(ipAddressAndPort);
this.ipAddress = ipAddressAndPort;
}
public String getPort() {
return view.getMenuBar().getPort().getText();
}
public Model getModel() {
return model;
}
public void setModel(Model model) {
this.model = model;
}
public void paintGraphicsPanel() {
}
public void addNewBulb(boolean isLux) {
PHBridgeConfiguration bridgeConfiguration = model.getBridgeConfiguration();
int numberOfLights = bridgeConfiguration.getLights().size();
int newIdentifer = numberOfLights+1;
String newLightId = "" + newIdentifer;
PHLight light = new PHLight();
light.setSwversion("65003148");
light.setUniqueid(Utils.generateRandomUniqueId());
if (isLux) {
light.setName("New white Light - " + newLightId);
light.setModelid(Constants.MODEL_ID_LUX_BULB);
light.setType(Constants.LIGHT_TYPE_LUX_BULB);
}
else {
light.setName("New Light - " + newLightId);
light.setModelid(Constants.MODEL_ID_COLOR_BULB);
light.setType("Extended color light");
}
PHLightState lightState = new PHLightState();
if (!isLux) {
lightState.setHue(5000);
List<Double> xyList = new ArrayList();
xyList.add(0d);
xyList.add(0d);
lightState.setXy(xyList);
}
if (!isLux) {
lightState.setColormode("xy");
lightState.setCt(0);
}
light.setPointsymbol(getDefaultPointSymbols());
lightState.setBri(254);
lightState.setSat(254);
lightState.setOn(true);
lightState.setReachable(true);
lightState.setEffect("none");
lightState.setAlert("none");
light.setState(lightState);
bridgeConfiguration.getLights().put(newLightId, light);
if (isLux) {
addTextToConsole("New Lux Bulb Created: " + newLightId, Color.ORANGE, true);
}
else {
addTextToConsole("New Bulb Created: " + newLightId, Color.ORANGE, true);
}
}
public static Map<String, String> getDefaultPointSymbols() {
Map<String, String> pointSymbols = new HashMap<String, String>();
pointSymbols.put("1", "none");
pointSymbols.put("2", "none");
pointSymbols.put("3", "none");
pointSymbols.put("4", "none");
pointSymbols.put("5", "none");
pointSymbols.put("6", "none");
pointSymbols.put("7", "none");
pointSymbols.put("8", "none");
return pointSymbols;
}
public String getIpAddress() {
return ipAddress;
}
public void clearConsole() {
// System.out.println("Clear Console " + int docLength = document.getLength(););
try {
view.getConsole().getDocument().remove(0, view.getConsole().getDocument().getLength());
} catch (BadLocationException e) {}
}
public void append(final String dateString, final String s, final Color color, final JEditorPane console) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
append(dateString, s, color, console);
}
});
return;
}
Document document = console.getDocument();
Style style = context.addStyle("test", null);
// set some style properties
StyleConstants.setForeground(style, color);
StyleConstants.setAlignment(style, StyleConstants.ALIGN_LEFT);
try {
StyleConstants.setForeground(sas, Color.yellow);
int docLength = document.getLength();
document.insertString(docLength, dateString, null);
docLength = document.getLength();
document.insertString(docLength, " " + s + "\n", style);
console.setCaretPosition( console.getDocument().getLength());
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public boolean isHasBridgeBeenPushLinked() {
return hasBridgeBeenPushLinked;
}
public void setHasBridgeBeenPushLinked(boolean hasBridgeBeenPushLinked) {
this.hasBridgeBeenPushLinked = hasBridgeBeenPushLinked;
}
public boolean showRequestJson() {
return model.isShowRequestJSON();
}
public void setShowRequestJson(boolean showRequestJSON) {
model.setShowRequestJSON(showRequestJSON);
}
public boolean showResponseJson() {
return model.isShowResponseJSON();
}
public void setShowResponseJson(boolean showResponseJSON) {
model.setShowResponseJSON(showResponseJSON);
}
public void setShowFullConfigJson(boolean showFullConfigJSON) {
model.setShowFullConfigJSON(showFullConfigJSON);
}
}
================================================
FILE: src/com/hueemulator/emulator/Emulator.java
================================================
package com.hueemulator.emulator;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import com.hueemulator.model.PHBridgeConfiguration;
import com.hueemulator.server.Server;
import com.hueemulator.server.UPNPServer;
// Taken from here: http://www.java2s.com/Code/Java/JDK-6/LightweightHTTPServer.htm
// Here is another one: http://www.sourcestream.com/programming-stuff/java-http-server
public class Emulator {
private Server server;
private UPNPServer upnpServer;
private Controller controller;
public Emulator(Controller controller, String fileName) {
this.controller = controller;
if(fileName == null) {
fileName = "/config-3bulbs.json";
}
controller.addTextToConsole("Loading configuration...", Color.WHITE, true);
loadConfiguration(fileName);
controller.addTextToConsole("Starting Emulator...", Color.GREEN, true);
}
public void startServers() {
try {
server = new Server(controller.getModel().getBridgeConfiguration(), controller, controller.getPort());
controller.setIPAddress();
} catch (java.net.BindException e) {
controller.addTextToConsole(" **NOT STARTED ** Server already running. " + e.getMessage(), Color.RED, true);
} catch (IOException e) {
e.printStackTrace();
}
server.getHttpServer().start();
controller.addTextToConsole("**STARTED** Emulator is listening on port: " + controller.getPort(), Color.WHITE, true);
upnpServer = new UPNPServer(controller);
upnpServer.startUPNPServer();
controller.addTextToConsole("UPnP Server Started" , Color.WHITE, true);
if (!controller.getPort().equals("80")) {
controller.addTextToConsole("UPnP works best with the Emulator running on port 80. Apps written with the Java/iOS SDK's wont connect to the Emulator." , Color.RED, true);
}
}
public void stopServer() {
if (server!=null && server.getHttpServer() !=null) {
server.getHttpServer().stop(0);
server.getHttpServer().removeContext("/api");
controller.addTextToConsole("Stopping the Server on port: " + server.getHttpServer().getAddress().getPort(), Color.RED, true);
}
if (upnpServer !=null) {
upnpServer.stopUPNPServer();
}
}
public boolean loadConfiguration(String fileName) {
//2. Convert JSON to Java object
ObjectMapper mapper = new ObjectMapper();
try {
InputStream is;
is = getClass().getResourceAsStream(fileName);
if(is == null) {
System.out.println("Loading external config file: " + fileName);
is = new FileInputStream(new File(fileName));
}
controller.getModel().setBridgeConfiguration(mapper.readValue(is, PHBridgeConfiguration.class));
return true;
} catch (JsonParseException e) {
return false;
} catch (JsonMappingException e) {
return false;
} catch (IOException e) {
return false;
}
}
public Server getServer() {
return server;
}
public void setServer(Server server) {
this.server = server;
}
}
================================================
FILE: src/com/hueemulator/emulator/HueEmulator.java
================================================
package com.hueemulator.emulator;
import com.hueemulator.gui.View;
public class HueEmulator{
public static void main(String args[]) {
new HueEmulator(args.length > 0 ? args[0] : null);
}
public HueEmulator(String fileName) {
Model model = new Model();
// Set Up the View (A JFrame, MenuBar and Console).
View view = new View();
// Bind the Model and View
Controller controller = new Controller(model,view,fileName);
view.getMenuBar().setController(controller);
view.getGraphicsPanel().setController(controller);
// Add all the Menu Listeners.
controller.addMenuListeners();
// Add all the Property Frame Listeners.
controller.addPropertiesListeners();
// Model is needed here to paint Light Bulbs/ Show bulb information.
view.getGraphicsPanel().setModel(model);
}
}
================================================
FILE: src/com/hueemulator/emulator/Model.java
================================================
package com.hueemulator.emulator;
import com.hueemulator.model.PHBridgeConfiguration;
public class Model {
private PHBridgeConfiguration bridgeConfiguration;
private boolean showConsoleTime;
private boolean showRequestJSON=true;
private boolean showResponseJSON=true;
private boolean showFullConfigJSON=true;
public Model(){
showConsoleTime=true;
}
public boolean isShowConsoleTime() {
return showConsoleTime;
}
public boolean isShowFullConfig() {
return showFullConfigJSON;
}
public void setShowConsoleTime(boolean showConsoleTime) {
this.showConsoleTime = showConsoleTime;
}
public PHBridgeConfiguration getBridgeConfiguration() {
return bridgeConfiguration;
}
public void setBridgeConfiguration(PHBridgeConfiguration bridgeConfiguration) {
this.bridgeConfiguration = bridgeConfiguration;
}
public boolean isShowRequestJSON() {
return showRequestJSON;
}
public void setShowRequestJSON(boolean showRequestJSON) {
this.showRequestJSON = showRequestJSON;
}
public boolean isShowResponseJSON() {
return showResponseJSON;
}
public void setShowResponseJSON(boolean showResponseJSON) {
this.showResponseJSON = showResponseJSON;
}
public void setShowFullConfigJSON(boolean showFullConfigJSON) {
this.showFullConfigJSON = showFullConfigJSON;
}
}
================================================
FILE: src/com/hueemulator/emulator/PHScheduleTimer.java
================================================
package com.hueemulator.emulator;
import java.util.Timer;
import org.json.JSONObject;
public class PHScheduleTimer extends Timer {
private String scheduleIdentifier;
private JSONObject commandJSON;
public String getScheduleIdentifier() {
return scheduleIdentifier;
}
public void setScheduleIdentifier(String scheduleIdentifier) {
this.scheduleIdentifier = scheduleIdentifier;
}
public JSONObject getCommandJSON() {
return commandJSON;
}
public void setCommandJSON(JSONObject commandJSON) {
this.commandJSON = commandJSON;
}
}
================================================
FILE: src/com/hueemulator/emulator/PHScheduleTimerManager.java
================================================
package com.hueemulator.emulator;
import java.util.HashMap;
public class PHScheduleTimerManager {
private static PHScheduleTimerManager scheduleManager;
/**
* Stores list of ScheduleIdentifiers and their Respective Timer Objects
*/
private HashMap<String ,PHScheduleTimer> scheduleStore=new HashMap<String ,PHScheduleTimer>();
/**
* default private constructor for ScheduleTimer manager
*/
private PHScheduleTimerManager() {
}
public static synchronized PHScheduleTimerManager getInstance(){
if(scheduleManager==null){
scheduleManager=new PHScheduleTimerManager();
}
return scheduleManager;
}
public void storeSchedule(String scheduleIdentifier, PHScheduleTimer schTimer){
scheduleStore.put(scheduleIdentifier, schTimer);
}
public void removeSchedule(String scheduleIdentifier){
scheduleStore.remove(scheduleIdentifier);
}
}
================================================
FILE: src/com/hueemulator/gui/About.java
================================================
package com.hueemulator.gui;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import com.hueemulator.emulator.Constants;
public class About extends JFrame{
private JEditorPane aboutPane;
public About() {
String text = "<h2>Hue Emulator " + Constants.EMULATOR_VERSION + "</h2><p>Programmed By: <b>SteveyO</b>. <p>See <a href=\"http://steveyo.github.io/Hue-Emulator/\">http://steveyo.github.io/Hue-Emulator/</a> for more details.</p>";
aboutPane = new JEditorPane();
aboutPane.setContentType("text/html");
aboutPane.setText(text);
setSize(400, 210);
aboutPane.setVisible(true);
add(aboutPane);
}
}
================================================
FILE: src/com/hueemulator/gui/GraphicsPanel.java
================================================
package com.hueemulator.gui;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import com.hueemulator.emulator.Constants;
import com.hueemulator.emulator.Controller;
import com.hueemulator.emulator.Model;
import com.hueemulator.model.PHConfig;
import com.hueemulator.model.PHLight;
import com.hueemulator.model.PHLightState;
public class GraphicsPanel extends JPanel implements MouseListener {
private Model model;
private BufferedImage bulbImage;
private BufferedImage lampTop; // For when the bulb is off
private BufferedImage bridgeImage;
// Used for slightly dimming bulbs which are off.
private AlphaComposite dimAlphaComposite;
private AlphaComposite helpAlphaComposite;
private AlphaComposite normalAlphaComposite;
private static final int VIEW_TYPE_LARGE=0;
private static final int VIEW_TYPE_SMALL=1; // New window with small bulbs
private static final int VIEW_TYPE_PANEL=2; // Panel on main window.
private static final int NO_BULBS_PER_ROW=5;
private static final int NO_BULBS_PER_ROW_SMALL=12;
private int viewType;
private int lightXOffset;
private int lightsGap;
private int yPosition;
private boolean drawBulbInfo=false;
private boolean drawBridgeInfo=false;
private Controller controller;
private Timer linkExpireTimer;
private int mouseOverBulb=-1; // Used for Helper Message, to indicate for which bulb to display the help/info.
public GraphicsPanel(String size) {
String path = "/";
if (size.equalsIgnoreCase(Constants.LIGHT_FRAME_LARGE)) {
path +="largeImages/";
viewType=VIEW_TYPE_LARGE;
lightsGap=240;
lightXOffset=245;
yPosition=-40;
}
else if (size.equalsIgnoreCase(Constants.LIGHT_FRAME_SMALL)) {
yPosition=-6;
lightsGap=80;
lightXOffset=130;
viewType=VIEW_TYPE_SMALL;
}
else {
yPosition=-6;
lightsGap=80;
lightXOffset=130;
viewType=VIEW_TYPE_PANEL;
}
setPreferredSize(new Dimension(1000,100));
try {
bridgeImage = ImageIO.read(getClass().getResource(path + "bridge.png"));
bulbImage = ImageIO.read(getClass().getResource(path + "lamp.png"));
lampTop = ImageIO.read(getClass().getResource(path + "lampTop.png"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int type = AlphaComposite.SRC_OVER;
dimAlphaComposite = AlphaComposite.getInstance(type, 0.5f);
normalAlphaComposite = AlphaComposite.getInstance(type, 1f);
helpAlphaComposite = AlphaComposite.getInstance(type, 0.8f);
addMouseListener(this);
}
public void setController(Controller controller) {
this.controller=controller;
}
public void paintComponent( Graphics g ) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.black);
g2.fillRect(0,0,super.getWidth(),super.getHeight());
g2.drawImage(bridgeImage, 5,10,null);
if (viewType==VIEW_TYPE_LARGE) {
yPosition=-40;
}
if (viewType==VIEW_TYPE_SMALL) {
yPosition=0;
}
if (model!=null) {
Map <String, PHLight> lightsMap = model.getBridgeConfiguration().getLights();
Iterator it = lightsMap.entrySet().iterator();
int counter=0;
int bulbNumber=0;
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
PHLight light = (PHLight) entry.getValue();
PHLightState state = light.getState();
if (state.getOn()) {
g2.setComposite(normalAlphaComposite);
}
else {
g2.setComposite(dimAlphaComposite);
}
if (viewType==VIEW_TYPE_LARGE && counter > 0 && counter % NO_BULBS_PER_ROW == 0) {
counter=0;
yPosition+=300;
}
if (viewType==VIEW_TYPE_SMALL && counter > 0 && counter % NO_BULBS_PER_ROW_SMALL == 0) {
counter=0;
yPosition+=100;
}
if (state.getOn()) {
// Bulb Colour
Color color;
if (light.getType().equals(Constants.LIGHT_TYPE_LUX_BULB)) { // Hue Lux bulb is dimmable white. No colors.
int minBri = 170; // As the bri is done based on alpha, a brightness of 0 would make the bulb look black (as set against a black background). So all Alpha Values will be in range 170-255 and the State bri will be a percentage between this range.
int bri = minBri + (85 * state.getBri()/255);
color=new Color(255,255,200, bri);
}
else {
float h = (float) state.getHue()/65535;
float s = (float) state.getSat()/254;
float b = (float) state.getBri()/254;
int rgb = Color.HSBtoRGB(h,s,b);
color = new Color(rgb);
}
g2.setColor(color);
g2.fillRect(lightXOffset + (counter*lightsGap),yPosition, bulbImage.getWidth(), bulbImage.getHeight());
}
else {
g2.drawImage(lampTop, lightXOffset + (counter*lightsGap),yPosition,null);
}
g2.drawImage(bulbImage, lightXOffset + (counter*lightsGap),yPosition,null);
counter++;
if (drawBridgeInfo && viewType == VIEW_TYPE_LARGE) {
showBridgeInfo(g2, model);
}
if (drawBulbInfo && viewType == VIEW_TYPE_LARGE && mouseOverBulb != -1 && (mouseOverBulb) == bulbNumber) {
showBulbInfo(g2, light, state, bulbNumber);
}
bulbNumber++;
} // End of Lights loop
}
}
public void showBridgeInfo(Graphics2D g2, Model model) {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.BLACK);
g2.setComposite(helpAlphaComposite);
g2.fillRect(15, 10, lightsGap-20, 270);
g2.setComposite(normalAlphaComposite);
g2.setColor(Color.MAGENTA);
PHConfig config = model.getBridgeConfiguration().getConfig();
g2.drawLine(15, 12, 200, 12);
g2.drawLine(15, 30, 200, 30);
g2.setColor(Color.WHITE);
g2.drawString("Name:", 30, 25);
g2.drawString(config.getName(), 100, 25);
g2.drawString("IP Address:", 30, 50);
g2.drawString(config.getIpaddress(),100, 50);
g2.drawString("UTC:", 30, 70);
g2.drawString(config.getUtc(), 100, 70);
g2.drawString("SW Version:", 30, 90);
g2.drawString("" + config.getSwversion(), 100, 90);
}
public void showBulbInfo(Graphics2D g2, PHLight light, PHLightState state, int bulbClicked) {
int newXOffset = (1 + mouseOverBulb % NO_BULBS_PER_ROW) * lightXOffset;
int yOffset = 25 + ((bulbClicked / NO_BULBS_PER_ROW) * 300);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.BLACK);
g2.setComposite(helpAlphaComposite);
g2.fillRect(newXOffset+15, yOffset-15, lightsGap-30, yOffset + 235);
g2.setComposite(normalAlphaComposite);
g2.setColor(Color.MAGENTA);
g2.drawLine(newXOffset+30, yOffset - 13, newXOffset+200, yOffset - 13);
g2.drawLine(newXOffset+30, yOffset + 5, newXOffset+200, yOffset + 5);
g2.setColor(Color.WHITE);
g2.drawString("Name:", newXOffset+30, yOffset);
g2.drawString(light.getName(), newXOffset+100, yOffset);
g2.drawString("Model:", newXOffset+30, yOffset + 25);
g2.drawString(light.getModelid(),newXOffset+100, yOffset + 25);
g2.drawString("Hue:", newXOffset+30, yOffset + 45);
g2.drawString("" + state.getHue(), newXOffset+100, yOffset + 45);
g2.drawString("Sat:", newXOffset+30, yOffset + 65);
g2.drawString("" + state.getSat(), newXOffset+100, yOffset + 65);
g2.drawString("Bri:", newXOffset+30, yOffset + 85);
g2.drawString("" + state.getBri(), newXOffset+100, yOffset + 85);
g2.drawString("x/y:", newXOffset+30, yOffset + 105);
g2.drawString("" + state.getXy(), newXOffset+100, yOffset + 105);
g2.drawString("Alert:", newXOffset+30, yOffset + 125);
g2.drawString(state.getAlert(), newXOffset+100, yOffset + 125);
g2.drawString("Effect", newXOffset+30, yOffset + 145);
g2.drawString(state.getEffect(), newXOffset+100, yOffset + 145);
g2.drawString("On:", newXOffset+30, yOffset + 165);
g2.drawString("" + state.getOn(), newXOffset+100, yOffset + 165);
}
public Model getModel() {
return model;
}
public void setModel(Model model) {
this.model = model;
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
drawBulbInfo = false;
drawBridgeInfo = false;
this.repaint();
}
@Override
public void mousePressed(MouseEvent e) {
int x= e.getX();
int y= e.getY();
boolean linkButtonPressed=false; // i.e. The use has clicked near the bridge image.
if (viewType == VIEW_TYPE_LARGE) {
drawBulbInfo = false;
drawBridgeInfo = false;
int bulbClicked = -1;
if (x > lightXOffset) {
bulbClicked = ((x - lightXOffset) / lightsGap) + (NO_BULBS_PER_ROW * (y/300));
drawBulbInfo=true;
mouseOverBulb = bulbClicked;
}
else {
drawBridgeInfo=true;
linkButtonPressed=true;
}
}
else if (x < 90) {
linkButtonPressed=true;
}
if (linkButtonPressed) {
controller.setHasBridgeBeenPushLinked(true);
controller.addTextToConsole("Link button has been pressed", Color.GREEN, true);
if (linkExpireTimer != null) {
linkExpireTimer.cancel();
}
linkExpireTimer = new Timer();
linkExpireTimer.schedule(new TimerTask() {
@Override
public void run() {
controller.setHasBridgeBeenPushLinked(false);
controller.addTextToConsole("Linking has expired", Color.RED, true);
}
}, 30000);
}
this.repaint();
}
@Override
public void mouseReleased(MouseEvent arg0) {
drawBulbInfo = false;
drawBridgeInfo = false;
this.repaint();
}
}
================================================
FILE: src/com/hueemulator/gui/Help.java
================================================
package com.hueemulator.gui;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
public class Help extends JFrame{
private JEditorPane aboutPane;
public Help() {
String text = "<h2>Help</h2>For full hue API documentation see: </br> "
+ "<p><a href=\"http://www.developers.meethue.com/philips-hue-api\">http://www.developers.meethue.com/philips-hue-api</a> (Login Required)</p>"
+ "<p><b>Note</b> that Rules and Sensors are not supported in the emulator</p>" +
"<p>Any bugs or issues please use the github issues page: <a href=\"https://github.com/SteveyO/Hue-Emulator/issues\">https://github.com/SteveyO/Hue-Emulator/issues</a></p>";
aboutPane = new JEditorPane();
aboutPane.setContentType("text/html");
aboutPane.setText(text);
setSize(450, 250);
aboutPane.setVisible(true);
add(aboutPane);
}
}
================================================
FILE: src/com/hueemulator/gui/HueMenuBar.java
================================================
package com.hueemulator.gui;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTextField;
import com.hueemulator.emulator.Constants;
import com.hueemulator.emulator.Controller;
public class HueMenuBar extends JMenuBar {
private JTextField port;
private JMenuBar menuBar;
private JMenu fileMenu, viewsMenu, debugMenu, helpMenu;
private JMenuItem menuItem;
private JButton startButton;
private JButton stopButton;
private JMenuItem clearConsoleMenuItem, helpMenuItem, aboutMenuItem,loadConfigMenuItem, saveConfigMenuItem, newColorBulbMenuItem, newLuxBulbMenuItem;
// Debug Menus Items
private JMenuItem showResponseJsonMenuItem, showRequestJsonMenuItem, showFullConfigMenuItem, showTimeInJson;
private JCheckBoxMenuItem viewGraphicsMenuItems;
private Controller controller;
private LightsFrame lightFrameLarge;
private LightsFrame lightFrameSmall;
public HueMenuBar() {
//Create the menu bar.
menuBar = new JMenuBar();
//Build the File Menu.
fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F);
menuBar.add(fileMenu);
loadConfigMenuItem = new JMenuItem("Load Config", KeyEvent.VK_L);
saveConfigMenuItem = new JMenuItem("Save Config", KeyEvent.VK_L);
fileMenu.add(loadConfigMenuItem);
fileMenu.add(saveConfigMenuItem);
newColorBulbMenuItem = new JMenuItem("Add New Color Bulb", KeyEvent.VK_B);
newColorBulbMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
controller.addNewBulb(false);
}
});
fileMenu.add(newColorBulbMenuItem);
newLuxBulbMenuItem = new JMenuItem("Add New Lux Bulb", KeyEvent.VK_L);
newLuxBulbMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
controller.addNewBulb(true);
}
});
fileMenu.add(newLuxBulbMenuItem);
clearConsoleMenuItem = new JMenuItem("Clear Console", KeyEvent.VK_L);
fileMenu.add(clearConsoleMenuItem);
menuItem = new JMenuItem("Exit");
menuItem.setMnemonic(KeyEvent.VK_B);
fileMenu.add(menuItem);
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
//Build the Views Menu.
viewsMenu = new JMenu("Views");
viewsMenu.setMnemonic(KeyEvent.VK_V);
menuBar.add(viewsMenu);
viewGraphicsMenuItems = new JCheckBoxMenuItem("Graphical View");
viewGraphicsMenuItems.setSelected(true);
viewsMenu.add(viewGraphicsMenuItems);
JCheckBoxMenuItem graphicsLargeFrameMenuItems;
graphicsLargeFrameMenuItems = new JCheckBoxMenuItem("Large Frame");
graphicsLargeFrameMenuItems.setSelected(false);
graphicsLargeFrameMenuItems.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if (lightFrameLarge == null) {
lightFrameLarge = new LightsFrame(controller, Constants.LIGHT_FRAME_LARGE);
lightFrameLarge.setModel(controller.getModel());
}
lightFrameLarge.setVisible(true);
}
});
viewsMenu.add(graphicsLargeFrameMenuItems);
JCheckBoxMenuItem graphicsSmallFrameMenuItems;
graphicsSmallFrameMenuItems = new JCheckBoxMenuItem("Small Frame");
graphicsSmallFrameMenuItems.setSelected(false);
graphicsSmallFrameMenuItems.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if (lightFrameSmall == null) {
lightFrameSmall = new LightsFrame(controller, Constants.LIGHT_FRAME_SMALL);
lightFrameSmall.setModel(controller.getModel());
}
lightFrameSmall.setVisible(true);
}
});
viewsMenu.add(graphicsSmallFrameMenuItems);
//Build the Debug Menu.
debugMenu = new JMenu("Debug");
debugMenu.setMnemonic(KeyEvent.VK_D);
menuBar.add(debugMenu);
showRequestJsonMenuItem = new JCheckBoxMenuItem("Show Request JSON");
showRequestJsonMenuItem.setSelected(true);
showRequestJsonMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
controller.setShowRequestJson(showRequestJsonMenuItem.isSelected());
}
});
debugMenu.add(showRequestJsonMenuItem);
showResponseJsonMenuItem = new JCheckBoxMenuItem("Show Response JSON");
showResponseJsonMenuItem.setSelected(true);
showResponseJsonMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
controller.setShowResponseJson(showResponseJsonMenuItem.isSelected());
}
});
debugMenu.add(showResponseJsonMenuItem);
showFullConfigMenuItem = new JCheckBoxMenuItem("Show FullConfig JSON (Heartbeat)");
showFullConfigMenuItem.setSelected(true);
showFullConfigMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
controller.setShowFullConfigJson(showFullConfigMenuItem.isSelected());
}
});
debugMenu.add(showFullConfigMenuItem);
debugMenu.addSeparator();
showTimeInJson = new JCheckBoxMenuItem("Show Time");
showTimeInJson.setSelected(true);
showTimeInJson.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
controller.getModel().setShowConsoleTime(showTimeInJson.isSelected());
}
});
debugMenu.add(showTimeInJson);
// Debug Menus Items
// private JMenuItem showResponseJsonMenuItem, showRequestJsonMenuItem, showFullConfigMenuItem;
//Build the Help Menu.
helpMenu = new JMenu("Help");
helpMenu.setMnemonic(KeyEvent.VK_H);
menuBar.add(helpMenu);
aboutMenuItem = new JMenuItem("About", KeyEvent.VK_P);
helpMenu.add(aboutMenuItem);
helpMenuItem = new JMenuItem("Help");
helpMenu.add(helpMenuItem);
menuBar.add(Box.createRigidArea(new Dimension(10,0)));
startButton = new JButton("Start");
stopButton = new JButton("Stop");
menuBar.add(startButton);
startButton.setPreferredSize(new Dimension(50,18));
menuBar.add(Box.createRigidArea(new Dimension(6,0)));
menuBar.add(stopButton);
stopButton.setPreferredSize(new Dimension(50,18));
stopButton.setEnabled(false);
menuBar.add(Box.createRigidArea(new Dimension(6,0)));
JLabel portLabel = new JLabel("port: ");
menuBar.add(portLabel);
port = new JTextField("8000", 4);
port.setColumns(4);
port.setMaximumSize(new Dimension(50,18));
menuBar.add(port);
add(menuBar);
}
public JTextField getPort() {
return port;
}
public void setPort(JTextField port) {
this.port = port;
}
public JMenuBar getMenuBar() {
return menuBar;
}
public void setMenuBar(JMenuBar menuBar) {
this.menuBar = menuBar;
}
public JMenu getFileMenu() {
return fileMenu;
}
public void setFileMenu(JMenu fileMenu) {
this.fileMenu = fileMenu;
}
public JMenu getHelpMenu() {
return helpMenu;
}
public void setHelpMenu(JMenu helpMenu) {
this.helpMenu = helpMenu;
}
public JMenuItem getMenuItem() {
return menuItem;
}
public void setMenuItem(JMenuItem menuItem) {
this.menuItem = menuItem;
}
public JButton getStartButton() {
return startButton;
}
public void setStartButton(JButton startButton) {
this.startButton = startButton;
}
public JButton getStopButton() {
return stopButton;
}
public void setStopButton(JButton stopButton) {
this.stopButton = stopButton;
}
public JMenuItem getClearConsoleMenuItem() {
return clearConsoleMenuItem;
}
public void setClearConsoleMenuItem(JMenuItem clearConsoleMenuItem) {
this.clearConsoleMenuItem = clearConsoleMenuItem;
}
public JMenuItem getHelpMenuItem() {
return helpMenuItem;
}
public void setHelpMenuItem(JMenuItem helpMenuItem) {
this.helpMenuItem = helpMenuItem;
}
public JMenuItem getAboutMenuItem() {
return aboutMenuItem;
}
public void setAboutMenuItem(JMenuItem aboutMenuItem) {
this.aboutMenuItem = aboutMenuItem;
}
public JCheckBoxMenuItem getViewGraphicsMenuItems() {
return viewGraphicsMenuItems;
}
public void setViewGraphicsMenuItems(JCheckBoxMenuItem viewGraphicsMenuItems) {
this.viewGraphicsMenuItems = viewGraphicsMenuItems;
}
public JMenuItem getLoadConfigMenuItem() {
return loadConfigMenuItem;
}
public void setLoadConfigMenuItem(JMenuItem loadConfigMenuItem) {
this.loadConfigMenuItem = loadConfigMenuItem;
}
public JMenuItem getSaveConfigMenuItem() {
return saveConfigMenuItem;
}
public void setSaveConfigMenuItem(JMenuItem saveConfigMenuItem) {
this.saveConfigMenuItem = saveConfigMenuItem;
}
public void setController(Controller controller) {
this.controller=controller;
}
public LightsFrame getLargeLightFrame() {
return lightFrameLarge;
}
public void setLargeLightFrame(LightsFrame lightFrame) {
this.lightFrameLarge = lightFrame;
}
public LightsFrame getSmallLightFrame() {
return lightFrameSmall;
}
public void setSmallLightFrame(LightsFrame lightFrame) {
this.lightFrameSmall = lightFrame;
}
}
================================================
FILE: src/com/hueemulator/gui/LightsFrame.java
================================================
package com.hueemulator.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import com.hueemulator.emulator.Constants;
import com.hueemulator.emulator.Controller;
import com.hueemulator.emulator.Model;
public class LightsFrame extends JFrame {
// Used for slightly dimming bulbs which are off.
private Model model;
private Controller controller;
private GraphicsPanel graphicsPanel;
public LightsFrame(Controller controller, String size) {
graphicsPanel = new GraphicsPanel(size);
graphicsPanel.setController(controller);
setTitle("MyHue Lights");
getContentPane().add(graphicsPanel, BorderLayout.CENTER);
if (size == Constants.LIGHT_FRAME_LARGE) {
setMinimumSize(new Dimension(1000,300));
}
else {
setMinimumSize(new Dimension(816,460));
}
pack();
setVisible(true);
}
public void setModel(Model model) {
this.model = model;
graphicsPanel.setModel(model);
}
}
================================================
FILE: src/com/hueemulator/gui/PropertiesFrame.java
================================================
package com.hueemulator.gui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PropertiesFrame extends JFrame{
private JCheckBox includeTime;
private JCheckBox showJSONResponses;
public PropertiesFrame() {
setTitle("Emulator Properties");
includeTime = new JCheckBox("Write time to console");
includeTime.setSelected(true);
showJSONResponses = new JCheckBox("Show JSON Responses");
showJSONResponses.setSelected(true);
showJSONResponses.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
JPanel listPane = new JPanel();
listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS));
listPane.add(includeTime);
listPane.add(showJSONResponses);
add(listPane);
setResizable(false);
setSize(300, 200);
}
public JCheckBox getIncludeTime() {
return includeTime;
}
public void setIncludeTime(JCheckBox includeTime) {
this.includeTime = includeTime;
}
public JCheckBox getShowJSONResponses() {
return showJSONResponses;
}
public void setShowJSONResponses(JCheckBox showJSONResponses) {
this.showJSONResponses = showJSONResponses;
}
}
================================================
FILE: src/com/hueemulator/gui/View.java
================================================
package com.hueemulator.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.text.html.HTMLDocument;
public class View {
private JEditorPane console; // Console where all text is displayed
private HueMenuBar menuBar;
private GraphicsPanel graphicsPanel;
private PropertiesFrame propertiesFrame;
private About about;
private Help help;
private JScrollPane consoleScrollPane;
public View(){
JFrame frame = new JFrame("Hue Emulator");
console = new JEditorPane();
graphicsPanel = new GraphicsPanel("SMALL");
graphicsPanel.setVisible(true);
help = new Help();
about = new About();
propertiesFrame = new PropertiesFrame();
//2. Optional: What happens when the frame closes?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(850,550));
console = new JEditorPane();
console.setEditable(false);
console.setContentType("text/html");
console.setBackground(Color.BLACK);
JToolBar toolbar = new JToolBar();
JButton button = new JButton("blah");
toolbar.add(button);
toolbar.setBorderPainted(false);
menuBar = new HueMenuBar();
Font font = new Font("Courier New", Font.PLAIN, 14);
String bodyRule = "body { color: #BBBBBB; font-family: " + font.getFamily() + "; " + "font-size: " + font.getSize() + "pt; }";
((HTMLDocument)console.getDocument()).getStyleSheet().addRule(bodyRule);
consoleScrollPane = new JScrollPane(console);
consoleScrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
consoleScrollPane.setPreferredSize(new Dimension(250, 250));
frame.getContentPane().add(menuBar, BorderLayout.NORTH);
frame.getContentPane().add(consoleScrollPane, BorderLayout.CENTER);
frame.getContentPane().add(graphicsPanel, BorderLayout.SOUTH);
//4. Size the frame.
frame.pack();
frame.setVisible(true);
}
public JEditorPane getConsole() {
return console;
}
public void setConsole(JEditorPane console) {
this.console = console;
}
public HueMenuBar getMenuBar() {
return menuBar;
}
public void setMenuBar(HueMenuBar menuBar) {
this.menuBar = menuBar;
}
public GraphicsPanel getGraphicsPanel() {
return graphicsPanel;
}
public void setGraphicsPanel(GraphicsPanel graphicsPanel) {
this.graphicsPanel = graphicsPanel;
}
public About getAbout() {
return about;
}
public void setAbout(About about) {
this.about = about;
}
public Help getHelp() {
return help;
}
public void setHelp(Help help) {
this.help = help;
}
public PropertiesFrame getPropertiesFrame() {
return propertiesFrame;
}
public void setPropertiesFrame(PropertiesFrame propertiesFrame) {
this.propertiesFrame = propertiesFrame;
}
public JScrollPane getConsoleScrollPane() {
return consoleScrollPane;
}
public void setConsoleScrollPane(JScrollPane consoleScrollPane) {
this.consoleScrollPane = consoleScrollPane;
}
}
================================================
FILE: src/com/hueemulator/model/PHBody.java
================================================
package com.hueemulator.model;
import java.util.List;
import org.codehaus.jackson.annotate.JsonProperty;
public class PHBody
{
@JsonProperty("scene")
private Boolean scene;
@JsonProperty("on")
private Boolean on;
@JsonProperty("xy")
private List<Double> xy;
@JsonProperty("bri")
private Integer bri;
@JsonProperty("transitiontime")
private Integer transitiontime;
public Integer getBri()
{
return bri;
}
public void setBri(Integer bri)
{
this.bri = bri;
}
public Integer getTransitiontime()
{
return transitiontime;
}
public void setTransitiontime(Integer transitiontime)
{
this.transitiontime = transitiontime;
}
public Boolean getOn()
{
return on;
}
public void setOn(Boolean on)
{
this.on = on;
}
public List<Double> getXy()
{
return xy;
}
public void setXy(List<Double> xy)
{
this.xy = xy;
}
public Boolean getScene() {
return scene;
}
public void setScene(Boolean scene) {
this.scene = scene;
}
}
================================================
FILE: src/com/hueemulator/model/PHBridgeConfiguration.java
================================================
package com.hueemulator.model;
import java.util.Map;
import org.codehaus.jackson.annotate.JsonProperty;
public class PHBridgeConfiguration
{
@JsonProperty("lights")
private Map<String, PHLight> lights;
@JsonProperty("schedules")
private Map<String, PHSchedulesEntry> schedules;
@JsonProperty("config")
private PHConfig config;
@JsonProperty("groups")
private Map<String, PHGroupsEntry> groups;
@JsonProperty("scenes")
private Map<String, PHScenesEntry> scenes;
public Map<String, PHLight> getLights()
{
return lights;
}
public void setLights(Map<String, PHLight> lights)
{
this.lights = lights;
}
public Map<String, PHSchedulesEntry> getSchedules()
{
return schedules;
}
public void setSchedules(Map<String, PHSchedulesEntry> schedules)
{
this.schedules = schedules;
}
public PHConfig getConfig()
{
return config;
}
public void setConfig(PHConfig config)
{
this.config = config;
}
public Map<String, PHGroupsEntry> getGroups()
{
return groups;
}
public Map<String, PHScenesEntry> getScenes()
{
return scenes;
}
public void setGroups(Map<String, PHGroupsEntry> groups)
{
this.groups = groups;
}
public void setScenes(Map<String, PHScenesEntry> scenes)
{
this.scenes = scenes;
}
}
================================================
FILE: src/com/hueemulator/model/PHCommand.java
================================================
package com.hueemulator.model;
import org.codehaus.jackson.annotate.JsonProperty;
public class PHCommand
{
@JsonProperty("body")
private PHBody body;
@JsonProperty("address")
private String address;
@JsonProperty("method")
private String method;
public PHBody getBody()
{
return body;
}
public void setBody(PHBody body)
{
this.body = body;
}
public String getAddress()
{
return address;
}
public void setAddress(String address)
{
this.address = address;
}
public String getMethod()
{
return method;
}
public void setMethod(String method)
{
this.method = method;
}
}
================================================
FILE: src/com/hueemulator/model/PHConfig.java
================================================
package com.hueemulator.model;
import java.util.Map;
import org.codehaus.jackson.annotate.JsonProperty;
public class PHConfig
{
@JsonProperty("portalservices")
private Boolean portalservices;
@JsonProperty("gateway")
private String gateway;
@JsonProperty("mac")
private String mac;
@JsonProperty("bridgeid")
private String bridgeid;
@JsonProperty("modelid")
private String modelid;
@JsonProperty("swversion")
private String swversion;
@JsonProperty("linkbutton")
private Boolean linkbutton;
@JsonProperty("ipaddress")
private String ipaddress;
@JsonProperty("proxyport")
private Integer proxyport;
@JsonProperty("swupdate")
private PHSwupdate swupdate;
@JsonProperty("netmask")
private String netmask;
@JsonProperty("name")
private String name;
@JsonProperty("dhcp")
private Boolean dhcp;
@JsonProperty("UTC")
private String utc;
@JsonProperty("proxyaddress")
private String proxyaddress;
@JsonProperty("whitelist")
private Map<String, PHWhitelistEntry> whitelist;
public Boolean getPortalservices()
{
return portalservices;
}
public void setPortalservices(Boolean portalservices)
{
this.portalservices = portalservices;
}
public String getGateway()
{
return gateway;
}
public void setGateway(String gateway)
{
this.gateway = gateway;
}
public String getMac()
{
return mac;
}
public void setMac(String mac)
{
this.mac = mac;
}
public String getSwversion()
{
return swversion;
}
public void setSwversion(String swversion)
{
this.swversion = swversion;
}
public Boolean getLinkbutton()
{
return linkbutton;
}
public void setLinkbutton(Boolean linkbutton)
{
this.linkbutton = linkbutton;
}
public String getIpaddress()
{
return ipaddress;
}
public void setIpaddress(String ipaddress)
{
this.ipaddress = ipaddress;
}
public Integer getProxyport()
{
return proxyport;
}
public void setProxyport(Integer proxyport)
{
this.proxyport = proxyport;
}
public PHSwupdate getSwupdate()
{
return swupdate;
}
public void setSwupdate(PHSwupdate swupdate)
{
this.swupdate = swupdate;
}
public String getNetmask()
{
return netmask;
}
public void setNetmask(String netmask)
{
this.netmask = netmask;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Boolean getDhcp()
{
return dhcp;
}
public void setDhcp(Boolean dhcp)
{
this.dhcp = dhcp;
}
public String getUtc()
{
return utc;
}
public void setUtc(String utc)
{
this.utc = utc;
}
public String getProxyaddress()
{
return proxyaddress;
}
public void setProxyaddress(String proxyaddress)
{
this.proxyaddress = proxyaddress;
}
public Map<String, PHWhitelistEntry> getWhitelist() {
return whitelist;
}
public void setWhitelist(Map<String, PHWhitelistEntry> whitelist) {
this.whitelist = whitelist;
}
public String getBridgeid() {
return bridgeid;
}
public void setBridgeid(String bridgeid) {
this.bridgeid = bridgeid;
}
public String getModelid() {
return modelid;
}
public void setModelid(String modelid) {
this.modelid = modelid;
}
}
================================================
FILE: src/com/hueemulator/model/PHGroupsEntry.java
================================================
package com.hueemulator.model;
import java.util.List;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class PHGroupsEntry
{
@JsonProperty("name")
private String name;
@JsonProperty("action")
private PHLightState lightState;
@JsonProperty("lights")
private List<String> lightIdentifiers;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public PHLightState getLightState()
{
return lightState;
}
public void setLightState(PHLightState lightState)
{
this.lightState = lightState;
}
public List<String> getLightIdentifiers() {
return lightIdentifiers;
}
public void setLightIdentifiers(List<String> lightIdentifiers) {
this.lightIdentifiers = lightIdentifiers;
}
}
================================================
FILE: src/com/hueemulator/model/PHLight.java
================================================
package com.hueemulator.model;
import java.util.Map;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
public class PHLight
{
@JsonIgnore
private String identifier;
@JsonProperty("state")
private PHLightState state;
@JsonProperty("type")
private String type;
@JsonProperty("name")
private String name;
@JsonProperty("modelid")
private String modelid;
@JsonProperty("swversion")
private String swversion;
@JsonProperty("uniqueid")
private String uniqueid;
@JsonProperty("pointsymbol")
private Map<String, String> pointsymbol;
public PHLight() {}
public PHLight(PHLight light) {
this.name=light.name;
this.modelid = light.modelid;
this.state = light.state;
this.swversion = light.swversion;
this.type = light.type;
this.uniqueid = light.uniqueid;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public PHLightState getState()
{
return state;
}
public void setState(PHLightState state)
{
this.state = state;
}
public String getModelid()
{
return modelid;
}
public void setModelid(String modelid)
{
this.modelid = modelid;
}
public String getSwversion()
{
return swversion;
}
public void setSwversion(String swversion)
{
this.swversion = swversion;
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
public Map<String, String> getPointsymbol()
{
return pointsymbol;
}
public void setPointsymbol(Map<String, String> pointsymbol)
{
this.pointsymbol = pointsymbol;
}
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getUniqueid() {
return uniqueid;
}
public void setUniqueid(String uniqueid) {
this.uniqueid = uniqueid;
}
}
================================================
FILE: src/com/hueemulator/model/PHLightState.java
================================================
package com.hueemulator.model;
import java.util.List;
import java.util.Locale;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
// @JsonFilter("stateFilter")
public class PHLightState
{
@JsonProperty("on")
private Boolean on;
@JsonProperty("bri")
private Integer bri;
@JsonProperty("hue")
private Integer hue;
@JsonProperty("sat")
private Integer sat;
@JsonProperty("xy")
private List<Double> xy;
@JsonProperty("ct")
private Integer ct;
@JsonProperty("alert")
private String alert;
@JsonProperty("effect")
private String effect;
@JsonProperty("colormode")
private String colormode;
@JsonProperty("reachable")
private Boolean reachable;
@JsonIgnore
private Integer transitionTime;
public PHLightState() { }
public PHLightState(PHLightState lightState) {
this.hue = lightState.hue;
this.bri = lightState.bri;
this.sat = lightState.sat;
this.ct = lightState.ct;
this.on = lightState.on;
this.colormode = lightState.colormode;
this.alert = lightState.alert;
this.reachable = lightState.reachable;
this.xy = lightState.xy;
}
public Integer getBri()
{
return bri;
}
public void setBri(Integer bri)
{
this.bri = bri;
}
public String getEffect()
{
return effect;
}
public void setEffect(String effect)
{
this.effect = effect;
}
public Integer getSat()
{
return sat;
}
public void setSat(Integer sat)
{
this.sat = sat;
}
@JsonIgnore
public Boolean getReachable()
{
return reachable;
}
public void setReachable(Boolean reachable)
{
this.reachable = reachable;
}
public String getAlert()
{
return alert;
}
public void setAlert(String alert)
{
this.alert = alert;
}
public Integer getHue()
{
return hue;
}
public void setHue(Integer hue)
{
this.hue = hue;
}
public String getColormode()
{
return colormode;
}
public void setColormode(String colormode)
{
this.colormode = colormode;
}
public Boolean getOn()
{
return on;
}
public void setOn(Boolean on)
{
this.on = on;
}
public Integer getCt()
{
return ct;
}
public void setCt(Integer ct)
{
this.ct = ct;
}
public List<Double> getXy()
{
return xy;
}
public void setXy(List<Double> xy)
{
this.xy = xy;
}
public JSONObject serializeLightState(PHLightState state) throws JSONException{
JSONObject toSend = new JSONObject();
if(state.getHue() != null) {
toSend.putOpt("hue", state.getHue());
}
if(state.getOn() != null){
toSend.putOpt("on", state.getOn());
}
if(state.getBri() != null) {
toSend.putOpt("bri", state.getBri());
}
if(state.getSat() != null) {
toSend.putOpt("sat", state.getSat());
}
if(state.getTransitionTime() != null) {
toSend.putOpt("transitiontime", state.getTransitionTime());
}
if(state.getCt() != null) {
toSend.putOpt("ct", state.getCt());
}
if (state.getReachable() !=null) {
toSend.putOpt("reachable", state.getReachable());
}
if (state.getXy() != null) {
JSONArray xyArray = new JSONArray();
JSONObject tempX = new JSONObject(String.format(Locale.ENGLISH,"{\"tempX\": %.4f}", state.getXy().get(0)));
JSONObject tempY = new JSONObject(String.format(Locale.ENGLISH,"{\"tempY\": %.4f}", state.getXy().get(1)));
xyArray.put(tempX.get("tempX")); //send 4 decimal places
xyArray.put(tempY.get("tempY"));
toSend.putOpt("xy", xyArray);
}
if(state.getAlert() != null) {
String alert = state.getAlert();
if(alert != null) {
toSend.putOpt("alert", alert);
}
}
if(state.getEffect() != null) {
String effect = state.getEffect();
if(effect != null) {
toSend.putOpt("effect", effect);
}
}
return toSend;
}
@Override
public String toString() {
return "Hue: " + hue + " Bri: " + bri + " sat: " + sat + " on: " + on + " reachable: " + reachable;
}
public Integer getTransitionTime() {
return transitionTime;
}
public void setTransitionTime(Integer transitionTime) {
this.transitionTime = transitionTime;
}
}
================================================
FILE: src/com/hueemulator/model/PHScenesEntry.java
================================================
package com.hueemulator.model;
import java.util.List;
import org.codehaus.jackson.annotate.JsonProperty;
public class PHScenesEntry
{
@JsonProperty("name")
private String name;
@JsonProperty("lights")
private List<String> lights;
@JsonProperty("active")
private boolean active;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public List<String> getLights()
{
return lights;
}
public void setLights(List<String> lights)
{
this.lights = lights;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}
================================================
FILE: src/com/hueemulator/model/PHSchedulesEntry.java
================================================
package com.hueemulator.model;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class PHSchedulesEntry
{
@JsonProperty("time")
private String time;
@JsonProperty("description")
private String description;
@JsonProperty("name")
private String name;
@JsonProperty("command")
private PHCommand command;
public String getTime()
{
return time;
}
public void setTime(String time)
{
this.time = time;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public PHCommand getCommand()
{
return command;
}
public void setCommand(PHCommand command)
{
this.command = command;
}
}
================================================
FILE: src/com/hueemulator/model/PHSwupdate.java
================================================
package com.hueemulator.model;
import org.codehaus.jackson.annotate.JsonProperty;
public class PHSwupdate
{
@JsonProperty("text")
private String text;
@JsonProperty("notify")
private Boolean notify;
@JsonProperty("updatestate")
private Integer updatestate;
@JsonProperty("url")
private String url;
public String getText()
{
return text;
}
public void setText(String text)
{
this.text = text;
}
public Boolean getNotify()
{
return notify;
}
public void setNotify(Boolean notify)
{
this.notify = notify;
}
public Integer getUpdatestate()
{
return updatestate;
}
public void setUpdatestate(Integer updatestate)
{
this.updatestate = updatestate;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
}
================================================
FILE: src/com/hueemulator/model/PHWhitelistEntry.java
================================================
package com.hueemulator.model;
import org.codehaus.jackson.annotate.JsonProperty;
public class PHWhitelistEntry
{
@JsonProperty("last use date")
private String lastUseDate;
@JsonProperty("create date")
private String createDate;
@JsonProperty("name")
private String name;
public String getLastUseDate()
{
return lastUseDate;
}
public void setLastUseDate(String lastUseDate)
{
this.lastUseDate = lastUseDate;
}
public String getCreateDate()
{
return createDate;
}
public void setCreateDate(String createDate)
{
this.createDate = createDate;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
================================================
FILE: src/com/hueemulator/server/MyApiHandler.java
================================================
package com.hueemulator.server;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.ObjectMapper;
import com.hueemulator.emulator.Controller;
import com.hueemulator.model.PHBridgeConfiguration;
import com.hueemulator.server.handlers.ConfigurationAPI;
import com.hueemulator.server.handlers.GroupsAPI;
import com.hueemulator.server.handlers.LightsAPI;
import com.hueemulator.server.handlers.ScenesAPI;
import com.hueemulator.server.handlers.SchedulesAPI;
import com.hueemulator.utils.Utils;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
class MyApiHandler implements HttpHandler {
private PHBridgeConfiguration bridgeConfiguration;
private Controller controller;
private LightsAPI lightsAPIhandler;
private ConfigurationAPI configurationAPIhandler;
private GroupsAPI groupsAPIhandler;
private SchedulesAPI schedulesAPIhandler;
private ScenesAPI scenesAPIhandler;
public MyApiHandler(PHBridgeConfiguration bridgeConfiguration, Controller controller) {
this.bridgeConfiguration = bridgeConfiguration;
this.controller = controller;
lightsAPIhandler = new LightsAPI();
groupsAPIhandler = new GroupsAPI();
schedulesAPIhandler = new SchedulesAPI();
scenesAPIhandler = new ScenesAPI();
configurationAPIhandler = new ConfigurationAPI();
}
public void handle(HttpExchange exchange) throws IOException {
String requestMethod = exchange.getRequestMethod();
String url = exchange.getRequestURI().toString();
OutputStream responseBody = exchange.getResponseBody();
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
responseHeaders.set("Pragma", "no-cache");
responseHeaders.set("Expires", "Mon, 1 Aug 2011 09:00:00 GMT");
responseHeaders.set("Connection", "close"); // Not sure if the server will actually close the connections by just setting the header
responseHeaders.set("Access-Control-Max-Age", "0");
responseHeaders.set("Access-Control-Allow-Origin", "*");
responseHeaders.set("Access-Control-Allow-Credentials", "true");
responseHeaders.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
responseHeaders.set("Access-Control-Allow-Headers", "Content-Type");
if (url.contains("description.xml")) {
responseHeaders.set("Content-Type", "application/xml; charset=utf-8");
}
else {
responseHeaders.set("Content-Type", "application/json; charset=utf-8");
}
exchange.sendResponseHeaders(200, 0);
ObjectMapper mapper = new ObjectMapper();
String urlElements[] = url.split("/");
controller.addTextToConsole(url.toString(), Color.gray, true);
if (url.equals("/api") || url.equals("/api/")) {
configurationAPIhandler.createNewUsername(bridgeConfiguration, responseBody, requestMethod);
}
else if (url.equals("/api/config")|| url.equals("/api/config/")) {
configurationAPIhandler.returnNonAuthenticatedConfig(bridgeConfiguration, responseBody);
}
// Check if username is on the whitelist. If not a JSON "Unauthorized User" response is sent back.
else if (!configurationAPIhandler.isValidUserName(bridgeConfiguration, responseBody, urlElements)) {
configurationAPIhandler.returnErrorResponse("1", "unauthorized user", "/", responseBody);
return;
}
responseHeaders.set("Content-Type", "application/json; charset=utf-8");
if (requestMethod.equalsIgnoreCase("GET")) {
handleGet(mapper, url, responseBody, urlElements);
responseBody.close();
}
else if (requestMethod.equalsIgnoreCase("DELETE")) {
handleDelete(mapper, responseBody, urlElements);
responseBody.close();
}
else if (requestMethod.equalsIgnoreCase("PUT") || requestMethod.equalsIgnoreCase("POST")) {
InputStreamReader isr = new InputStreamReader(exchange.getRequestBody(),"utf-8");
BufferedReader br = new BufferedReader(isr);
String jSONString="";
String line="";
while ((line = br.readLine()) != null) {
jSONString += line;
}
// Check the json is valid, if not return the same response as the bridge.
boolean isValidJSON = Utils.isJSONValid(jSONString);
if (!isValidJSON) {
configurationAPIhandler.returnErrorResponse("2", "body contains invalid json", url, responseBody);
}
controller.addTextToConsole(jSONString, Color.gray, controller.showRequestJson()); // Show the JSON we are sending to the Bridge (i.e. Emulator) in the console.
if (requestMethod.equalsIgnoreCase("PUT")) {
handlePut(mapper, url, responseBody, jSONString, urlElements);
}
if (requestMethod.equalsIgnoreCase("POST")) {
handlePost(mapper, url, responseBody, jSONString, urlElements);
}
} else { // probably OPTIONS
responseBody.close();
}
}
public void handlePut(ObjectMapper mapper, String url, OutputStream responseBody, String jSONString, String[] urlElements) throws JsonParseException, IOException {
int noURLEelements=urlElements.length;
String lastURLElement = urlElements[noURLEelements-1];
if (urlElements[noURLEelements-2].equals("lights")) {
String light=urlElements[noURLEelements-1];
lightsAPIhandler.setLightAttributes_1_5(mapper, jSONString, bridgeConfiguration, responseBody, controller, light);
}
else if (lastURLElement.equals("name")) { // This is a temporary fudge fix for the Java SDK. It is appending /name to the Update Lights URL.
String light=urlElements[noURLEelements-2];
lightsAPIhandler.setLightAttributes_1_5(mapper, jSONString, bridgeConfiguration, responseBody, controller, light);
}
else if (lastURLElement.equals("state")) {
lightsAPIhandler.setLightState_1_6(mapper, jSONString, bridgeConfiguration, responseBody, controller, urlElements[noURLEelements-2]);
}
else if (lastURLElement.equals("action")) {
groupsAPIhandler.setGroupState_2_5(mapper, jSONString, bridgeConfiguration, responseBody, controller, urlElements[noURLEelements-2],lightsAPIhandler);
}
else if (urlElements[noURLEelements-2].equals("groups")) {
String groupIdentifier=urlElements[noURLEelements-1];
groupsAPIhandler.setGroupAttributes_2_4(mapper, jSONString, bridgeConfiguration, responseBody, controller, groupIdentifier);
}
else if (urlElements[noURLEelements-2].equals("schedules")) {
String scheduleIdentifier=urlElements[noURLEelements-1];
schedulesAPIhandler.setScheduleAttributes_3_4(mapper, jSONString, bridgeConfiguration, responseBody, controller, scheduleIdentifier);
}
else if (urlElements[noURLEelements-2].equals("scenes")) {
String sceneIdentifier=urlElements[noURLEelements-1];
scenesAPIhandler.createScene_4_2(mapper, jSONString, bridgeConfiguration, responseBody, controller, sceneIdentifier);
}
}
public void handlePost(ObjectMapper mapper, String url, OutputStream responseBody, String jSONString, String[] urlElements) throws JsonParseException, IOException {
int noURLEelements=urlElements.length;
String lastURLElement = urlElements[noURLEelements-1];
if (lastURLElement.equals("schedules")) {
schedulesAPIhandler.createSchedule_3_2(mapper, jSONString, bridgeConfiguration, responseBody, controller);
}
else if (lastURLElement.equals("groups")) {
groupsAPIhandler.createGroup_2_2(mapper, jSONString, bridgeConfiguration, responseBody, controller);
}
else if (lastURLElement.equals("api")) {
configurationAPIhandler.createUser_7_1(mapper, jSONString, bridgeConfiguration, responseBody, controller);
}
}
public void handleGet(ObjectMapper mapper, String url, OutputStream responseBody, String[] urlElements) throws JsonGenerationException, IOException {
int noURLEelements=urlElements.length;
String lastURLElement = urlElements[noURLEelements-1];
// URL Ends with /lights,
if (lastURLElement.equals("lights")) {
lightsAPIhandler.getAllLights_1_1(mapper, bridgeConfiguration, responseBody, controller);
}
else if (urlElements[noURLEelements-2].equals("lights")) {
String light=urlElements[noURLEelements-1];
lightsAPIhandler.getLightAttributes_1_4(mapper, bridgeConfiguration, responseBody, controller, light);
}
else if (lastURLElement.equals("groups")) {
groupsAPIhandler.getAllGroups_2_1(mapper, bridgeConfiguration, responseBody, controller);
}
else if (lastURLElement.equals("schedules")) {
schedulesAPIhandler.getAllSchedules_3_1(bridgeConfiguration, responseBody, controller);
}
else if (lastURLElement.equals("scenes")) {
scenesAPIhandler.getAllScenes_4_1(mapper, bridgeConfiguration, responseBody, controller);
}
else if (lastURLElement.equals("config")) {
configurationAPIhandler.getConfig_7_2(mapper, bridgeConfiguration, responseBody, controller);
}
else if (urlElements[noURLEelements-2].equals("schedules")) {
String scheduleId=urlElements[noURLEelements-1];
schedulesAPIhandler.getScheduleAttributes_3_3(mapper, bridgeConfiguration, responseBody, controller, scheduleId);
}
else if (urlElements[noURLEelements-2].equals("groups")) {
String groupId=urlElements[noURLEelements-1];
groupsAPIhandler.getGroupAttributes_2_3(mapper, bridgeConfiguration, responseBody, controller, groupId);
}
else {
configurationAPIhandler.getFullState_7_5(mapper, bridgeConfiguration, responseBody, controller);
}
}
public void handleDelete(ObjectMapper mapper, OutputStream responseBody, String[] urlElements) throws JsonParseException, IOException {
int noURLEelements=urlElements.length;
String lastURLElement = urlElements[noURLEelements-1];
if (urlElements[noURLEelements-2].equals("schedules")) {
schedulesAPIhandler.deleteSchedule_3_5(mapper, bridgeConfiguration, responseBody, controller, lastURLElement);
}
else if (urlElements[noURLEelements-2].equals("groups")) {
groupsAPIhandler.deleteGroup_2_6(mapper, bridgeConfiguration, responseBody, controller, lastURLElement);
}
else if (urlElements[noURLEelements-2].equals("whitelist")) {
controller.addTextToConsole("Handling delete for whitelist entry: " + lastURLElement, Color.RED, true);
configurationAPIhandler.deleteUser_7_4(mapper, bridgeConfiguration, responseBody, controller, lastURLElement);
}
}
}
================================================
FILE: src/com/hueemulator/server/MyRootHandler.java
================================================
package com.hueemulator.server;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import com.hueemulator.emulator.Controller;
import com.hueemulator.server.handlers.ConfigurationAPI;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
class MyRootHandler implements HttpHandler {
private Controller controller;
private ConfigurationAPI configurationAPIhandler;
public MyRootHandler(Controller controller) {
this.controller = controller;
configurationAPIhandler = new ConfigurationAPI();
}
public void handle(HttpExchange exchange) throws IOException {
String url = exchange.getRequestURI().toString();
OutputStream responseBody = exchange.getResponseBody();
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
responseHeaders.set("Pragma", "no-cache");
responseHeaders.set("Expires", "Mon, 1 Aug 2011 09:00:00 GMT");
responseHeaders.set("Connection", "close"); // Not sure if the server will actually close the connections by just setting the header
responseHeaders.set("Access-Control-Max-Age", "0");
responseHeaders.set("Access-Control-Allow-Origin", "*");
responseHeaders.set("Access-Control-Allow-Credentials", "true");
responseHeaders.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
responseHeaders.set("Access-Control-Allow-Headers", "Content-Type");
if (url.contains("description.xml")) {
responseHeaders.set("Content-Type", "application/xml; charset=utf-8");
}
else {
responseHeaders.set("Content-Type", "application/json; charset=utf-8");
}
exchange.sendResponseHeaders(200, 0);
if (url.equals("/description.xml")) {
configurationAPIhandler.getBridgeDescription(responseBody, controller.getIpAddress());
controller.addTextToConsole(url.toString(), Color.gray, true);
}
}
}
================================================
FILE: src/com/hueemulator/server/Server.java
================================================
package com.hueemulator.server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import com.hueemulator.emulator.Controller;
import com.hueemulator.model.PHBridgeConfiguration;
import com.sun.net.httpserver.HttpServer;
public class Server {
private HttpServer httpServer;
public Server(PHBridgeConfiguration bridgeConfiguration, Controller controller, String portNumber) throws IOException {
InetSocketAddress addr = new InetSocketAddress(Integer.valueOf(portNumber));
httpServer = HttpServer.create(addr, 0);
createContext(bridgeConfiguration, controller);
httpServer.setExecutor(Executors.newCachedThreadPool());
}
public void createContext(PHBridgeConfiguration bridgeConfiguration, Controller controller) {
httpServer.createContext("/", new MyRootHandler(controller));
httpServer.createContext("/api", new MyApiHandler(bridgeConfiguration, controller));
}
public void removeContext() {
httpServer.removeContext("/api");
httpServer.removeContext("/");
}
public HttpServer getHttpServer() {
return httpServer;
}
public void setHttpServer(HttpServer httpServer) {
this.httpServer = httpServer;
}
}
================================================
FILE: src/com/hueemulator/server/UPNPServer.java
================================================
package com.hueemulator.server;
import java.awt.Color;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import com.hueemulator.emulator.Controller;
public class UPNPServer extends Thread {
private static final int UPNP_PORT = 1901;
public DatagramSocket socket;
public boolean runUPNPServer=true;
public Controller controller;
// First implementation of a UPNP server. Am not sure if this is the correct implementation but it seems to work. The emulator is found by SDK bridge searches.
// It will be improved if the implementation is faulty, as it could well be as this (java network stuff) not my strong point.
public UPNPServer(Controller controller) {
this.controller = controller;
try {
socket = new DatagramSocket(UPNP_PORT);
} catch (SocketException e) {
controller.addTextToConsole("Cound not run UPnP Server", Color.RED, true);
System.out.println("Cound not run UPnP Server: " + e.getLocalizedMessage());
}
}
public void run() {
System.out.println("Starting Server");
while (runUPNPServer) {
try {
byte[] buf = new byte[256];
// don't wait for request...just send a quote
String remoteIP = InetAddress.getLocalHost().getHostAddress();
String msg;
msg = "HTTP/1.1 200 OK\r\n" +
"CACHE-CONTROL: max-age=100\r\n" +
"EXT:\r\n" +
"LOCATION: http://" + remoteIP + ":80/description.xml\r\n" +
"SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/0.1\r\n" +
"ST: uuid:0FDD7736-722C-4995-89F2-ABCDEF000000\r\n" +
"USN: uuid:0FDD7736-722C-4995-89F2-ABCDEF000000\r\n" +
"\r\n";
buf = msg.getBytes();
InetAddress group = InetAddress.getByName("239.255.255.250");
DatagramPacket packet;
packet = new DatagramPacket(buf, buf.length, group, UPNP_PORT);
socket.send(packet);
try {
sleep(2000); // Wait 2 seconds
}
catch (InterruptedException e) { }
}
catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
public void startUPNPServer() {
runUPNPServer=true;
start();
}
public void stopUPNPServer() {
runUPNPServer=false;
}
}
================================================
FILE: src/com/hueemulator/server/handlers/ConfigurationAPI.java
================================================
package com.hueemulator.server.handlers;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.JSONArray;
import org.json.JSONObject;
import com.hueemulator.emulator.Controller;
import com.hueemulator.model.PHBridgeConfiguration;
import com.hueemulator.model.PHConfig;
import com.hueemulator.model.PHWhitelistEntry;
import com.hueemulator.utils.Utils;
public class ConfigurationAPI {
// Used for Pushlinking. Stores all usernames (that are being created).
// For pushlinking you have to click anywhere on the bridge panel
public List<String> users = new ArrayList<String>();
public void getBridgeDescription(OutputStream responseBody, String ipAddressAndPort) {
String descriptionFile = "";
try {
descriptionFile = Utils.loadDescriptionFile("/description.xml");
} catch (IOException e) {
e.printStackTrace();
}
descriptionFile = descriptionFile.replace("##URLBASE##", ipAddressAndPort);
try {
responseBody.write(descriptionFile.getBytes());
responseBody.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 7.1 CREATE USER
// http://www.developers.meethue.com/documentation/configuration-api#71_create_user 7.1 Create User
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void createUser_7_1(ObjectMapper mapper, String jSONString, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller) throws JsonParseException, IOException {
PHWhitelistEntry whitelistEntry = new PHWhitelistEntry();
String responseBase = "/api/";
String resourceUrl="";
String errorDescription="";
String userName="";
String name="";
String errorCode = "7";
JSONArray responseArray = new JSONArray();
JSONObject jObject = new JSONObject(jSONString);
if (jObject != null) {
JSONArray names = jObject.names();
boolean isSuccess=true; // Success is returned for a valid fieldname, if a field name is invalid then an "error" is returned.
JSONObject successObject = new JSONObject();
responseArray.put(successObject);
for (int i=0; i<names.length(); i++) {
name = names.getString(i);
resourceUrl = responseBase + name;
userName = Utils.generateRandomUsername();
if (!controller.isHasBridgeBeenPushLinked() ) {
controller.setHasBridgeBeenPushLinked(false);
errorDescription = "link button not pressed";
controller.addTextToConsole("Mouse click anywhere close to the bridge image (Graphical View) to simulate Push linking the bridge.", Color.RED, controller.showResponseJson());
isSuccess=false;
errorCode="101";
resourceUrl=""; // Copying what the bridge returns here.
users.add(userName);
}
else if (controller.isHasBridgeBeenPushLinked()){
isSuccess=true;
}
if (name.equals("devicetype")) {
String devicetype = jObject.optString(name);
if (devicetype == null || devicetype.length() > 40) {
errorDescription = "invalid value, " + devicetype + ", for parameter, devicetype";
isSuccess=false;
}
else {
whitelistEntry.setName(devicetype);
}
}
if (!isSuccess) { // Handle errors, i.e. Non Supported fields
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", errorCode);
errorLine.putOpt("address", resourceUrl);
errorLine.putOpt("description", errorDescription);
successObject.putOpt("error", errorLine);
break;
}
} // For Names
if (isSuccess) {
JSONObject idObject = new JSONObject();
idObject.put("username", userName);
successObject.putOpt("success", idObject);
whitelistEntry.setCreateDate(Utils.getCurrentDate());
whitelistEntry.setLastUseDate(Utils.getCurrentDate());
bridgeConfiguration.getConfig().getWhitelist().put(userName, whitelistEntry);
}
} // JObject !=null
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
controller.addTextToConsole(responseArray.toString(), Color.WHITE, controller.showResponseJson());
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 7.2 GET CONFIGURATION
// http://www.developers.meethue.com/documentation/configuration-api#72_get_configuration 7.2 Get Configuration
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void getConfig_7_2(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller) throws JsonParseException, IOException {
PHConfig config = bridgeConfiguration.getConfig();
mapper.writeValue(responseBody, config); // Write to the response.
controller.addTextToConsole(mapper.writeValueAsString(config), Color.WHITE, controller.showResponseJson());
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 7.4 DELETE USER FROM WHITELIST
// http://www.developers.meethue.com/documentation/configuration-api#74_delete_user_from_whitelist 7.4 Delete user from whitelist
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void deleteUser_7_4(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String removingUsername) throws JsonParseException, IOException {
bridgeConfiguration.getConfig().getWhitelist().remove(removingUsername);
JSONObject responseObj = new JSONObject();
responseObj.put("success", "/config/whitelist/" + removingUsername + " deleted.");
mapper.writeValue(responseBody, responseObj); // Write to the response.
controller.addTextToConsole(mapper.writeValueAsString(responseObj), Color.WHITE, controller.showResponseJson());
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 7.5 GET FULL STATE (DATASTORE)
// http://www.developers.meethue.com/documentation/configuration-api#75_get_full_state_datastore 7.5 Get Full State (DataStore
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void getFullState_7_5(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller) throws JsonParseException, IOException {
mapper.writeValue(responseBody, bridgeConfiguration); // Write to the response.
if (controller.getModel().isShowFullConfig()) { // The full config can be large, and displayed every 10 seconds if an app has it enabled, so we have the option to hide this.
controller.addTextToConsole(mapper.writeValueAsString(bridgeConfiguration), Color.WHITE, controller.showResponseJson());
}
}
public boolean isValidUserName(PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, String[] urlElements) {
if (urlElements.length < 3) {
return false;
}
String username = urlElements[2];
Map<String, PHWhitelistEntry> whiteListMap = bridgeConfiguration.getConfig().getWhitelist();
Iterator it = whiteListMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry <String, PHWhitelistEntry> entry = (Map.Entry) it.next();
String whiteListUsername = (String)entry.getKey();
if (whiteListUsername.equals(username)) {
whiteListMap.get(username).setLastUseDate(Utils.getCurrentDate()); // Set the last use date.
return true;
}
}
return false; // An unauthorized user
}
public void createNewUsername(PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, String requestMethod) {
if (!requestMethod.equalsIgnoreCase("POST")) {
returnErrorResponse("3", "method, " + requestMethod + ", not available for resource, /", "/", responseBody);
}
}
// The Hue Bridge returns some fields when a <IP ADDRESS>/api/config is sent (with no authenticated usernames). See 'Bridge Information without a valid user" here: http://www.developers.meethue.com/documentation/message-structure-and-response-0
public void returnNonAuthenticatedConfig(PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody) {
JSONObject responseObject = new JSONObject();
responseObject.put("name", bridgeConfiguration.getConfig().getName());
responseObject.put("mac", bridgeConfiguration.getConfig().getMac());
responseObject.put("bridgeid", bridgeConfiguration.getConfig().getBridgeid());
responseObject.put("modelid", bridgeConfiguration.getConfig().getModelid());
try {
responseBody.write(responseObject.toString().getBytes());
responseBody.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void returnErrorResponse(String errorType, String description, String address, OutputStream responseBody) {
JSONObject errorObject = new JSONObject();
JSONArray responseArray = new JSONArray();
responseArray.put(errorObject);
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", errorType);
errorLine.putOpt("address", address);
errorLine.putOpt("description", description);
errorObject.putOpt("error", errorLine);
try {
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
================================================
FILE: src/com/hueemulator/server/handlers/GroupsAPI.java
================================================
package com.hueemulator.server.handlers;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.JSONArray;
import org.json.JSONObject;
import com.hueemulator.emulator.Controller;
import com.hueemulator.model.PHBridgeConfiguration;
import com.hueemulator.model.PHGroupsEntry;
import com.hueemulator.model.PHLight;
import com.hueemulator.model.PHLightState;
import com.hueemulator.utils.Utils;
public class GroupsAPI {
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 2.1 GET ALL GROUPS
// http://www.developers.meethue.com/documentation/groups-api#21_get_all_groups 2.1. Get all groups
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void getAllGroups_2_1(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller) throws JsonParseException, IOException {
Map <String, PHGroupsEntry> groupsMap = bridgeConfiguration.getGroups();
Iterator it = groupsMap.entrySet().iterator();
JSONObject groupsResponseJson = new JSONObject();
while (it.hasNext()) {
Map.Entry <String, PHGroupsEntry> entry = (Map.Entry) it.next();
String identifier = (String)entry.getKey();
PHGroupsEntry group = (PHGroupsEntry) entry.getValue();
JSONObject groupsJson = new JSONObject();
groupsJson.putOpt("name", group.getName());
groupsJson.putOpt("lights", group.getLightIdentifiers());
JSONObject actionJson = new JSONObject(group.getLightState());
groupsJson.putOpt("action", actionJson);
groupsResponseJson.putOpt(identifier, groupsJson);
}
responseBody.write(groupsResponseJson.toString().getBytes());
responseBody.close();
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 2.2 CREATE GROUP
// http://www.developers.meethue.com/documentation/groups-api#22_create_group 3.2. Create Group
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void createGroup_2_2(ObjectMapper mapper, String jSONString, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller) throws JsonParseException, IOException {
PHGroupsEntry groupObject = new PHGroupsEntry();
String responseBase = "/groups/";
String resourceUrl="";
String errorDescription="";
String name="group";
JSONArray responseArray = new JSONArray();
String nextGroupNumber = Integer.toString(bridgeConfiguration.getGroups().size() + 1);
JSONObject jObject = new JSONObject(jSONString);
if (jObject != null) {
JSONArray names = jObject.names();
boolean isSuccess=true; // Success is returned for a valid fieldname, if a field name is invalid then an "error" is returned.
JSONObject successObject = new JSONObject();
responseArray.put(successObject);
for (int i=0; i<names.length(); i++) {
name = names.getString(i);
resourceUrl = responseBase + name;
if (name.equals("name")) {
String groupName = jObject.optString(name);
if (groupName == null || groupName.length() > 32) {
errorDescription = "invalid value, " + groupName + ", for parameter, name";
isSuccess=false;
}
else {
groupObject.setName(groupName);
}
}
else if (name.equals("lights")) {
JSONArray lightsArray = jObject.optJSONArray("lights");
List<String> lightIdentifiers = new ArrayList();
for (int a=0; a< lightsArray.length(); a++) {
lightIdentifiers.add(lightsArray.get(a).toString());
}
groupObject.setLightIdentifiers(lightIdentifiers);
}
if (!isSuccess) { // Handle errors, i.e. Non Supported fields
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", 7);
errorLine.putOpt("address", resourceUrl);
errorLine.putOpt("description", errorDescription);
successObject.putOpt("error", errorLine);
break;
}
} // For Names
if (isSuccess) {
JSONObject idObject = new JSONObject();
idObject.put("id", responseBase + nextGroupNumber);
successObject.putOpt("success", idObject);
bridgeConfiguration.getGroups().put(nextGroupNumber, groupObject);
}
} // JObject !=null
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
controller.addTextToConsole(responseArray.toString(), Color.WHITE, controller.showResponseJson());
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 2.3 GET GROUP ATTRIBUTES
// http://www.developers.meethue.com/documentation/groups-api#23_get_group_attributes 2.3. Get group attributes
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void getGroupAttributes_2_3(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String groupIdentifier) throws JsonParseException, IOException {
if (bridgeConfiguration.getGroups() == null || bridgeConfiguration.getGroups().get(groupIdentifier) == null) {
sendErrorResponse(groupIdentifier, "3", responseBody);
}
else {
mapper.writeValue(responseBody, bridgeConfiguration.getGroups().get(groupIdentifier)); // Write to the response.
controller.addTextToConsole(mapper.writeValueAsString(bridgeConfiguration.getGroups().get(groupIdentifier)), Color.WHITE, controller.showResponseJson());
}
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 2.4 SET GROUP ATTRIBUTES
// http://www.developers.meethue.com/documentation/groups-api#24_set_group_attributes 2.4. Set group attributes
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void setGroupAttributes_2_4(ObjectMapper mapper, String jSONString, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String groupIdentifier) throws JsonParseException, IOException {
if (bridgeConfiguration.getGroups() == null || bridgeConfiguration.getGroups().get(groupIdentifier) == null) {
sendErrorResponse(groupIdentifier, "3", responseBody);
}
PHGroupsEntry groupObject = bridgeConfiguration.getGroups().get(groupIdentifier);
String responseBase = "/groups/" + groupIdentifier + "/";
String resourceUrl="";
JSONArray responseArray = new JSONArray();
JSONObject jObject = new JSONObject(jSONString);
if (jObject != null) {
JSONArray names = jObject.names();
for (int i=0; i<names.length(); i++) {
JSONObject successObject = new JSONObject();
boolean isSuccess=true; // Success is returned for a valid fieldname, if a field name is invalid then an "error" is returned.
responseArray.put(successObject);
JSONObject successLine = new JSONObject();
String name = names.getString(i);
resourceUrl = responseBase + name;
if (name.equals("name")) {
String lightName = jObject.optString(name);
if (lightName == null || lightName.length() > 32) {
isSuccess=false;
}
else {
successLine.putOpt(resourceUrl, lightName);
groupObject.setName(lightName);
}
}
else if (name.equals("lights")) {
JSONArray lightsArray = jObject.optJSONArray("lights");
List<String> lightIdentifiers = new ArrayList();
if (lightsArray.length() == 0) {
isSuccess=false;
}
else {
for (int a=0; a< lightsArray.length(); a++) {
lightIdentifiers.add(lightsArray.get(a).toString());
}
successLine.putOpt(resourceUrl, lightIdentifiers);
groupObject.setLightIdentifiers(lightIdentifiers);
}
}
if (!isSuccess) { // Handle errors, i.e. Non Supported fields
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", 7);
errorLine.putOpt("address", resourceUrl);
errorLine.putOpt("description", "invalid value, " + Utils.chopName(jObject.optString(name)) + ", for parameter, name");
successObject.putOpt("error", errorLine);
}
if (isSuccess) {
successObject.putOpt("success", successLine);
}
}
}
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
bridgeConfiguration.getGroups().put(groupIdentifier, groupObject);
controller.addTextToConsole(responseArray.toString(), Color.WHITE, controller.showResponseJson());
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 2.5 SET GROUP STATE
// http://www.developers.meethue.com/documentation/groups-api#25_set_group_state 2.5. Set Group State
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void setGroupState_2_5(ObjectMapper mapper, String jSONString, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String groupIdentifier, LightsAPI lightsAPI) throws JsonParseException, IOException {
String resourceUrl = "/groups/" + groupIdentifier + "/action/";
if (bridgeConfiguration.getLights() == null) {
sendErrorResponse(groupIdentifier, "3", responseBody);
}
Map<String, PHLight> allLights;
if (groupIdentifier.equals("0")) { // 0 is the default 'all lights' group
allLights = bridgeConfiguration.getLights();
}
else {
allLights = new HashMap<String, PHLight>();
Map <String, PHLight> lightsMap = bridgeConfiguration.getLights();
PHGroupsEntry group = bridgeConfiguration.getGroups().get(groupIdentifier); // Get the selected group, so we can filter out the lights in this group.
Iterator it = lightsMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry <String, PHLight> entry = (Map.Entry) it.next();
String identifier = (String)entry.getKey();
PHLight light = (PHLight) entry.getValue();
if (group.getLightIdentifiers().contains(identifier)) {
allLights.put(identifier, light);
}
}
}
JSONArray responseArray = new JSONArray();
if (jSONString.indexOf("\"scene\"") != -1) { // Scene recall here (http://www.developers.meethue.com/documentation/scenes-api#44_recall_scene)
JSONObject jsonObject = new JSONObject(jSONString);
String sceneId = jsonObject.optString("scene");
System.out.println("Recalling scene: " + sceneId);
if (ScenesAPI.emulatorScenes.containsKey(sceneId)) { // i.e. This scene has been set
for (PHLight lightInScene: ScenesAPI.emulatorScenes.get(sceneId)) {
lightInScene.setState(lightInScene.getState());
// Clone the light state object here (using the copy constructor), so the stored scene lights do not get overwritten.
PHLightState newState = new PHLightState(lightInScene.getState());
System.out.println("Recall scene hue is: " + newState.getHue());
JSONObject jsonLightStateObject = newState.serializeLightState(newState);
System.out.println(" JSON STRING: "+ jsonLightStateObject.toString());
// TODO Instead of the below Send the JSON String to the lightsAPI.setLightState so we get the success response from the bridge.
bridgeConfiguration.getLights().get(lightInScene.getIdentifier()).setState(newState);
}
}
}
else {
Iterator it = allLights.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
PHLight light = (PHLight) entry.getValue();
PHLightState ls = light.getState();
lightsAPI.setLightState(resourceUrl, light.getModelid(), ls, responseArray, jSONString);
light.setState(ls);
}
}
// Here the Response array has duplicates (i.e. commands for each bulb) so duplicates are filtered. Also error messages are removed, as these are not caught by a group command.
responseArray = removeDuplicates(responseArray, true);
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
controller.addTextToConsole(responseArray.toString(), Color.WHITE, controller.showResponseJson());
}
public static JSONArray removeDuplicates(JSONArray originalArray, boolean removeErrors) {
List currentObjs = new ArrayList();
JSONArray newArray = new JSONArray();
boolean includeLine=true;
for (int i=0; i< originalArray.length(); i++) {
Object obj = originalArray.get(i);
String jsonString = originalArray.getJSONObject(i).toString();
includeLine=true;
if (removeErrors && jsonString.startsWith("{\"error\":{")) {
includeLine=false;
}
if (!currentObjs.contains(obj)) {
if (includeLine) {
newArray.put(obj);
}
}
currentObjs.add(obj);
}
return newArray;
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 2.6 DELETE GROUP
// http://www.developers.meethue.com/documentation/groups-api#26_delete_group 3.5. Delete group
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void deleteGroup_2_6(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String groupIdentifier) throws JsonParseException, IOException {
if (bridgeConfiguration.getGroups() == null || bridgeConfiguration.getGroups().get(groupIdentifier) == null) {
sendErrorResponse(groupIdentifier, "3", responseBody);
}
else {
bridgeConfiguration.getGroups().remove(groupIdentifier);
String resourceURL = "/groups/" + groupIdentifier + " deleted";
JSONArray jsonArray = new JSONArray();
JSONObject responseObject = new JSONObject();
responseObject.putOpt("success", resourceURL);
jsonArray.put(responseObject);
String responseText = jsonArray.toString();
responseBody.write(responseText.getBytes());
responseBody.close();
controller.addTextToConsole(responseText, Color.WHITE, controller.showResponseJson());
}
}
public void sendErrorResponse(String groupIdentifier, String type, OutputStream responseBody) throws IOException {
JSONArray responseArray = new JSONArray();
JSONObject errorObject = new JSONObject();
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", type);
errorLine.putOpt("address", "/groups/" + groupIdentifier);
errorLine.putOpt("description", "resource, /groups/" + groupIdentifier + ", not available");
errorObject.putOpt("error", errorLine);
responseArray.put(errorObject);
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
}
// Returns a list of PHLight objects from a list of Strings (Light Identifiers).
public List<PHLight> getLightObjectsFromLightIds(PHBridgeConfiguration bridgeConfiguration, List <String>lightIdentifiers) {
List <PHLight> phLightList = new ArrayList<PHLight>();
for (String sceneLight: lightIdentifiers) {
phLightList.add(bridgeConfiguration.getLights().get(sceneLight));
}
return phLightList;
}
}
================================================
FILE: src/com/hueemulator/server/handlers/LightsAPI.java
================================================
package com.hueemulator.server.handlers;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.JSONArray;
import org.json.JSONObject;
import com.hueemulator.emulator.Constants;
import com.hueemulator.emulator.Controller;
import com.hueemulator.model.PHBridgeConfiguration;
import com.hueemulator.model.PHLight;
import com.hueemulator.model.PHLightState;
import com.hueemulator.model.PHSchedulesEntry;
import com.hueemulator.utils.PHUtilitiesHelper;
import com.hueemulator.utils.PointF;
import com.hueemulator.utils.Utils;
public class LightsAPI {
DecimalFormat fourDP = new DecimalFormat("#.####");
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 1.1 GET ALL LIGHTS
// http://www.developers.meethue.com/documentation/lights-api#11_get_all_lights 1.1. Get all lights
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void getAllLights_1_1(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller) throws JsonParseException, IOException {
Map <String, PHLight> lightsMap = bridgeConfiguration.getLights();
// mapper.writeValue(responseBody, lightsMap); // Write to the response.
JSONObject lightsJson = new JSONObject();
for (Map.Entry<String, PHLight> entry : lightsMap.entrySet()) {
PHLight light = entry.getValue();
lightsJson.put(entry.getKey(), getLightJSON(light));
}
responseBody.write(lightsJson.toString().getBytes());
responseBody.close();
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 1.4 GET LIGHT ATTRIBUTES AND STATE
// http://www.developers.meethue.com/documentation/lights-api#14_get_light_attributes_and_state 1.4. Get light attributes and state
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void getLightAttributes_1_4(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String lightIdentifier) throws JsonParseException, IOException {
if (bridgeConfiguration.getLights() == null || bridgeConfiguration.getLights().get(lightIdentifier) == null) {
sendErrorResponse(lightIdentifier, "3", responseBody);
}
else {
responseBody.write(getLightJSON(bridgeConfiguration.getLights().get(lightIdentifier)).toString().getBytes());
responseBody.close();
// mapper.writeValue(responseBody, bridgeConfiguration.getLights().get(lightIdentifier)); // Write to the response.
controller.addTextToConsole(mapper.writeValueAsString(bridgeConfiguration.getLights().get(lightIdentifier)),Color.WHITE, controller.showResponseJson());
}
}
public JSONObject getLightJSON(PHLight light) {
JSONObject lightJson = new JSONObject();
JSONObject stateJson = new JSONObject();
PHLightState state = light.getState();
stateJson.putOpt("on", state.getOn());
stateJson.putOpt("bri", state.getBri());
if (!light.getModelid().equals(Constants.MODEL_ID_LUX_BULB)) {
stateJson.putOpt("sat", state.getSat());
stateJson.putOpt("hue", state.getHue());
stateJson.putOpt("xy", state.getXy());
stateJson.putOpt("ct", state.getCt());
stateJson.putOpt("effect", state.getEffect());
stateJson.putOpt("colormode", state.getColormode());
}
stateJson.putOpt("alert", state.getAlert());
stateJson.putOpt("reachable", state.getReachable());
lightJson.putOpt("state", stateJson);
lightJson.putOpt("type", light.getType());
lightJson.putOpt("name", light.getName());
lightJson.putOpt("swversion", light.getSwversion());
lightJson.putOpt("uniqueid", light.getUniqueid());
lightJson.putOpt("modelid", light.getModelid());
lightJson.putOpt("pointsymbol", light.getPointsymbol());
return lightJson;
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 1.5 SET LIGHT ATTRIBUTES
// http://www.developers.meethue.com/documentation/lights-api#15_set_light_attributes_rename 1.5. Set light attributes (rename)
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void setLightAttributes_1_5(ObjectMapper mapper, String jSONString, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String light) throws JsonParseException, IOException {
PHLight lightObject = bridgeConfiguration.getLights().get(light);
String responseBase = "/lights/" + light + "/";
String resourceUrl="";
JSONArray responseArray = new JSONArray();
JSONObject jObject = new JSONObject(jSONString);
if (jObject != null) {
JSONArray names = jObject.names();
for (int i=0; i<names.length(); i++) {
JSONObject successObject = new JSONObject();
boolean isSuccess=true; // Success is returned for a valid fieldname, if a field name is invalid then an "error" is returned.
responseArray.put(successObject);
JSONObject successLine = new JSONObject();
String name = names.getString(i);
resourceUrl = responseBase + name;
if (name.equals("name")) {
String lightName = jObject.optString("name");
if (lightName == null || lightName.length() > 32) {
isSuccess=false;
}
else {
successLine.putOpt(resourceUrl, lightName);
lightObject.setName(lightName);
}
}
if (!isSuccess) { // Handle errors, i.e. Non Supported fields
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", 7);
errorLine.putOpt("address", resourceUrl);
errorLine.putOpt("description", "invalid value, " + Utils.chopName(jObject.optString(name)) + ", for parameter, name");
successObject.putOpt("error", errorLine);
}
if (isSuccess) {
successObject.putOpt("success", successLine);
}
}
}
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
bridgeConfiguration.getLights().put(light, lightObject);
controller.addTextToConsole(responseArray.toString(), Color.WHITE, controller.showResponseJson());
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 1.6 SET LIGHT STATE
// http://www.developers.meethue.com/documentation/lights-api#16_set_light_state 1.6. Set light state
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void setLightState_1_6(ObjectMapper mapper, String jSONString, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String lightIdentifier) throws JsonParseException, IOException {
String resourceUrl = "/lights/" + lightIdentifier + "/state/";
if (bridgeConfiguration.getLights() == null || bridgeConfiguration.getLights().get(lightIdentifier) == null) {
sendErrorResponse(lightIdentifier, "3", responseBody);
}
PHLightState ls = bridgeConfiguration.getLights().get(lightIdentifier).getState();
String lightType = bridgeConfiguration.getLights().get(lightIdentifier).getType();
JSONArray responseArray = new JSONArray();
setLightState(resourceUrl,lightType, ls, responseArray, jSONString);
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
bridgeConfiguration.getLights().get(lightIdentifier).setState(ls);
controller.addTextToConsole(responseArray.toString(), Color.WHITE, controller.showResponseJson());
}
public void setLightState(String baseUrl, String lightType, PHLightState ls, JSONArray responseArray, String jSONString) {
JSONObject jObject = new JSONObject(jSONString);
if (jObject != null) {
JSONArray names = jObject.names();
boolean isOn = ls.getOn(); // An attempt to modify the state of a bulb which is off results in a bridge error.
if (jObject.has("on")) { // do not throw an error when 'on' is set to true.
isOn = jObject.getBoolean("on");
}
for (int i=0; i<names.length(); i++) {
JSONObject successObject = new JSONObject();
JSONObject successLine = new JSONObject();
String name = names.getString(i);
String errorDescription="";
int errorType=0;
String resourceUrl=baseUrl + name;
responseArray.put(successObject);
boolean isSuccess=true; // Success is returned for a valid fieldname, if a field name is invalid then an "error" is returned.
if (name.equals("on")) {
successLine.putOpt(resourceUrl, jObject.optBoolean(name));
ls.setOn(jObject.optBoolean(name));
}
else if (name.equals("hue") && !lightType.equals(Constants.LIGHT_TYPE_LUX_BULB) ) {
int val = jObject.optInt(name);
if (!isOn) {
isSuccess=false; errorType=201; errorDescription = "parameter, hue, is not modifiable. Device is set to off.";
}
else if (Utils.isInRange(val, 0, 65535)) {
successLine.putOpt(resourceUrl, val);
ls.setHue(val);
}
else {
isSuccess=false;
errorDescription = "invalid value, " + val + " , for parameter, hue";
errorType=7;
}
}
else if (name.equals("bri")) {
int val = jObject.optInt(name);
if (!isOn) {
isSuccess=false; errorType=201; errorDescription = "parameter, bri, is not modifiable. Device is set to off.";
}
else if (Utils.isInRange(val, 0, 255)) {
successLine.putOpt(resourceUrl, val);
ls.setBri(val);
}
else {
isSuccess=false;
errorDescription = "invalid value, " + val + " , for parameter, bri";
errorType=7;
}
}
else if (name.equals("sat") && !lightType.equals(Constants.LIGHT_TYPE_LUX_BULB)) {
int val = jObject.optInt(name);
if (!isOn) {
isSuccess=false; errorType=201; errorDescription = "parameter, sat, is not modifiable. Device is set to off.";
}
else if (Utils.isInRange(val, 0, 255)) {
successLine.putOpt(resourceUrl, val);
ls.setSat(val);
}
else {
isSuccess=false;
errorDescription = "invalid value, " + val + " , for parameter, sat";
errorType=7;
}
}
else if (name.equals("ct") && !lightType.equals(Constants.LIGHT_TYPE_LUX_BULB)) {
if (!isOn) {
isSuccess=false; errorType=201; errorDescription = "parameter, ct, is not modifiable. Device is set to off.";
}
else {
successLine.putOpt(resourceUrl, jObject.optInt(name));
ls.setCt(jObject.optInt(name));
}
}
else if (name.equals("xy") && !lightType.equals(Constants.LIGHT_TYPE_LUX_BULB)) {
if (!isOn) {
isSuccess=false; errorType=201; errorDescription = "parameter, xy, is not modifiable. Device is set to off.";
}
else {
JSONArray xyArray = jObject.optJSONArray("xy");
successLine.putOpt(resourceUrl, xyArray);
float point1 = Float.valueOf(xyArray.get(0).toString());
float point2 = Float.valueOf(xyArray.get(1).toString());
PointF xy = new PointF(point1,point2);
xy = PHUtilitiesHelper.fixIfOutOfRange(xy, Constants.MODEL_ID_COLOR_BULB); // If the sent x/y values are out of range, the find the closest point.
float[] xyFloatArray = {xy.x, xy.y};
int colour = PHUtilitiesHelper.colorFromXY(xyFloatArray, Constants.MODEL_ID_COLOR_BULB);
Color col = new Color(colour);
int r = col.getRed();
int g = col.getGreen();
int b = col.getBlue();
float[] hsv = new float[3];
Color.RGBtoHSB(r,g,b,hsv);
// Recalculate Hue
ls.setHue((int) (hsv[0] * 65535));
ls.setSat((int) (hsv[1] * 254));
List<Double> xyList = new ArrayList();
String xStr = fourDP.format(xy.x);
String yStr = fourDP.format(xy.y);
xyList.add(Double.valueOf(xStr));
xyList.add(Double.valueOf(yStr));
ls.setXy(xyList);
}
}
else if (name.equals("effect") && !lightType.equals(Constants.LIGHT_TYPE_LUX_BULB)) {
String effect = jObject.optString(name);
if (!isOn) {
isSuccess=false; errorType=201; errorDescription = "parameter, effect, is not modifiable. Device is set to off.";
}
else if (effect==null || (!effect.equals("none") && !effect.equals("colorloop"))) {
isSuccess=false;
errorDescription = "invalid value, " + effect + " , for parameter, effect";
errorType=7;
}
else {
successLine.putOpt(resourceUrl, effect);
ls.setEffect(effect);
}
}
else if (name.equals("alert")) {
String alert = jObject.optString(name);
if (!isOn) {
isSuccess=false; errorType=201; errorDescription = "parameter, alert, is not modifiable. Device is set to off.";
}
else if (alert==null || (!alert.equals("none") && !alert.equals("select") && !alert.equals("lselect"))) {
isSuccess=false;
errorDescription = "invalid value, " + alert + " , for parameter, alert";
errorType=7;
}
else {
successLine.putOpt(resourceUrl, alert);
ls.setAlert(alert);
}
}
else if (name.equals("reachable")) {
successLine.putOpt(resourceUrl, jObject.optBoolean(name));
ls.setReachable(jObject.optBoolean(name));
}
else if (name.equals("transitiontime")) {
int val = jObject.optInt(name);
if (!isOn) {
isSuccess=false; errorType=201; errorDescription = "parameter, transitiontime, is not modifiable. Device is set to off.";
}
else{
successLine.putOpt(resourceUrl, val);
}
}
else {
isSuccess=false; // Handle errors, i.e. Non Supported fields
errorDescription = "parameter, " + name + ", not available";
errorType=6;
}
if (!isSuccess) {
isSuccess=false;
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", errorType);
errorLine.putOpt("address", resourceUrl);
errorLine.putOpt("description", errorDescription);
successObject.putOpt("error", errorLine);
}
if (isSuccess) {
successObject.putOpt("success", successLine);
}
} // End of for loop.
}
}
public void sendErrorResponse(String lightIdentifier, String type, OutputStream responseBody) throws IOException {
JSONArray responseArray = new JSONArray();
JSONObject errorObject = new JSONObject();
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", type);
errorLine.putOpt("address", "/lights/" + lightIdentifier);
errorLine.putOpt("description", "resource, /lights/" + lightIdentifier + ", not available");
errorObject.putOpt("error", errorLine);
responseArray.put(errorObject);
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
}
}
================================================
FILE: src/com/hueemulator/server/handlers/ScenesAPI.java
================================================
package com.hueemulator.server.handlers;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.JSONArray;
import org.json.JSONObject;
import com.hueemulator.emulator.Controller;
import com.hueemulator.model.PHBridgeConfiguration;
import com.hueemulator.model.PHLight;
import com.hueemulator.model.PHLightState;
import com.hueemulator.model.PHScenesEntry;
public class ScenesAPI {
// In the bridge, the light states for each scene are stored in the bulbs (not in the Bridge JSON/COnfig). Hence this map is for storing the LightStates for each scene.
public static Map<String, List<PHLight>> emulatorScenes = new HashMap<String, List<PHLight>>();
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 4.1 GET ALL SCENES
// http://www.developers.meethue.com/documentation/scenes-api#41_get_all_scenes 4.1. Get all scenes
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void getAllScenes_4_1(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller) throws JsonParseException, IOException {
Map <String, PHScenesEntry> scenesMap = bridgeConfiguration.getScenes();
Iterator it = scenesMap.entrySet().iterator();
JSONObject scenesResponseJson = new JSONObject();
while (it.hasNext()) {
Map.Entry <String, PHScenesEntry> entry = (Map.Entry) it.next();
String identifier = (String) entry.getKey();
PHScenesEntry scene = (PHScenesEntry) entry.getValue();
JSONObject scenesJson = new JSONObject();
scenesJson.putOpt("name", scene.getName());
scenesJson.putOpt("active", true);
JSONArray lightsArray = new JSONArray();
for (String lightID: scene.getLights()) {
lightsArray.put(lightID);
}
scenesJson.put("lights", lightsArray);
scenesResponseJson.putOpt(identifier, scenesJson);
}
responseBody.write(scenesResponseJson.toString().getBytes());
responseBody.close();
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 4.2 CREATE SCENES SCENE
// http://www.developers.meethue.com/documentation/scenes-api#42_create_scene 4.2. Create Scene
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void createScene_4_2(ObjectMapper mapper, String jSONString, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String sceneIdentifier) throws JsonParseException, IOException {
PHScenesEntry sceneObject = new PHScenesEntry();
String responseBase = "/scenes/";
String resourceUrl="";
String errorDescription="";
String name="scene";
JSONArray responseArray = new JSONArray();
JSONObject jObject = new JSONObject(jSONString);
if (jObject != null) {
JSONArray names = jObject.names();
boolean isSuccess=true; // Success is returned for a valid fieldname, if a field name is invalid then an "error" is returned.
JSONObject successObject = new JSONObject();
List<PHLight> lightsList = new ArrayList<PHLight>(); // A list of all light objects that are part of the scene.
responseArray.put(successObject);
for (int i=0; i<names.length(); i++) {
name = names.getString(i);
resourceUrl = responseBase + name;
if (name.equals("name")) {
String sceneName = jObject.optString(name);
if (sceneName == null || sceneName.length() > 16) {
errorDescription = "invalid value, " + sceneName + ", for parameter, name";
isSuccess=false;
}
else {
sceneObject.setName(sceneName);
}
}
else if (name.equals("lights")) {
JSONArray lightsArray = jObject.optJSONArray("lights");
List<String> lightIdentifiers = new ArrayList<String>();
for (int a=0; a< lightsArray.length(); a++) {
lightIdentifiers.add(lightsArray.get(a).toString());
}
lightsList.addAll(cloneLightObjectsFromLightIds(bridgeConfiguration, lightIdentifiers));
sceneObject.setLights(lightIdentifiers);
}
if (!isSuccess) { // Handle errors, i.e. Non Supported fields
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", 7);
errorLine.putOpt("address", resourceUrl);
errorLine.putOpt("description", errorDescription);
successObject.putOpt("error", errorLine);
break;
}
} // For Names
if (isSuccess) {
JSONObject idObject = new JSONObject();
idObject.put("id", responseBase + sceneIdentifier);
successObject.putOpt("success", idObject);
emulatorScenes.put(sceneIdentifier,lightsList);
bridgeConfiguration.getScenes().put(sceneIdentifier, sceneObject);
}
} // JObject !=null
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
controller.addTextToConsole(responseArray.toString(), Color.WHITE, controller.showResponseJson());
}
// Returns a list of PHLight objects from a list of Strings (Light Identifiers).
public List<PHLight> cloneLightObjectsFromLightIds(PHBridgeConfiguration bridgeConfiguration, List <String>lightIdentifiers) {
List <PHLight> phLightList = new ArrayList<PHLight>();
for (String sceneLightIdentifier: lightIdentifiers) {
PHLight light = bridgeConfiguration.getLights().get(sceneLightIdentifier);
// Clone both the Light State object (which is saved per scene) and light, otherwise they can get modified by other lightUpdate calls.
PHLightState savedState = new PHLightState(light.getState());
PHLight savedLight= new PHLight(light);
savedLight.setIdentifier(sceneLightIdentifier);
savedLight.setState(savedState);
phLightList.add(savedLight);
}
return phLightList;
}
}
================================================
FILE: src/com/hueemulator/server/handlers/SchedulesAPI.java
================================================
package com.hueemulator.server.handlers;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.TimerTask;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.JSONArray;
import org.json.JSONObject;
import com.hueemulator.emulator.Controller;
import com.hueemulator.emulator.PHScheduleTimer;
import com.hueemulator.emulator.PHScheduleTimerManager;
import com.hueemulator.model.PHBody;
import com.hueemulator.model.PHBridgeConfiguration;
import com.hueemulator.model.PHCommand;
import com.hueemulator.model.PHSchedulesEntry;
import com.hueemulator.utils.Utils;
public class SchedulesAPI {
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 3.1 GET ALL SCHEDULESCREATE SCHEDULE
// http://developers.meethue.com/3_schedulesapi.html 3.1. Get All Schedules
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void getAllSchedules_3_1(PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller) throws JsonParseException, IOException {
Map <String, PHSchedulesEntry> lightsMap = bridgeConfiguration.getSchedules();
Iterator it = lightsMap.entrySet().iterator();
JSONObject lightsJson = new JSONObject();
while (it.hasNext()) {
Map.Entry <String, PHSchedulesEntry> entry = (Map.Entry) it.next();
String identifier = (String)entry.getKey();
PHSchedulesEntry schedule = (PHSchedulesEntry) entry.getValue();
JSONObject lightJson = new JSONObject();
lightJson.putOpt("name", schedule.getName());
lightJson.putOpt("description", schedule.getDescription());
lightJson.putOpt("time", schedule.getTime());
JSONObject commandObject = new JSONObject();
commandObject.putOpt("address", schedule.getCommand().getAddress());
JSONObject commandBody = new JSONObject();
PHBody body = schedule.getCommand().getBody();
if (body.getOn() !=null) commandBody.put("on", body.getOn());
if (body.getBri() !=null) commandBody.put("bri", body.getBri());
if (body.getXy() !=null) commandBody.put("xy", body.getXy());
if (body.getScene() !=null) commandBody.put("scene", body.getScene());
commandObject.putOpt("body", commandBody);
commandObject.putOpt("method", schedule.getCommand().getMethod());
lightJson.putOpt("command", commandObject);
lightsJson.putOpt(identifier, lightJson);
}
responseBody.write(lightsJson.toString().getBytes());
responseBody.close();
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 3.2 CREATE SCHEDULE
// http://developers.meethue.com/3_schedulesapi.html 3.2. Create Schedule
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void createSchedule_3_2(ObjectMapper mapper, String jSONString, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller) throws JsonParseException, IOException {
PHSchedulesEntry scheduleObject = new PHSchedulesEntry();
String responseBase = "/schedules/";
String resourceUrl="";
String errorDescription="";
String name="schedule";
JSONArray responseArray = new JSONArray();
String nextScheduleNumber = Integer.toString(bridgeConfiguration.getSchedules().size() + 1);
JSONObject jObject = new JSONObject(jSONString);
if (jObject != null) {
JSONArray names = jObject.names();
boolean isSuccess=true; // Success is returned for a valid fieldname, if a field name is invalid then an "error" is returned.
JSONObject successObject = new JSONObject();
responseArray.put(successObject);
JSONObject commandObject=null; // This JSON (String) will be stored in the ScheduleTimer object, so will be sent to the Emulator when the Schedule Time occurs.
for (int i=0; i<names.length(); i++) {
name = names.getString(i);
resourceUrl = responseBase + name;
if (name.equals("name")) {
String scheduleName = jObject.optString(name);
if (scheduleName == null || scheduleName.length() > 32) {
errorDescription = "invalid value, " + scheduleName + ", for parameter, name";
isSuccess=false;
}
else {
scheduleObject.setName(scheduleName);
}
}
else if (name.equals("description")) {
String scheduleDescription = jObject.optString(name);
if (scheduleDescription == null || scheduleDescription.length() > 32) {
errorDescription = "invalid value, " + scheduleDescription + ", for parameter, description";
isSuccess=false;
}
else {
scheduleObject.setDescription(scheduleDescription);
}
}
else if (name.equals("time")) {
String scheduleTime = jObject.optString(name);
// If date is not correctly formatted or in the past an error is returned.
if (!Utils.isDateValid(scheduleTime)) {
isSuccess=false;
errorDescription = "invalid value, " + scheduleTime + ", for parameter, time";
}
scheduleObject.setTime(scheduleTime);
}
else if (name.equals("command")) {
commandObject = jObject.optJSONObject("command");
PHCommand command = new PHCommand();
command.setAddress(commandObject.optString("address"));
command.setMethod(commandObject.optString("method"));
JSONObject bodyObject = commandObject.optJSONObject("body");
PHBody body = new PHBody();
body.setBri(bodyObject.optInt("bri"));
body.setOn(bodyObject.optBoolean("on"));
body.setTransitiontime(bodyObject.optInt("transitiontime"));
command.setBody(body);
scheduleObject.setCommand(command);
}
if (!isSuccess) { // Handle errors, i.e. Non Supported fields
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", 7);
errorLine.putOpt("address", resourceUrl);
errorLine.putOpt("description", errorDescription);
successObject.putOpt("error", errorLine);
break;
}
} // For Names
if (isSuccess) {
JSONObject idObject = new JSONObject();
idObject.put("id", nextScheduleNumber);
successObject.putOpt("success", idObject);
bridgeConfiguration.getSchedules().put(nextScheduleNumber, scheduleObject);
Date scheduleDate = Utils.stringToDate(scheduleObject.getTime());
// Create The Schedule.
PHScheduleTimer scheduleTimer = new PHScheduleTimer();
scheduleTimer.setScheduleIdentifier(nextScheduleNumber);
scheduleTimer.schedule(new ScheduleTask(nextScheduleNumber, commandObject, controller.getIpAddress(), bridgeConfiguration) , scheduleDate);
scheduleTimer.setCommandJSON(commandObject);
PHScheduleTimerManager timerManager = PHScheduleTimerManager.getInstance();
timerManager.storeSchedule(nextScheduleNumber, scheduleTimer);
}
} // JObject !=null
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
controller.addTextToConsole(responseArray.toString(), Color.WHITE, controller.showResponseJson());
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 3.3 GET SCHEDULE ATTRIBUTES
// http://developers.meethue.com/3_schedulesapi.html 3.3. Get schedule attributes
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void getScheduleAttributes_3_3(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String scheduleIdentifier) throws JsonParseException, IOException {
if (bridgeConfiguration.getSchedules() == null || bridgeConfiguration.getSchedules().get(scheduleIdentifier) == null) {
sendErrorResponse(scheduleIdentifier, "3", responseBody);
}
else {
mapper.writeValue(responseBody, bridgeConfiguration.getSchedules().get(scheduleIdentifier)); // Write to the response.
controller.addTextToConsole(mapper.writeValueAsString(bridgeConfiguration.getSchedules().get(scheduleIdentifier)), Color.WHITE, controller.showResponseJson());
}
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 3.4 SET SCHEDULE ATTRIBUTES
// http://developers.meethue.com/3_schedulesapi.html 3.4. Set schedule attributes
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void setScheduleAttributes_3_4(ObjectMapper mapper, String jSONString, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String scheduleIdentifier) throws JsonParseException, IOException {
if (bridgeConfiguration.getSchedules() == null || bridgeConfiguration.getSchedules().get(scheduleIdentifier) == null) {
sendErrorResponse(scheduleIdentifier, "3", responseBody);
}
PHSchedulesEntry scheduleObject = bridgeConfiguration.getSchedules().get(scheduleIdentifier);
String responseBase = "/schedules/" + scheduleIdentifier + "/";
String resourceUrl="";
JSONArray responseArray = new JSONArray();
JSONObject jObject = new JSONObject(jSONString);
if (jObject != null) {
JSONArray names = jObject.names();
for (int i=0; i<names.length(); i++) {
JSONObject successObject = new JSONObject();
boolean isSuccess=true; // Success is returned for a valid fieldname, if a field name is invalid then an "error" is returned.
responseArray.put(successObject);
JSONObject successLine = new JSONObject();
String name = names.getString(i);
resourceUrl = responseBase + name;
if (name.equals("name")) {
String lightName = jObject.optString(name);
if (lightName == null || lightName.length() > 32) {
isSuccess=false;
}
else {
successLine.putOpt(resourceUrl, lightName);
scheduleObject.setName(lightName);
}
}
else if (name.equals("description")) {
String lightDescription = jObject.optString(name);
successLine.putOpt(resourceUrl, jObject.optString(name));
scheduleObject.setDescription(lightDescription);
}
else if (name.equals("time")) {
String time = jObject.optString(name);
successLine.putOpt(resourceUrl, jObject.optString(time));
scheduleObject.setTime(time);
}
// TODO Command. Do the below.
else if (name.equals("command")) {
JSONObject commandObject = jObject.optJSONObject("command");
if (commandObject != null) {
JSONArray commandNames = commandObject.names();
PHCommand command = bridgeConfiguration.getSchedules().get(scheduleIdentifier).getCommand();
for (int c=0; c< commandNames.length(); c++) {
String cName = commandNames.getString(c);
if (cName.equals("address")) {
command.setAddress(commandObject.optString("address"));
}
else if (cName.equals("body")) {
JSONObject bodyObject = commandObject.optJSONObject("body");
PHBody body =command.getBody();
JSONArray bodyNames = bodyObject.names();
// TODO Validate these values (e.g. If bri is out of range or not).
for (int b=0; b < bodyNames.length(); b++) {
String bName = bodyNames.getString(b);
if (bName.equals("bri")) {
body.setBri(bodyObject.optInt("bri"));
}
else if (bName.equals("on")) {
body.setOn(bodyObject.optBoolean("on"));
}
else if (bName.equals("transitiontime")) {
body.setTransitiontime(bodyObject.optInt("transitiontime"));
}
} // End of body Names loop
command.setBody(body);
}
} // End of Command Names
bridgeConfiguration.getSchedules().get(scheduleIdentifier).setCommand(command);
} // Command Object != null
}
if (!isSuccess) { // Handle errors, i.e. Non Supported fields
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", 7);
errorLine.putOpt("address", resourceUrl);
errorLine.putOpt("description", "invalid value, " + Utils.chopName(jObject.optString(name)) + ", for parameter, name");
successObject.putOpt("error", errorLine);
}
if (isSuccess) {
successObject.putOpt("success", successLine);
}
}
}
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
bridgeConfiguration.getSchedules().put(scheduleIdentifier, scheduleObject);
controller.addTextToConsole(responseArray.toString(), Color.WHITE, controller.showResponseJson());
}
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
// 3.5 DELETE SCHEDULE
// http://developers.meethue.com/3_schedulesapi.html 3.5. Delete schedule
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
public void deleteSchedule_3_5(ObjectMapper mapper, PHBridgeConfiguration bridgeConfiguration, OutputStream responseBody, Controller controller, String scheduleIdentifier) throws JsonParseException, IOException {
if (bridgeConfiguration.getSchedules() == null || bridgeConfiguration.getSchedules().get(scheduleIdentifier) == null) {
sendErrorResponse(scheduleIdentifier, "3", responseBody);
}
else {
bridgeConfiguration.getSchedules().remove(scheduleIdentifier);
String resourceURL = "/schedules/" + scheduleIdentifier + " deleted";
JSONObject responseObject = new JSONObject();
responseObject.putOpt("success", resourceURL);
responseBody.write(responseObject.toString().getBytes());
responseBody.close();
// mapper.writeValue(responseBody, bridgeConfiguration.getSchedules().get(scheduleIdentifier)); // Write to the response.
controller.addTextToConsole(mapper.writeValueAsString(bridgeConfiguration.getSchedules().get(scheduleIdentifier)), Color.WHITE, controller.showResponseJson());
}
}
public void sendErrorResponse(String lightIdentifier, String type, OutputStream responseBody) throws IOException {
JSONArray responseArray = new JSONArray();
JSONObject errorObject = new JSONObject();
JSONObject errorLine = new JSONObject();
errorLine.putOpt("type", type);
errorLine.putOpt("address", "/schedules/" + lightIdentifier);
errorLine.putOpt("description", "resource, /schedules/" + lightIdentifier + ", not available");
errorObject.putOpt("error", errorLine);
responseArray.put(errorObject);
responseBody.write(responseArray.toString().getBytes());
responseBody.close();
}
/*
* ScheduleTask is called back when a Schedule time has occurred.
* This sends the HTTP call back to the Emulator Server and executes it!!
*/
class ScheduleTask extends TimerTask {
private String scheduleIdentifier;
private JSONObject commandObject; // The JSON to execute when the Schedule occurs.
private String ipAddress;
private PHBridgeConfiguration bridgeConfiguration;
public ScheduleTask(String scheduleIdentifier, JSONObject commandObject, String ipAddress, PHBridgeConfiguration bridgeConfiguration) {
this.scheduleIdentifier = scheduleIdentifier;
this.commandObject = commandObject;
this.ipAddress = ipAddress;
this.bridgeConfiguration = bridgeConfiguration;
}
public void run() {
System.out.format("Time's up! Identifier: " + scheduleIdentifier + " Command JSON: " + commandObject.toString());
JSONObject jsonBody = commandObject.optJSONObject("body");
String address = commandObject.optString("address");
String method = commandObject.optString("method");
if (ipAddress == null) { // Nasty fudge for the Integration testing. When a schedule's time is up, it makes a http call with the command/action. This fudge will ensure it sends the command back to the test emulator.
ipAddress = "localhost:8888";
}
try {
Utils.doHttpCall(ipAddress, method, address, jsonBody);
} catch (IOException e) {
System.out.println("Unable to make HTTP Call for schedule. " + e.getMessage());
}
bridgeConfiguration.getSchedules().remove(scheduleIdentifier);
this.cancel(); //Terminate the timer thread
}
}
}
================================================
FILE: src/com/hueemulator/utils/HueColor.java
================================================
package com.hueemulator.utils;
import java.util.HashMap;
import java.util.Locale;
/**
* The Color class defines methods for creating and converting color ints.
* Colors are represented as packed ints, made up of 4 bytes: alpha, red,
* green, blue. The values are unpremultiplied, meaning any transparency is
* stored solely in the alpha component, and not in the color components. The
* components are stored as follows (alpha << 24) | (red << 16) |
* (green << 8) | blue. Each component ranges between 0..255 with 0
* meaning no contribution for that component, and 255 meaning 100%
* contribution. Thus opaque-black would be 0xFF000000 (100% opaque but
* no contributions from red, green, or blue), and opaque-white would be
* 0xFFFFFFFF
*/
public class HueColor {
public static final int BLACK = 0xFF000000;
public static final int DKGRAY = 0xFF444444;
public static final int GRAY = 0xFF888888;
public static final int LTGRAY = 0xFFCCCCCC;
public static final int WHITE = 0xFFFFFFFF;
public static final int RED = 0xFFFF0000;
public static final int GREEN = 0xFF00FF00;
public static final int BLUE = 0xFF0000FF;
public static final int YELLOW = 0xFFFFFF00;
public static final int CYAN = 0xFF00FFFF;
public static final int MAGENTA = 0xFFFF00FF;
public static final int TRANSPARENT = 0;
/**
* Return the alpha component of a color int. This is the same as saying
* color >>> 24
*/
public static int alpha(int color) {
return color >>> 24;
}
/**
* Return the red component of a color int. This is the same as saying
* (color >> 16) & 0xFF
*/
public static int red(int color) {
return (color >> 16) & 0xFF;
}
/**
* Return the green component of a color int. This is the same as saying
* (color >> 8) & 0xFF
*/
public static int green(int color) {
return (color >> 8) & 0xFF;
}
/**
* Return the blue component of a color int. This is the same as saying
* color & 0xFF
*/
public static int blue(int color) {
return color & 0xFF;
}
/**
* Return a color-int from red, green, blue components.
* The alpha component is implicity 255 (fully opaque).
* These component values should be [0..255], but there is no
* range check performed, so if they are out of range, the
* returned color is undefined.
* @param red Red component [0..255] of the color
* @param green Green component [0..255] of the color
* @param blue Blue component [0..255] of the color
*/
public static int rgb(int red, int green, int blue) {
return (0xFF << 24) | (red << 16) | (green << 8) | blue;
}
/**
* Return a color-int from alpha, red, green, blue components.
* These component values should be [0..255], but there is no
* range check performed, so if they are out of range, the
* returned color is undefined.
* @param alpha Alpha component [0..255] of the color
* @param red Red component [0..255] of the color
* @param green Green component [0..255] of the color
* @param blue Blue component [0..255] of the color
*/
public static int argb(int alpha, int red, int green, int blue) {
return (alpha << 24) | (red << 16) | (green << 8) | blue;
}
/**
* Returns the hue component of a color int.
*
* @return A value between 0.0f and 1.0f
*
* @hide Pending API council
*/
public static float hue(int color) {
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = color & 0xFF;
int v = Math.max(b, Math.max(r, g));
int temp = Math.min(b, Math.min(r, g));
float h;
if (v == temp) {
h = 0;
} else {
final float vtemp = (float) (v - temp);
final float cr = (v - r) / vtemp;
final float cg = (v - g) / vtemp;
final float cb = (v - b) / vtemp;
if (r == v) {
h = cb - cg;
} else if (g == v) {
h = 2 + cr - cb;
} else {
h = 4 + cg - cr;
}
h /= 6.f;
if (h < 0) {
h++;
}
}
return h;
}
/**
* Returns the saturation component of a color int.
*
* @return A value between 0.0f and 1.0f
*
* @hide Pending API council
*/
public static float saturation(int color) {
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = color & 0xFF;
int v = Math.max(b, Math.max(r, g));
int temp = Math.min(b, Math.min(r, g));
float s;
if (v == temp) {
s = 0;
} else {
s = (v - temp) / (float) v;
}
return s;
}
/**
* Returns the brightness component of a color int.
*
* @return A value between 0.0f and 1.0f
*
* @hide Pending API council
*/
public static float brightness(int color) {
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = color & 0xFF;
int v = Math.max(b, Math.max(r, g));
return (v / 255.f);
}
/**
* Parse the color string, and return the corresponding color-int.
* If the string cannot be parsed, throws an IllegalArgumentException
* exception. Supported formats are:
* #RRGGBB
* #AARRGGBB
* 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta',
* 'yellow', 'lightgray', 'darkgray', 'grey', 'lightgrey', 'darkgrey',
* 'aqua', 'fuschia', 'lime', 'maroon', 'navy', 'olive', 'purple',
* 'silver', 'teal'
*/
public static int parseColor(String colorString) {
if (colorString.charAt(0) == '#') {
// Use a long to avoid rollovers on #ffXXXXXX
long color = Long.parseLong(colorString.substring(1), 16);
if (colorString.length() == 7) {
// Set the alpha value
color |= 0x00000000ff000000;
} else if (colorString.length() != 9) {
throw new IllegalArgumentException("Unknown color");
}
return (int)color;
} else {
Integer color = S_COLOR_NAME_MAP.get(colorString.toLowerCase(Locale.US));
if (color != null) {
return color;
}
}
throw new IllegalArgumentException("Unknown color");
}
private static final HashMap<String, Integer> S_COLOR_NAME_MAP;
static {
S_COLOR_NAME_MAP = new HashMap<String, Integer>();
S_COLOR_NAME_MAP.put("black", BLACK);
S_COLOR_NAME_MAP.put("darkgray", DKGRAY);
S_COLOR_NAME_MAP.put("gray", GRAY);
S_COLOR_NAME_MAP.put("lightgray", LTGRAY);
S_COLOR_NAME_MAP.put("white", WHITE);
S_COLOR_NAME_MAP.put("red", RED);
S_COLOR_NAME_MAP.put("green", GREEN);
S_COLOR_NAME_MAP.put("blue", BLUE);
S_COLOR_NAME_MAP.put("yellow", YELLOW);
S_COLOR_NAME_MAP.put("cyan", CYAN);
S_COLOR_NAME_MAP.put("magenta", MAGENTA);
S_COLOR_NAME_MAP.put("aqua", 0x00FFFF);
S_COLOR_NAME_MAP.put("fuchsia", 0xFF00FF);
S_COLOR_NAME_MAP.put("darkgrey", DKGRAY);
S_COLOR_NAME_MAP.put("grey", GRAY);
S_COLOR_NAME_MAP.put("lightgrey", LTGRAY);
S_COLOR_NAME_MAP.put("lime", 0x00FF00);
S_COLOR_NAME_MAP.put("maroon", 0x800000);
S_COLOR_NAME_MAP.put("navy", 0x000080);
S_COLOR_NAME_MAP.put("olive", 0x808000);
S_COLOR_NAME_MAP.put("purple", 0x800080);
S_COLOR_NAME_MAP.put("silver", 0xC0C0C0);
S_COLOR_NAME_MAP.put("teal", 0x008080);
}
}
================================================
FILE: src/com/hueemulator/utils/OpenFileFilter.java
================================================
package com.hueemulator.utils;
/**
* This class defines which file types are displayed (by default) by the JFileChooser and what file
* types appear in the drop down menu in the file dialog.
* You could add more than one file type to the open file dialog by creating multiple instances of this
* class and then repeatedly calling addFileFilter.
* @author LaSpina
*/
import java.io.File;
import javax.swing.filechooser.*;
public class OpenFileFilter extends FileFilter {
String description = "";
String fileExt = "";
public OpenFileFilter(String extension) {
fileExt = extension;
}
public OpenFileFilter(String extension, String typeDescription) {
fileExt = extension;
this.description = typeDescription;
}
@Override
public boolean accept(File f) {
if (f.isDirectory())
return true;
return (f.getName().toLowerCase().endsWith(fileExt));
}
@Override
public String getDescription() {
return description;
}
}
================================================
FILE: src/com/hueemulator/utils/PHUtilitiesHelper.java
================================================
package com.hueemulator.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class PHUtilitiesHelper {
private static final int CPT_RED = 0;
private static final int CPT_GREEN = 1;
private static final int CPT_BLUE = 2;
/**
* Generates the color for the given XY values and light model Id. Note:
* When the exact values cannot be represented, it will return the closest
* match.
*
* @param points
* the float array contain x and the y value.
* @param model
* the model of the lamp, example: "LCT001" for hue bulb. Used to
* calculate the color gamut. If this value is empty the default
* gamut values are used.
* @return int the Android Color value. If xy is null OR xy is not an array
* of size 2, Color.BLACK will be returned
* @throws NullPointerException
* If either points or model is null
*/
public static int colorFromXY(float[] points, String model) {
PointF xy = new PointF(points[0], points[1]);
xy = fixIfOutOfRange(xy, model);
float x = xy.x;
float y = xy.y;
float z = 1.0f - x - y;
float y2 = 1.0f;
float x2 = (y2 / y) * x;
float z2 = (y2 / y) * z;
// sRGB D65 conversion
float r = x2 * 3.2406f - y2 * 1.5372f - z2 * 0.4986f;
float g = -x2 * 0.9689f + y2 * 1.8758f + z2 * 0.0415f;
float b = x2 * 0.0557f - y2 * 0.2040f + z2 * 1.0570f;
if (r > b && r > g && r > 1.0f) {
// red is too big
g = g / r;
b = b / r;
r = 1.0f;
} else if (g > b && g > r && g > 1.0f) {
// green is too big
r = r / g;
b = b / g;
g = 1.0f;
} else if (b > r && b > g && b > 1.0f) {
// blue is too big
r = r / b;
g = g / b;
b = 1.0f;
}
// Apply gamma correction
r = r <= 0.0031308f ? 12.92f * r : (1.0f + 0.055f)
* (float) Math.pow(r, (1.0f / 2.4f)) - 0.055f;
g = g <= 0.0031308f ? 12.92f * g : (1.0f + 0.055f)
* (float) Math.pow(g, (1.0f / 2.4f)) - 0.055f;
b = b <= 0.0031308f ? 12.92f * b : (1.0f + 0.055f)
* (float) Math.pow(b, (1.0f / 2.4f)) - 0.055f;
if (r > b && r > g) {
// red is biggest
if (r > 1.0f) {
g = g / r;
b = b / r;
r = 1.0f;
}
} else if (g > b && g > r) {
// green is biggest
if (g > 1.0f) {
r = r / g;
b = b / g;
g = 1.0f;
}
} else if (b > r && b > g && b > 1.0f) {
r = r / b;
g = g / b;
b = 1.0f;
}
// neglecting if the value is negative.
if (r < 0.0f) {
r = 0.0f;
}
if (g < 0.0f) {
g = 0.0f;
}
if (b < 0.0f) {
b = 0.0f;
}
// Converting float components to int components.
int r1 = (int) (r * 255.0f);
int g1 = (int) (g * 255.0f);
int b1 = (int) (b * 255.0f);
return HueColor.rgb(r1, g1, b1);
}
public static PointF fixIfOutOfRange(PointF xy, String model) {
List<PointF> colorPoints = colorPointsForModel(model);
boolean inReachOfLamps = checkPointInLampsReach(xy, colorPoints);
if (!inReachOfLamps) {
// It seems the colour is out of reach
// let's find the closest colour we can produce with our lamp and
// send this XY value out.
// Find the closest point on each line in the triangle.
PointF pAB = getClosestPointToPoints(colorPoints.get(CPT_RED),
colorPoints.get(CPT_GREEN), xy);
PointF pAC = getClosestPointToPoints(colorPoints.get(CPT_BLUE),
colorPoints.get(CPT_RED), xy);
PointF pBC = getClosestPointToPoints(colorPoints.get(CPT_GREEN),
colorPoints.get(CPT_BLUE), xy);
// Get the distances per point and see which point is closer to our point.
float dAB = getDistanceBetweenTwoPoints(xy, pAB);
float dAC = getDistanceBetweenTwoPoints(xy, pAC);
float dBC = getDistanceBetweenTwoPoints(xy, pBC);
float lowest = dAB;
PointF closestPoint = pAB;
if (dAC < lowest) {
lowest = dAC;
closestPoint = pAC;
}
if (dBC < lowest) {
lowest = dBC;
closestPoint = pBC;
}
// Change the xy value to a value which is within the reach of the lamp.
xy.x = closestPoint.x;
xy.y = closestPoint.y;
}
return new PointF(xy.x, xy.y);
}
/**
* Return x, y value from RGB
*
* @param red the amount of red.
* @param blue the amount of blue.
* @param green the amount of green.
* @param model
* the model Id of Light
* @return float[] the float array of length 2, where index 0, 1 gives
* respective x, y values.
*/
public float[] calculateXYFromRGB(int red, int green, int blue, String model) {
int rgb = HueColor.rgb(red, green, blue);
return calculateXY(rgb, model);
}
/**
* Return x, y value from android color & light model Id.
*
* @param color
* the color value
* @param model
* the model Id of Light
* @return float[] the float array of length 2, where index 0, 1 gives
* respective x, y values.
*/
public float[] calculateXY(int color, String model) {
// Default to white
float red = 1.0f;
float green = 1.0f;
float blue = 1.0f;
// Get no. of components
red = HueColor.red(color) / 255.0f;
green = HueColor.green(color) / 255.0f;
blue = HueColor.blue(color) / 255.0f;
// Wide gamut conversion D65
float r = ((red > 0.04045f) ? (float) Math.pow((red + 0.055f)
/ (1.0f + 0.055f), 2.4f) : (red / 12.92f));
float g = (green > 0.04045f) ? (float) Math.pow((green + 0.055f)
/ (1.0f + 0.055f), 2.4f) : (green / 12.92f);
float b = (blue > 0.04045f) ? (float) Math.pow((blue + 0.055f)
/ (1.0f + 0.055f), 2.4f) : (blue / 12.92f);
// Why values are different in ios and android , IOS is considered
// Modified conversion from RGB -> XYZ with better results on colors for
// the lights
float x = r * 0.649926f + g * 0.103455f + b * 0.197109f;
float y = r * 0.234327f + g * 0.743075f + b * 0.022598f;
float z = r * 0.0000000f + g * 0.053077f + b * 1.035763f;
float xy[] = new float[2];
xy[0] = (x / (x + y + z));
xy[1] = (y / (x + y + z));
if (Float.isNaN(xy[0])) {
xy[0] = 0.0f;
}
if (Float.isNaN(xy[1])) {
xy[1] = 0.0f;
}
// Check if the given XY value is within the colourreach of our lamps.
PointF xyPoint = new PointF(xy[0], xy[1]);
List<PointF> colorPoints = colorPointsForModel(model);
boolean inReachOfLamps = checkPointInLampsReach(xyPoint, colorPoints);
if (!inReachOfLamps) {
// It seems the colour is out of reach
// let's find the closes colour we can produce with our lamp and
// send this XY value out.
// Find the closest point on each line in the triangle.
PointF pAB = getClosestPointToPoints(colorPoints.get(CPT_RED), colorPoints.get(CPT_GREEN), xyPoint);
PointF pAC = getClosestPointToPoints(colorPoints.get(CPT_BLUE), colorPoints.get(CPT_RED), xyPoint);
PointF pBC = getClosestPointToPoints(colorPoints.get(CPT_GREEN), colorPoints.get(CPT_BLUE), xyPoint);
// Get the distances per point and see which point is closer to our
// Point.
float dAB = getDistanceBetweenTwoPoints(xyPoint, pAB);
float dAC = getDistanceBe
gitextract_j346hbtz/
├── .classpath
├── .gitignore
├── .project
├── CHANGELOG.md
├── HueEmulator-v0.1.jar
├── HueEmulator-v0.2.jar
├── HueEmulator-v0.3.jar
├── HueEmulator-v0.4.jar
├── HueEmulator-v0.5.jar
├── HueEmulator-v0.6.jar
├── HueEmulator-v0.7.jar
├── HueEmulator-v0.8.jar
├── README.md
├── libs/
│ ├── jackson-core-asl-1.9.12.jar
│ ├── jackson-mapper-asl-1.9.12.jar
│ └── junit-4.11.jar
├── resources/
│ ├── config-3bulbs.json
│ └── description.xml
├── src/
│ ├── com/
│ │ └── hueemulator/
│ │ ├── emulator/
│ │ │ ├── Constants.java
│ │ │ ├── Controller.java
│ │ │ ├── Emulator.java
│ │ │ ├── HueEmulator.java
│ │ │ ├── Model.java
│ │ │ ├── PHScheduleTimer.java
│ │ │ └── PHScheduleTimerManager.java
│ │ ├── gui/
│ │ │ ├── About.java
│ │ │ ├── GraphicsPanel.java
│ │ │ ├── Help.java
│ │ │ ├── HueMenuBar.java
│ │ │ ├── LightsFrame.java
│ │ │ ├── PropertiesFrame.java
│ │ │ └── View.java
│ │ ├── model/
│ │ │ ├── PHBody.java
│ │ │ ├── PHBridgeConfiguration.java
│ │ │ ├── PHCommand.java
│ │ │ ├── PHConfig.java
│ │ │ ├── PHGroupsEntry.java
│ │ │ ├── PHLight.java
│ │ │ ├── PHLightState.java
│ │ │ ├── PHScenesEntry.java
│ │ │ ├── PHSchedulesEntry.java
│ │ │ ├── PHSwupdate.java
│ │ │ └── PHWhitelistEntry.java
│ │ ├── server/
│ │ │ ├── MyApiHandler.java
│ │ │ ├── MyRootHandler.java
│ │ │ ├── Server.java
│ │ │ ├── UPNPServer.java
│ │ │ └── handlers/
│ │ │ ├── ConfigurationAPI.java
│ │ │ ├── GroupsAPI.java
│ │ │ ├── LightsAPI.java
│ │ │ ├── ScenesAPI.java
│ │ │ └── SchedulesAPI.java
│ │ └── utils/
│ │ ├── HueColor.java
│ │ ├── OpenFileFilter.java
│ │ ├── PHUtilitiesHelper.java
│ │ ├── PointF.java
│ │ └── Utils.java
│ └── org/
│ └── json/
│ ├── JSONArray.java
│ ├── JSONException.java
│ ├── JSONObject.java
│ ├── JSONString.java
│ └── JSONTokener.java
└── tests/
└── com/
└── hueemulator/
├── emulator/
│ ├── HttpTester.java
│ └── TestEmulator.java
├── lighting/
│ └── utils/
│ └── TestUtils.java
└── server/
└── handlers/
├── TestConfigurationAPI.java
├── TestGroupsAPI.java
├── TestLightsAPI.java
└── TestSchedulesAPI.java
SYMBOL INDEX (582 symbols across 51 files)
FILE: src/com/hueemulator/emulator/Constants.java
class Constants (line 3) | public class Constants {
FILE: src/com/hueemulator/emulator/Controller.java
class Controller (line 41) | public class Controller {
method Controller (line 57) | public Controller(Model model, View view, String fileName){
method addPropertiesListeners (line 71) | public void addPropertiesListeners() {
method addMenuListeners (line 80) | public void addMenuListeners(){
method Controller (line 204) | public Controller() {
method addTextToConsole (line 209) | public void addTextToConsole(String text, Color textColour, boolean ap...
method repaintBulbs (line 230) | public void repaintBulbs() {
method setIPAddress (line 249) | public void setIPAddress() throws UnknownHostException {
method getPort (line 259) | public String getPort() {
method getModel (line 263) | public Model getModel() {
method setModel (line 267) | public void setModel(Model model) {
method paintGraphicsPanel (line 271) | public void paintGraphicsPanel() {
method addNewBulb (line 275) | public void addNewBulb(boolean isLux) {
method getDefaultPointSymbols (line 333) | public static Map<String, String> getDefaultPointSymbols() {
method getIpAddress (line 346) | public String getIpAddress() {
method clearConsole (line 350) | public void clearConsole() {
method append (line 357) | public void append(final String dateString, final String s, final Colo...
method isHasBridgeBeenPushLinked (line 389) | public boolean isHasBridgeBeenPushLinked() {
method setHasBridgeBeenPushLinked (line 393) | public void setHasBridgeBeenPushLinked(boolean hasBridgeBeenPushLinked) {
method showRequestJson (line 397) | public boolean showRequestJson() {
method setShowRequestJson (line 401) | public void setShowRequestJson(boolean showRequestJSON) {
method showResponseJson (line 405) | public boolean showResponseJson() {
method setShowResponseJson (line 409) | public void setShowResponseJson(boolean showResponseJSON) {
method setShowFullConfigJson (line 413) | public void setShowFullConfigJson(boolean showFullConfigJSON) {
FILE: src/com/hueemulator/emulator/Emulator.java
class Emulator (line 22) | public class Emulator {
method Emulator (line 28) | public Emulator(Controller controller, String fileName) {
method startServers (line 39) | public void startServers() {
method stopServer (line 62) | public void stopServer() {
method loadConfiguration (line 73) | public boolean loadConfiguration(String fileName) {
method getServer (line 96) | public Server getServer() {
method setServer (line 100) | public void setServer(Server server) {
FILE: src/com/hueemulator/emulator/HueEmulator.java
class HueEmulator (line 5) | public class HueEmulator{
method main (line 7) | public static void main(String args[]) {
method HueEmulator (line 11) | public HueEmulator(String fileName) {
FILE: src/com/hueemulator/emulator/Model.java
class Model (line 6) | public class Model {
method Model (line 15) | public Model(){
method isShowConsoleTime (line 19) | public boolean isShowConsoleTime() {
method isShowFullConfig (line 23) | public boolean isShowFullConfig() {
method setShowConsoleTime (line 27) | public void setShowConsoleTime(boolean showConsoleTime) {
method getBridgeConfiguration (line 31) | public PHBridgeConfiguration getBridgeConfiguration() {
method setBridgeConfiguration (line 35) | public void setBridgeConfiguration(PHBridgeConfiguration bridgeConfigu...
method isShowRequestJSON (line 39) | public boolean isShowRequestJSON() {
method setShowRequestJSON (line 43) | public void setShowRequestJSON(boolean showRequestJSON) {
method isShowResponseJSON (line 47) | public boolean isShowResponseJSON() {
method setShowResponseJSON (line 51) | public void setShowResponseJSON(boolean showResponseJSON) {
method setShowFullConfigJSON (line 55) | public void setShowFullConfigJSON(boolean showFullConfigJSON) {
FILE: src/com/hueemulator/emulator/PHScheduleTimer.java
class PHScheduleTimer (line 7) | public class PHScheduleTimer extends Timer {
method getScheduleIdentifier (line 12) | public String getScheduleIdentifier() {
method setScheduleIdentifier (line 16) | public void setScheduleIdentifier(String scheduleIdentifier) {
method getCommandJSON (line 20) | public JSONObject getCommandJSON() {
method setCommandJSON (line 24) | public void setCommandJSON(JSONObject commandJSON) {
FILE: src/com/hueemulator/emulator/PHScheduleTimerManager.java
class PHScheduleTimerManager (line 6) | public class PHScheduleTimerManager {
method PHScheduleTimerManager (line 18) | private PHScheduleTimerManager() {
method getInstance (line 22) | public static synchronized PHScheduleTimerManager getInstance(){
method storeSchedule (line 29) | public void storeSchedule(String scheduleIdentifier, PHScheduleTimer s...
method removeSchedule (line 33) | public void removeSchedule(String scheduleIdentifier){
FILE: src/com/hueemulator/gui/About.java
class About (line 9) | public class About extends JFrame{
method About (line 13) | public About() {
FILE: src/com/hueemulator/gui/GraphicsPanel.java
class GraphicsPanel (line 31) | public class GraphicsPanel extends JPanel implements MouseListener {
method GraphicsPanel (line 60) | public GraphicsPanel(String size) {
method setController (line 103) | public void setController(Controller controller) {
method paintComponent (line 107) | public void paintComponent( Graphics g ) {
method showBridgeInfo (line 203) | public void showBridgeInfo(Graphics2D g2, Model model) {
method showBulbInfo (line 232) | public void showBulbInfo(Graphics2D g2, PHLight light, PHLightState st...
method getModel (line 276) | public Model getModel() {
method setModel (line 280) | public void setModel(Model model) {
method mouseClicked (line 287) | @Override
method mouseEntered (line 293) | @Override
method mouseExited (line 299) | @Override
method mousePressed (line 306) | @Override
method mouseReleased (line 357) | @Override
FILE: src/com/hueemulator/gui/Help.java
class Help (line 7) | public class Help extends JFrame{
method Help (line 10) | public Help() {
FILE: src/com/hueemulator/gui/HueMenuBar.java
class HueMenuBar (line 20) | public class HueMenuBar extends JMenuBar {
method HueMenuBar (line 39) | public HueMenuBar() {
method getPort (line 220) | public JTextField getPort() {
method setPort (line 225) | public void setPort(JTextField port) {
method getMenuBar (line 230) | public JMenuBar getMenuBar() {
method setMenuBar (line 235) | public void setMenuBar(JMenuBar menuBar) {
method getFileMenu (line 240) | public JMenu getFileMenu() {
method setFileMenu (line 245) | public void setFileMenu(JMenu fileMenu) {
method getHelpMenu (line 250) | public JMenu getHelpMenu() {
method setHelpMenu (line 255) | public void setHelpMenu(JMenu helpMenu) {
method getMenuItem (line 260) | public JMenuItem getMenuItem() {
method setMenuItem (line 265) | public void setMenuItem(JMenuItem menuItem) {
method getStartButton (line 269) | public JButton getStartButton() {
method setStartButton (line 273) | public void setStartButton(JButton startButton) {
method getStopButton (line 277) | public JButton getStopButton() {
method setStopButton (line 281) | public void setStopButton(JButton stopButton) {
method getClearConsoleMenuItem (line 285) | public JMenuItem getClearConsoleMenuItem() {
method setClearConsoleMenuItem (line 289) | public void setClearConsoleMenuItem(JMenuItem clearConsoleMenuItem) {
method getHelpMenuItem (line 293) | public JMenuItem getHelpMenuItem() {
method setHelpMenuItem (line 297) | public void setHelpMenuItem(JMenuItem helpMenuItem) {
method getAboutMenuItem (line 301) | public JMenuItem getAboutMenuItem() {
method setAboutMenuItem (line 305) | public void setAboutMenuItem(JMenuItem aboutMenuItem) {
method getViewGraphicsMenuItems (line 309) | public JCheckBoxMenuItem getViewGraphicsMenuItems() {
method setViewGraphicsMenuItems (line 313) | public void setViewGraphicsMenuItems(JCheckBoxMenuItem viewGraphicsMen...
method getLoadConfigMenuItem (line 317) | public JMenuItem getLoadConfigMenuItem() {
method setLoadConfigMenuItem (line 321) | public void setLoadConfigMenuItem(JMenuItem loadConfigMenuItem) {
method getSaveConfigMenuItem (line 325) | public JMenuItem getSaveConfigMenuItem() {
method setSaveConfigMenuItem (line 329) | public void setSaveConfigMenuItem(JMenuItem saveConfigMenuItem) {
method setController (line 333) | public void setController(Controller controller) {
method getLargeLightFrame (line 337) | public LightsFrame getLargeLightFrame() {
method setLargeLightFrame (line 341) | public void setLargeLightFrame(LightsFrame lightFrame) {
method getSmallLightFrame (line 345) | public LightsFrame getSmallLightFrame() {
method setSmallLightFrame (line 349) | public void setSmallLightFrame(LightsFrame lightFrame) {
FILE: src/com/hueemulator/gui/LightsFrame.java
class LightsFrame (line 12) | public class LightsFrame extends JFrame {
method LightsFrame (line 19) | public LightsFrame(Controller controller, String size) {
method setModel (line 37) | public void setModel(Model model) {
FILE: src/com/hueemulator/gui/PropertiesFrame.java
class PropertiesFrame (line 12) | public class PropertiesFrame extends JFrame{
method PropertiesFrame (line 17) | public PropertiesFrame() {
method getIncludeTime (line 41) | public JCheckBox getIncludeTime() {
method setIncludeTime (line 45) | public void setIncludeTime(JCheckBox includeTime) {
method getShowJSONResponses (line 49) | public JCheckBox getShowJSONResponses() {
method setShowJSONResponses (line 53) | public void setShowJSONResponses(JCheckBox showJSONResponses) {
FILE: src/com/hueemulator/gui/View.java
class View (line 15) | public class View {
method View (line 26) | public View(){
method getConsole (line 75) | public JEditorPane getConsole() {
method setConsole (line 79) | public void setConsole(JEditorPane console) {
method getMenuBar (line 83) | public HueMenuBar getMenuBar() {
method setMenuBar (line 87) | public void setMenuBar(HueMenuBar menuBar) {
method getGraphicsPanel (line 91) | public GraphicsPanel getGraphicsPanel() {
method setGraphicsPanel (line 95) | public void setGraphicsPanel(GraphicsPanel graphicsPanel) {
method getAbout (line 99) | public About getAbout() {
method setAbout (line 103) | public void setAbout(About about) {
method getHelp (line 107) | public Help getHelp() {
method setHelp (line 111) | public void setHelp(Help help) {
method getPropertiesFrame (line 115) | public PropertiesFrame getPropertiesFrame() {
method setPropertiesFrame (line 119) | public void setPropertiesFrame(PropertiesFrame propertiesFrame) {
method getConsoleScrollPane (line 123) | public JScrollPane getConsoleScrollPane() {
method setConsoleScrollPane (line 127) | public void setConsoleScrollPane(JScrollPane consoleScrollPane) {
FILE: src/com/hueemulator/model/PHBody.java
class PHBody (line 7) | public class PHBody
method getBri (line 26) | public Integer getBri()
method setBri (line 31) | public void setBri(Integer bri)
method getTransitiontime (line 36) | public Integer getTransitiontime()
method setTransitiontime (line 41) | public void setTransitiontime(Integer transitiontime)
method getOn (line 46) | public Boolean getOn()
method setOn (line 51) | public void setOn(Boolean on)
method getXy (line 56) | public List<Double> getXy()
method setXy (line 61) | public void setXy(List<Double> xy)
method getScene (line 66) | public Boolean getScene() {
method setScene (line 70) | public void setScene(Boolean scene) {
FILE: src/com/hueemulator/model/PHBridgeConfiguration.java
class PHBridgeConfiguration (line 7) | public class PHBridgeConfiguration
method getLights (line 25) | public Map<String, PHLight> getLights()
method setLights (line 30) | public void setLights(Map<String, PHLight> lights)
method getSchedules (line 35) | public Map<String, PHSchedulesEntry> getSchedules()
method setSchedules (line 40) | public void setSchedules(Map<String, PHSchedulesEntry> schedules)
method getConfig (line 45) | public PHConfig getConfig()
method setConfig (line 50) | public void setConfig(PHConfig config)
method getGroups (line 55) | public Map<String, PHGroupsEntry> getGroups()
method getScenes (line 60) | public Map<String, PHScenesEntry> getScenes()
method setGroups (line 65) | public void setGroups(Map<String, PHGroupsEntry> groups)
method setScenes (line 70) | public void setScenes(Map<String, PHScenesEntry> scenes)
FILE: src/com/hueemulator/model/PHCommand.java
class PHCommand (line 5) | public class PHCommand
method getBody (line 16) | public PHBody getBody()
method setBody (line 21) | public void setBody(PHBody body)
method getAddress (line 26) | public String getAddress()
method setAddress (line 31) | public void setAddress(String address)
method getMethod (line 36) | public String getMethod()
method setMethod (line 41) | public void setMethod(String method)
FILE: src/com/hueemulator/model/PHConfig.java
class PHConfig (line 7) | public class PHConfig
method getPortalservices (line 59) | public Boolean getPortalservices()
method setPortalservices (line 64) | public void setPortalservices(Boolean portalservices)
method getGateway (line 69) | public String getGateway()
method setGateway (line 74) | public void setGateway(String gateway)
method getMac (line 79) | public String getMac()
method setMac (line 84) | public void setMac(String mac)
method getSwversion (line 89) | public String getSwversion()
method setSwversion (line 94) | public void setSwversion(String swversion)
method getLinkbutton (line 99) | public Boolean getLinkbutton()
method setLinkbutton (line 104) | public void setLinkbutton(Boolean linkbutton)
method getIpaddress (line 109) | public String getIpaddress()
method setIpaddress (line 114) | public void setIpaddress(String ipaddress)
method getProxyport (line 119) | public Integer getProxyport()
method setProxyport (line 124) | public void setProxyport(Integer proxyport)
method getSwupdate (line 129) | public PHSwupdate getSwupdate()
method setSwupdate (line 134) | public void setSwupdate(PHSwupdate swupdate)
method getNetmask (line 139) | public String getNetmask()
method setNetmask (line 144) | public void setNetmask(String netmask)
method getName (line 149) | public String getName()
method setName (line 154) | public void setName(String name)
method getDhcp (line 159) | public Boolean getDhcp()
method setDhcp (line 164) | public void setDhcp(Boolean dhcp)
method getUtc (line 169) | public String getUtc()
method setUtc (line 174) | public void setUtc(String utc)
method getProxyaddress (line 179) | public String getProxyaddress()
method setProxyaddress (line 184) | public void setProxyaddress(String proxyaddress)
method getWhitelist (line 189) | public Map<String, PHWhitelistEntry> getWhitelist() {
method setWhitelist (line 193) | public void setWhitelist(Map<String, PHWhitelistEntry> whitelist) {
method getBridgeid (line 197) | public String getBridgeid() {
method setBridgeid (line 201) | public void setBridgeid(String bridgeid) {
method getModelid (line 205) | public String getModelid() {
method setModelid (line 209) | public void setModelid(String modelid) {
FILE: src/com/hueemulator/model/PHGroupsEntry.java
class PHGroupsEntry (line 8) | @JsonIgnoreProperties(ignoreUnknown = true)
method getName (line 20) | public String getName()
method setName (line 25) | public void setName(String name)
method getLightState (line 30) | public PHLightState getLightState()
method setLightState (line 35) | public void setLightState(PHLightState lightState)
method getLightIdentifiers (line 40) | public List<String> getLightIdentifiers() {
method setLightIdentifiers (line 44) | public void setLightIdentifiers(List<String> lightIdentifiers) {
FILE: src/com/hueemulator/model/PHLight.java
class PHLight (line 8) | public class PHLight
method PHLight (line 34) | public PHLight() {}
method PHLight (line 36) | public PHLight(PHLight light) {
method getName (line 45) | public String getName()
method setName (line 50) | public void setName(String name)
method getState (line 55) | public PHLightState getState()
method setState (line 60) | public void setState(PHLightState state)
method getModelid (line 65) | public String getModelid()
method setModelid (line 70) | public void setModelid(String modelid)
method getSwversion (line 75) | public String getSwversion()
method setSwversion (line 80) | public void setSwversion(String swversion)
method getType (line 85) | public String getType()
method setType (line 90) | public void setType(String type)
method getPointsymbol (line 95) | public Map<String, String> getPointsymbol()
method setPointsymbol (line 100) | public void setPointsymbol(Map<String, String> pointsymbol)
method getIdentifier (line 105) | public String getIdentifier() {
method setIdentifier (line 109) | public void setIdentifier(String identifier) {
method getUniqueid (line 113) | public String getUniqueid() {
method setUniqueid (line 117) | public void setUniqueid(String uniqueid) {
FILE: src/com/hueemulator/model/PHLightState.java
class PHLightState (line 13) | public class PHLightState
method PHLightState (line 49) | public PHLightState() { }
method PHLightState (line 51) | public PHLightState(PHLightState lightState) {
method getBri (line 64) | public Integer getBri()
method setBri (line 69) | public void setBri(Integer bri)
method getEffect (line 74) | public String getEffect()
method setEffect (line 79) | public void setEffect(String effect)
method getSat (line 84) | public Integer getSat()
method setSat (line 89) | public void setSat(Integer sat)
method getReachable (line 94) | @JsonIgnore
method setReachable (line 100) | public void setReachable(Boolean reachable)
method getAlert (line 105) | public String getAlert()
method setAlert (line 110) | public void setAlert(String alert)
method getHue (line 115) | public Integer getHue()
method setHue (line 120) | public void setHue(Integer hue)
method getColormode (line 125) | public String getColormode()
method setColormode (line 130) | public void setColormode(String colormode)
method getOn (line 135) | public Boolean getOn()
method setOn (line 140) | public void setOn(Boolean on)
method getCt (line 145) | public Integer getCt()
method setCt (line 150) | public void setCt(Integer ct)
method getXy (line 155) | public List<Double> getXy()
method setXy (line 160) | public void setXy(List<Double> xy)
method serializeLightState (line 165) | public JSONObject serializeLightState(PHLightState state) throws JSONE...
method toString (line 219) | @Override
method getTransitionTime (line 224) | public Integer getTransitionTime() {
method setTransitionTime (line 228) | public void setTransitionTime(Integer transitionTime) {
FILE: src/com/hueemulator/model/PHScenesEntry.java
class PHScenesEntry (line 7) | public class PHScenesEntry
method getName (line 19) | public String getName()
method setName (line 24) | public void setName(String name)
method getLights (line 29) | public List<String> getLights()
method setLights (line 34) | public void setLights(List<String> lights)
method isActive (line 39) | public boolean isActive() {
method setActive (line 43) | public void setActive(boolean active) {
FILE: src/com/hueemulator/model/PHSchedulesEntry.java
class PHSchedulesEntry (line 6) | @JsonIgnoreProperties(ignoreUnknown = true)
method getTime (line 21) | public String getTime()
method setTime (line 26) | public void setTime(String time)
method getDescription (line 31) | public String getDescription()
method setDescription (line 36) | public void setDescription(String description)
method getName (line 41) | public String getName()
method setName (line 46) | public void setName(String name)
method getCommand (line 51) | public PHCommand getCommand()
method setCommand (line 56) | public void setCommand(PHCommand command)
FILE: src/com/hueemulator/model/PHSwupdate.java
class PHSwupdate (line 5) | public class PHSwupdate
method getText (line 19) | public String getText()
method setText (line 24) | public void setText(String text)
method getNotify (line 29) | public Boolean getNotify()
method setNotify (line 34) | public void setNotify(Boolean notify)
method getUpdatestate (line 39) | public Integer getUpdatestate()
method setUpdatestate (line 44) | public void setUpdatestate(Integer updatestate)
method getUrl (line 49) | public String getUrl()
method setUrl (line 54) | public void setUrl(String url)
FILE: src/com/hueemulator/model/PHWhitelistEntry.java
class PHWhitelistEntry (line 5) | public class PHWhitelistEntry
method getLastUseDate (line 16) | public String getLastUseDate()
method setLastUseDate (line 21) | public void setLastUseDate(String lastUseDate)
method getCreateDate (line 26) | public String getCreateDate()
method setCreateDate (line 31) | public void setCreateDate(String createDate)
method getName (line 36) | public String getName()
method setName (line 41) | public void setName(String name)
FILE: src/com/hueemulator/server/MyApiHandler.java
class MyApiHandler (line 25) | class MyApiHandler implements HttpHandler {
method MyApiHandler (line 35) | public MyApiHandler(PHBridgeConfiguration bridgeConfiguration, Control...
method handle (line 46) | public void handle(HttpExchange exchange) throws IOException {
method handlePut (line 127) | public void handlePut(ObjectMapper mapper, String url, OutputStream re...
method handlePost (line 159) | public void handlePost(ObjectMapper mapper, String url, OutputStream r...
method handleGet (line 175) | public void handleGet(ObjectMapper mapper, String url, OutputStream re...
method handleDelete (line 213) | public void handleDelete(ObjectMapper mapper, OutputStream responseBod...
FILE: src/com/hueemulator/server/MyRootHandler.java
class MyRootHandler (line 13) | class MyRootHandler implements HttpHandler {
method MyRootHandler (line 18) | public MyRootHandler(Controller controller) {
method handle (line 24) | public void handle(HttpExchange exchange) throws IOException {
FILE: src/com/hueemulator/server/Server.java
class Server (line 12) | public class Server {
method Server (line 16) | public Server(PHBridgeConfiguration bridgeConfiguration, Controller co...
method createContext (line 26) | public void createContext(PHBridgeConfiguration bridgeConfiguration, C...
method removeContext (line 31) | public void removeContext() {
method getHttpServer (line 36) | public HttpServer getHttpServer() {
method setHttpServer (line 40) | public void setHttpServer(HttpServer httpServer) {
FILE: src/com/hueemulator/server/UPNPServer.java
class UPNPServer (line 12) | public class UPNPServer extends Thread {
method UPNPServer (line 22) | public UPNPServer(Controller controller) {
method run (line 33) | public void run() {
method startUPNPServer (line 73) | public void startUPNPServer() {
method stopUPNPServer (line 78) | public void stopUPNPServer() {
FILE: src/com/hueemulator/server/handlers/ConfigurationAPI.java
class ConfigurationAPI (line 22) | public class ConfigurationAPI {
method getBridgeDescription (line 28) | public void getBridgeDescription(OutputStream responseBody, String ipA...
method createUser_7_1 (line 51) | public void createUser_7_1(ObjectMapper mapper, String jSONString, PHB...
method getConfig_7_2 (line 139) | public void getConfig_7_2(ObjectMapper mapper, PHBridgeConfiguration b...
method deleteUser_7_4 (line 150) | public void deleteUser_7_4(ObjectMapper mapper, PHBridgeConfiguration ...
method getFullState_7_5 (line 165) | public void getFullState_7_5(ObjectMapper mapper, PHBridgeConfiguratio...
method isValidUserName (line 172) | public boolean isValidUserName(PHBridgeConfiguration bridgeConfigurati...
method createNewUsername (line 198) | public void createNewUsername(PHBridgeConfiguration bridgeConfiguratio...
method returnNonAuthenticatedConfig (line 207) | public void returnNonAuthenticatedConfig(PHBridgeConfiguration bridgeC...
method returnErrorResponse (line 223) | public void returnErrorResponse(String errorType, String description, ...
FILE: src/com/hueemulator/server/handlers/GroupsAPI.java
class GroupsAPI (line 24) | public class GroupsAPI {
method getAllGroups_2_1 (line 32) | public void getAllGroups_2_1(ObjectMapper mapper, PHBridgeConfiguratio...
method createGroup_2_2 (line 63) | public void createGroup_2_2(ObjectMapper mapper, String jSONString, PH...
method getGroupAttributes_2_3 (line 143) | public void getGroupAttributes_2_3(ObjectMapper mapper, PHBridgeConfig...
method setGroupAttributes_2_4 (line 159) | public void setGroupAttributes_2_4(ObjectMapper mapper, String jSONStr...
method setGroupState_2_5 (line 240) | public void setGroupState_2_5(ObjectMapper mapper, String jSONString, ...
method removeDuplicates (line 317) | public static JSONArray removeDuplicates(JSONArray originalArray, bool...
method deleteGroup_2_6 (line 349) | public void deleteGroup_2_6(ObjectMapper mapper, PHBridgeConfiguration...
method sendErrorResponse (line 372) | public void sendErrorResponse(String groupIdentifier, String type, Out...
method getLightObjectsFromLightIds (line 386) | public List<PHLight> getLightObjectsFromLightIds(PHBridgeConfiguration...
FILE: src/com/hueemulator/server/handlers/LightsAPI.java
class LightsAPI (line 27) | public class LightsAPI {
method getAllLights_1_1 (line 35) | public void getAllLights_1_1(ObjectMapper mapper, PHBridgeConfiguratio...
method getLightAttributes_1_4 (line 55) | public void getLightAttributes_1_4(ObjectMapper mapper, PHBridgeConfig...
method getLightJSON (line 72) | public JSONObject getLightJSON(PHLight light) {
method setLightAttributes_1_5 (line 111) | public void setLightAttributes_1_5(ObjectMapper mapper, String jSONStr...
method setLightState_1_6 (line 169) | public void setLightState_1_6(ObjectMapper mapper, String jSONString, ...
method setLightState (line 192) | public void setLightState(String baseUrl, String lightType, PHLightSta...
method sendErrorResponse (line 377) | public void sendErrorResponse(String lightIdentifier, String type, Out...
FILE: src/com/hueemulator/server/handlers/ScenesAPI.java
class ScenesAPI (line 23) | public class ScenesAPI {
method getAllScenes_4_1 (line 33) | public void getAllScenes_4_1(ObjectMapper mapper, PHBridgeConfiguratio...
method createScene_4_2 (line 66) | public void createScene_4_2(ObjectMapper mapper, String jSONString, PH...
method cloneLightObjectsFromLightIds (line 144) | public List<PHLight> cloneLightObjectsFromLightIds(PHBridgeConfigurati...
FILE: src/com/hueemulator/server/handlers/SchedulesAPI.java
class SchedulesAPI (line 25) | public class SchedulesAPI {
method getAllSchedules_3_1 (line 32) | public void getAllSchedules_3_1(PHBridgeConfiguration bridgeConfigurat...
method createSchedule_3_2 (line 77) | public void createSchedule_3_2(ObjectMapper mapper, String jSONString,...
method getScheduleAttributes_3_3 (line 198) | public void getScheduleAttributes_3_3(ObjectMapper mapper, PHBridgeCon...
method setScheduleAttributes_3_4 (line 214) | public void setScheduleAttributes_3_4(ObjectMapper mapper, String jSON...
method deleteSchedule_3_5 (line 331) | public void deleteSchedule_3_5(ObjectMapper mapper, PHBridgeConfigurat...
method sendErrorResponse (line 355) | public void sendErrorResponse(String lightIdentifier, String type, Out...
class ScheduleTask (line 372) | class ScheduleTask extends TimerTask {
method ScheduleTask (line 378) | public ScheduleTask(String scheduleIdentifier, JSONObject commandObj...
method run (line 385) | public void run() {
FILE: src/com/hueemulator/utils/HueColor.java
class HueColor (line 18) | public class HueColor {
method alpha (line 36) | public static int alpha(int color) {
method red (line 44) | public static int red(int color) {
method green (line 52) | public static int green(int color) {
method blue (line 60) | public static int blue(int color) {
method rgb (line 74) | public static int rgb(int red, int green, int blue) {
method argb (line 88) | public static int argb(int alpha, int red, int green, int blue) {
method hue (line 99) | public static float hue(int color) {
method saturation (line 141) | public static float saturation(int color) {
method brightness (line 168) | public static float brightness(int color) {
method parseColor (line 189) | public static int parseColor(String colorString) {
FILE: src/com/hueemulator/utils/OpenFileFilter.java
class OpenFileFilter (line 14) | public class OpenFileFilter extends FileFilter {
method OpenFileFilter (line 19) | public OpenFileFilter(String extension) {
method OpenFileFilter (line 23) | public OpenFileFilter(String extension, String typeDescription) {
method accept (line 28) | @Override
method getDescription (line 35) | @Override
FILE: src/com/hueemulator/utils/PHUtilitiesHelper.java
class PHUtilitiesHelper (line 7) | public class PHUtilitiesHelper {
method colorFromXY (line 30) | public static int colorFromXY(float[] points, String model) {
method fixIfOutOfRange (line 110) | public static PointF fixIfOutOfRange(PointF xy, String model) {
method calculateXYFromRGB (line 159) | public float[] calculateXYFromRGB(int red, int green, int blue, String...
method calculateXY (line 174) | public float[] calculateXY(int color, String model) {
method checkPointInLampsReach (line 260) | private static boolean checkPointInLampsReach(PointF point, List<Point...
method getDistanceBetweenTwoPoints (line 287) | private static float getDistanceBetweenTwoPoints(PointF one, PointF tw...
method crossProduct (line 304) | private static float crossProduct(PointF point1, PointF point2) {
method colorPointsForModel (line 316) | private static List<PointF> colorPointsForModel(String model) {
method getClosestPointToPoints (line 368) | private static PointF getClosestPointToPoints(PointF pointA, PointF po...
method precision (line 389) | public static float precision(int decimalPlace, float val) {
FILE: src/com/hueemulator/utils/PointF.java
class PointF (line 7) | public class PointF {
method PointF (line 11) | public PointF() {}
method PointF (line 13) | public PointF(float x, float y) {
method set (line 22) | public final void set(float x, float y) {
method set (line 30) | public final void set(PointF p) {
method negate (line 35) | public final void negate() {
method offset (line 40) | public final void offset(float dx, float dy) {
method equals (line 48) | public final boolean equals(float x, float y) {
FILE: src/com/hueemulator/utils/Utils.java
class Utils (line 18) | public class Utils {
method isInRange (line 22) | public static boolean isInRange(int value, int start, int end) {
method chopName (line 30) | public static String chopName(String name) {
method isDateValid (line 47) | public static boolean isDateValid(String dateString) {
method stringToDate (line 67) | public static Date stringToDate(String dateString) {
method doHttpCall (line 86) | public static void doHttpCall(String ipAddress, String httpMethod, Str...
method getCurrentDate (line 116) | public static String getCurrentDate() {
method isJSONValid (line 125) | public static boolean isJSONValid(String test)
method loadDescriptionFile (line 138) | public static String loadDescriptionFile(String fileName) throws IOExc...
method generateRandomUsername (line 164) | public static String generateRandomUsername() {
method generateRandomUniqueId (line 177) | public static String generateRandomUniqueId()
FILE: src/org/json/JSONArray.java
class JSONArray (line 80) | public class JSONArray {
method JSONArray (line 90) | public JSONArray() {
method JSONArray (line 102) | public JSONArray(JSONTokener x) throws JSONException {
method JSONArray (line 143) | public JSONArray(String source) throws JSONException {
method JSONArray (line 153) | public JSONArray(Collection collection) {
method JSONArray (line 169) | public JSONArray(Object array) throws JSONException {
method get (line 191) | public Object get(int index) throws JSONException {
method getBoolean (line 210) | public boolean getBoolean(int index) throws JSONException {
method getDouble (line 234) | public double getDouble(int index) throws JSONException {
method getInt (line 253) | public int getInt(int index) throws JSONException {
method getJSONArray (line 273) | public JSONArray getJSONArray(int index) throws JSONException {
method getJSONObject (line 291) | public JSONObject getJSONObject(int index) throws JSONException {
method getLong (line 309) | public long getLong(int index) throws JSONException {
method getString (line 328) | public String getString(int index) throws JSONException {
method isNull (line 343) | public boolean isNull(int index) {
method join (line 358) | public String join(String separator) throws JSONException {
method length (line 376) | public int length() {
method opt (line 387) | public Object opt(int index) {
method optBoolean (line 401) | public boolean optBoolean(int index) {
method optBoolean (line 416) | public boolean optBoolean(int index, boolean defaultValue) {
method optDouble (line 433) | public double optDouble(int index) {
method optDouble (line 448) | public double optDouble(int index, double defaultValue) {
method optInt (line 465) | public int optInt(int index) {
method optInt (line 480) | public int optInt(int index, int defaultValue) {
method optJSONArray (line 496) | public JSONArray optJSONArray(int index) {
method optJSONObject (line 510) | public JSONObject optJSONObject(int index) {
method optLong (line 524) | public long optLong(int index) {
method optLong (line 539) | public long optLong(int index, long defaultValue) {
method optString (line 556) | public String optString(int index) {
method optString (line 570) | public String optString(int index, String defaultValue) {
method put (line 583) | public JSONArray put(boolean value) {
method put (line 596) | public JSONArray put(Collection value) {
method put (line 610) | public JSONArray put(double value) throws JSONException {
method put (line 624) | public JSONArray put(int value) {
method put (line 636) | public JSONArray put(long value) {
method put (line 649) | public JSONArray put(Map value) {
method put (line 663) | public JSONArray put(Object value) {
method put (line 681) | public JSONArray put(int index, boolean value) throws JSONException {
method put (line 698) | public JSONArray put(int index, Collection value) throws JSONException {
method put (line 716) | public JSONArray put(int index, double value) throws JSONException {
method put (line 734) | public JSONArray put(int index, int value) throws JSONException {
method put (line 752) | public JSONArray put(int index, long value) throws JSONException {
method put (line 770) | public JSONArray put(int index, Map value) throws JSONException {
method put (line 791) | public JSONArray put(int index, Object value) throws JSONException {
method remove (line 815) | public Object remove(int index) {
method toJSONObject (line 833) | public JSONObject toJSONObject(JSONArray names) throws JSONException {
method toString (line 855) | public String toString() {
method toString (line 875) | public String toString(int indentFactor) throws JSONException {
method write (line 891) | public Writer write(Writer writer) throws JSONException {
method write (line 908) | Writer write(Writer writer, int indentFactor, int indent)
FILE: src/org/json/JSONException.java
class JSONException (line 9) | public class JSONException extends RuntimeException {
method JSONException (line 19) | public JSONException(String message) {
method JSONException (line 26) | public JSONException(Throwable cause) {
method getCause (line 38) | public Throwable getCause() {
FILE: src/org/json/JSONObject.java
class JSONObject (line 95) | public class JSONObject {
class Null (line 101) | private static final class Null {
method equals (line 111) | public boolean equals(Object object) {
method toString (line 120) | public String toString() {
method JSONObject (line 141) | public JSONObject() {
method JSONObject (line 159) | public JSONObject(JSONObject jo, String[] names) {
method JSONObject (line 178) | public JSONObject(JSONTokener x) throws JSONException {
method JSONObject (line 232) | public JSONObject(Map map) {
method JSONObject (line 267) | public JSONObject(Object bean) {
method JSONObject (line 286) | public JSONObject(Object object, String names[]) {
method JSONObject (line 310) | public JSONObject(String source) throws JSONException {
method JSONObject (line 324) | public JSONObject(String baseName, Locale locale) throws JSONException {
method accumulate (line 376) | public JSONObject accumulate(String key, Object value) throws JSONExce...
method append (line 406) | public JSONObject append(String key, Object value) throws JSONException {
method doubleToString (line 428) | public static String doubleToString(double d) {
method get (line 457) | public Object get(String key) throws JSONException {
method getBoolean (line 478) | public boolean getBoolean(String key) throws JSONException {
method getDouble (line 503) | public double getDouble(String key) throws JSONException {
method getInt (line 524) | public int getInt(String key) throws JSONException {
method getJSONArray (line 544) | public JSONArray getJSONArray(String key) throws JSONException {
method getJSONObject (line 562) | public JSONObject getJSONObject(String key) throws JSONException {
method getLong (line 581) | public long getLong(String key) throws JSONException {
method getNames (line 597) | public static String[] getNames(JSONObject jo) {
method getNames (line 617) | public static String[] getNames(Object object) {
method getString (line 643) | public String getString(String key) throws JSONException {
method has (line 658) | public boolean has(String key) {
method increment (line 674) | public JSONObject increment(String key) throws JSONException {
method isNull (line 701) | public boolean isNull(String key) {
method keys (line 710) | public Iterator keys() {
method keySet (line 719) | public Set keySet() {
method length (line 728) | public int length() {
method names (line 739) | public JSONArray names() {
method numberToString (line 757) | public static String numberToString(Number number) throws JSONException {
method opt (line 785) | public Object opt(String key) {
method optBoolean (line 797) | public boolean optBoolean(String key) {
method optBoolean (line 812) | public boolean optBoolean(String key, boolean defaultValue) {
method optDouble (line 829) | public double optDouble(String key) {
method optDouble (line 844) | public double optDouble(String key, double defaultValue) {
method optInt (line 861) | public int optInt(String key) {
method optInt (line 876) | public int optInt(String key, int defaultValue) {
method optJSONArray (line 892) | public JSONArray optJSONArray(String key) {
method optJSONObject (line 905) | public JSONObject optJSONObject(String key) {
method optLong (line 919) | public long optLong(String key) {
method optLong (line 934) | public long optLong(String key, long defaultValue) {
method optString (line 951) | public String optString(String key) {
method optString (line 965) | public String optString(String key, String defaultValue) {
method populateMap (line 970) | private void populateMap(Object bean) {
method put (line 1027) | public JSONObject put(String key, boolean value) throws JSONException {
method put (line 1043) | public JSONObject put(String key, Collection value) throws JSONExcepti...
method put (line 1059) | public JSONObject put(String key, double value) throws JSONException {
method put (line 1075) | public JSONObject put(String key, int value) throws JSONException {
method put (line 1091) | public JSONObject put(String key, long value) throws JSONException {
method put (line 1107) | public JSONObject put(String key, Map value) throws JSONException {
method put (line 1126) | public JSONObject put(String key, Object value) throws JSONException {
method putOnce (line 1150) | public JSONObject putOnce(String key, Object value) throws JSONExcepti...
method putOpt (line 1174) | public JSONObject putOpt(String key, Object value) throws JSONException {
method quote (line 1191) | public static String quote(String string) {
method quote (line 1203) | public static Writer quote(String string, Writer w) throws IOException {
method remove (line 1270) | public Object remove(String key) {
method stringToValue (line 1282) | public static Object stringToValue(String string) {
method testValidity (line 1335) | public static void testValidity(Object o) throws JSONException {
method toJSONArray (line 1362) | public JSONArray toJSONArray(JSONArray names) throws JSONException {
method toString (line 1385) | public String toString() {
method toString (line 1407) | public String toString(int indentFactor) throws JSONException {
method valueToString (line 1438) | public static String valueToString(Object value) throws JSONException {
method wrap (line 1485) | public static Object wrap(Object object) {
method write (line 1532) | public Writer write(Writer writer) throws JSONException {
method writeValue (line 1536) | static final Writer writeValue(Writer writer, Object value,
method indent (line 1569) | static final void indent(Writer writer, int indent) throws IOException {
method write (line 1584) | Writer write(Writer writer, int indentFactor, int indent)
method equals (line 1632) | @Override
FILE: src/org/json/JSONString.java
type JSONString (line 10) | public interface JSONString {
method toJSONString (line 17) | String toJSONString();
FILE: src/org/json/JSONTokener.java
class JSONTokener (line 41) | public class JSONTokener {
method JSONTokener (line 57) | public JSONTokener(Reader reader) {
method JSONTokener (line 73) | public JSONTokener(InputStream inputStream) throws JSONException {
method JSONTokener (line 83) | public JSONTokener(String s) {
method back (line 93) | public void back() throws JSONException {
method dehexchar (line 110) | public static int dehexchar(char c) {
method end (line 123) | public boolean end() {
method more (line 133) | public boolean more() throws JSONException {
method next (line 148) | public char next() throws JSONException {
method next (line 187) | public char next(char c) throws JSONException {
method next (line 206) | public String next(int n) throws JSONException {
method nextClean (line 230) | public char nextClean() throws JSONException {
method nextString (line 251) | public String nextString(char quote) throws JSONException {
method nextTo (line 308) | public String nextTo(char delimiter) throws JSONException {
method nextTo (line 329) | public String nextTo(String delimiters) throws JSONException {
method nextValue (line 353) | public Object nextValue() throws JSONException {
method skipTo (line 400) | public char skipTo(char to) throws JSONException {
method syntaxError (line 432) | public JSONException syntaxError(String message) {
method toString (line 442) | public String toString() {
FILE: tests/com/hueemulator/emulator/HttpTester.java
class HttpTester (line 12) | public class HttpTester {
method doGet (line 15) | public String doGet(String url) {
method doPutOrPost (line 53) | public String doPutOrPost(String url, String jsonString, String reques...
method doDelete (line 98) | public String doDelete(String url) {
FILE: tests/com/hueemulator/emulator/TestEmulator.java
class TestEmulator (line 12) | public class TestEmulator {
method getInstance (line 24) | public static TestEmulator getInstance() {
method startEmulator (line 33) | public void startEmulator() throws IOException {
method reloadInitialConfig (line 60) | public void reloadInitialConfig() {
method isServerRunning (line 66) | public boolean isServerRunning() {
method setServerRunning (line 70) | public void setServerRunning(boolean isServerRunning) {
method getEmulator (line 76) | public Emulator getEmulator() {
method setEmulator (line 81) | public void setEmulator(Emulator emulator) {
method getModel (line 85) | public Model getModel() {
method setModel (line 89) | public void setModel(Model model) {
FILE: tests/com/hueemulator/lighting/utils/TestUtils.java
class TestUtils (line 51) | public class TestUtils {
method loadTestFixture (line 61) | public static String loadTestFixture(String path) throws IOException {
method jsonsEqual (line 78) | public static boolean jsonsEqual(String json1, String json2) throws Ex...
method jsonsArrayEqual (line 91) | public static boolean jsonsArrayEqual(String json1, String json2) thro...
method xmlsEqual (line 106) | public static boolean xmlsEqual(String xml1, String xml2) throws Excep...
method convertJsonElement (line 130) | @SuppressWarnings("unchecked")
method getChildSet (line 161) | private static Set<Object> getChildSet(Node node, String basePath) {
method getDateSecondsInFuture (line 174) | public static String getDateSecondsInFuture(int noSeconds) {
FILE: tests/com/hueemulator/server/handlers/TestConfigurationAPI.java
class TestConfigurationAPI (line 15) | public class TestConfigurationAPI extends TestCase {
method setUp (line 23) | @Before
method testBadJSON (line 37) | public void testBadJSON() throws Exception {
method testCreateUserAPI_4_1 (line 47) | @Test
method testRandomUsernames (line 60) | @Test
FILE: tests/com/hueemulator/server/handlers/TestGroupsAPI.java
class TestGroupsAPI (line 16) | public class TestGroupsAPI extends TestCase {
method setUp (line 25) | @Before
method testGroupsAPI_2_1 (line 39) | @Test
method testGroupsAPI_2_2 (line 52) | @Test
method testGroupsAPI_2_3 (line 67) | @Test
method testGroupsAPI_2_4 (line 79) | @Test
method testGroupsAPI_2_5 (line 92) | @Test
method testGroupsAPI_2_6 (line 105) | @Test
FILE: tests/com/hueemulator/server/handlers/TestLightsAPI.java
class TestLightsAPI (line 16) | public class TestLightsAPI extends TestCase {
method setUp (line 24) | @Before
method testLightsAPI_1_1 (line 38) | @Test
method testLightsAPI_1_4 (line 51) | @Test
method testLightsAPI_1_5 (line 74) | @Test
method testLightsAPI_1_6 (line 94) | @Test
FILE: tests/com/hueemulator/server/handlers/TestSchedulesAPI.java
class TestSchedulesAPI (line 16) | public class TestSchedulesAPI extends TestCase {
method setUp (line 24) | @Before
method testSchedulesAPI_3_1 (line 38) | @Test
method testSchedulesAPI_3_2 (line 52) | @Test
method testSchedulesAPI_3_3 (line 97) | @Test
method testSchedulesAPI_3_4 (line 109) | @Test
method testSchedulesAPI_3_5 (line 129) | @Test
Condensed preview — 69 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (361K chars).
[
{
"path": ".classpath",
"chars": 515,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"src\" path=\"src\"/>\n\t<classpathentry kind=\"src\" "
},
{
"path": ".gitignore",
"chars": 5,
"preview": "/bin\n"
},
{
"path": ".project",
"chars": 370,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>hueemulator</name>\n\t<comment></comment>\n\t<projects>\n\t"
},
{
"path": "CHANGELOG.md",
"chars": 2677,
"preview": "Hue-Emulator Changelog\n============\nv0.8 (18-March-2018)\n* Merged in the 4 open pull requests.\n\nv0.7 (04-December-2015)\n"
},
{
"path": "README.md",
"chars": 478,
"preview": "Hue-Emulator\n============\n\nThe Hue Emulator is a Bridge Emulator for the Philips Hue - Personal Wireless System. \n\nIt a"
},
{
"path": "resources/config-3bulbs.json",
"chars": 4199,
"preview": "{\n \"lights\": {\n \"1\": {\n \"state\": {\n \"on\": true,\n \"bri\": 254,\n "
},
{
"path": "resources/description.xml",
"chars": 1163,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<root xmlns=\"urn:schemas-upnp-org:device-1-0\">\n\t<specVersion>\n\t\t<major>1</major>"
},
{
"path": "src/com/hueemulator/emulator/Constants.java",
"chars": 445,
"preview": "package com.hueemulator.emulator;\n\npublic class Constants {\n \n public static String EMULATOR_VERSION = \"v0.6\"; \n "
},
{
"path": "src/com/hueemulator/emulator/Controller.java",
"chars": 14863,
"preview": "package com.hueemulator.emulator;\n\nimport java.awt.Color;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.Actio"
},
{
"path": "src/com/hueemulator/emulator/Emulator.java",
"chars": 3603,
"preview": "package com.hueemulator.emulator;\n\nimport java.awt.Color;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport ja"
},
{
"path": "src/com/hueemulator/emulator/HueEmulator.java",
"chars": 978,
"preview": "package com.hueemulator.emulator;\n\nimport com.hueemulator.gui.View;\n\npublic class HueEmulator{\n \n public static voi"
},
{
"path": "src/com/hueemulator/emulator/Model.java",
"chars": 1331,
"preview": "package com.hueemulator.emulator;\n\nimport com.hueemulator.model.PHBridgeConfiguration;\n\n\npublic class Model {\n \n private"
},
{
"path": "src/com/hueemulator/emulator/PHScheduleTimer.java",
"chars": 611,
"preview": "package com.hueemulator.emulator;\n\nimport java.util.Timer;\n\nimport org.json.JSONObject;\n\npublic class PHScheduleTimer ex"
},
{
"path": "src/com/hueemulator/emulator/PHScheduleTimerManager.java",
"chars": 982,
"preview": "package com.hueemulator.emulator;\n\nimport java.util.HashMap;\n\n\npublic class PHScheduleTimerManager {\n\n private static"
},
{
"path": "src/com/hueemulator/gui/About.java",
"chars": 700,
"preview": "package com.hueemulator.gui;\n\nimport javax.swing.JEditorPane;\nimport javax.swing.JFrame;\n\nimport com.hueemulator.emulato"
},
{
"path": "src/com/hueemulator/gui/GraphicsPanel.java",
"chars": 12659,
"preview": "package com.hueemulator.gui;\n\n\nimport java.awt.AlphaComposite;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport "
},
{
"path": "src/com/hueemulator/gui/Help.java",
"chars": 937,
"preview": "package com.hueemulator.gui;\n\nimport javax.swing.JEditorPane;\nimport javax.swing.JFrame;\n\n\npublic class Help extends JFr"
},
{
"path": "src/com/hueemulator/gui/HueMenuBar.java",
"chars": 10721,
"preview": "package com.hueemulator.gui;\n\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.Action"
},
{
"path": "src/com/hueemulator/gui/LightsFrame.java",
"chars": 1063,
"preview": "package com.hueemulator.gui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\n\nimport javax.swing.JFrame;\n\nimpo"
},
{
"path": "src/com/hueemulator/gui/PropertiesFrame.java",
"chars": 1354,
"preview": "package com.hueemulator.gui;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport javax.swi"
},
{
"path": "src/com/hueemulator/gui/View.java",
"chars": 3573,
"preview": "package com.hueemulator.gui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport jav"
},
{
"path": "src/com/hueemulator/model/PHBody.java",
"chars": 1170,
"preview": "package com.hueemulator.model;\n\nimport java.util.List;\n\nimport org.codehaus.jackson.annotate.JsonProperty;\n\npublic class"
},
{
"path": "src/com/hueemulator/model/PHBridgeConfiguration.java",
"chars": 1267,
"preview": "package com.hueemulator.model;\n\nimport java.util.Map;\n\nimport org.codehaus.jackson.annotate.JsonProperty;\n\npublic class "
},
{
"path": "src/com/hueemulator/model/PHCommand.java",
"chars": 615,
"preview": "package com.hueemulator.model;\n\nimport org.codehaus.jackson.annotate.JsonProperty;\n\npublic class PHCommand\n{\n @JsonPrope"
},
{
"path": "src/com/hueemulator/model/PHConfig.java",
"chars": 3183,
"preview": "package com.hueemulator.model;\n\nimport java.util.Map;\n\nimport org.codehaus.jackson.annotate.JsonProperty;\n\npublic class "
},
{
"path": "src/com/hueemulator/model/PHGroupsEntry.java",
"chars": 989,
"preview": "package com.hueemulator.model;\n\nimport java.util.List;\n\nimport org.codehaus.jackson.annotate.JsonIgnoreProperties;\nimpor"
},
{
"path": "src/com/hueemulator/model/PHLight.java",
"chars": 1952,
"preview": "package com.hueemulator.model;\n\nimport java.util.Map;\n\nimport org.codehaus.jackson.annotate.JsonIgnore;\nimport org.codeh"
},
{
"path": "src/com/hueemulator/model/PHLightState.java",
"chars": 4415,
"preview": "package com.hueemulator.model;\n\nimport java.util.List;\nimport java.util.Locale;\n\nimport org.codehaus.jackson.annotate.Js"
},
{
"path": "src/com/hueemulator/model/PHScenesEntry.java",
"chars": 666,
"preview": "package com.hueemulator.model;\n\nimport java.util.List;\n\nimport org.codehaus.jackson.annotate.JsonProperty;\n\npublic class"
},
{
"path": "src/com/hueemulator/model/PHSchedulesEntry.java",
"chars": 930,
"preview": "package com.hueemulator.model;\n\nimport org.codehaus.jackson.annotate.JsonIgnoreProperties;\nimport org.codehaus.jackson.a"
},
{
"path": "src/com/hueemulator/model/PHSwupdate.java",
"chars": 801,
"preview": "package com.hueemulator.model;\n\nimport org.codehaus.jackson.annotate.JsonProperty;\n\npublic class PHSwupdate\n{\n @JsonProp"
},
{
"path": "src/com/hueemulator/model/PHWhitelistEntry.java",
"chars": 689,
"preview": "package com.hueemulator.model;\n\nimport org.codehaus.jackson.annotate.JsonProperty;\n\npublic class PHWhitelistEntry\n{\n @Js"
},
{
"path": "src/com/hueemulator/server/MyApiHandler.java",
"chars": 11763,
"preview": "package com.hueemulator.server;\n\nimport java.awt.Color;\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimpor"
},
{
"path": "src/com/hueemulator/server/MyRootHandler.java",
"chars": 2195,
"preview": "package com.hueemulator.server;\n\nimport java.awt.Color;\nimport java.io.IOException;\nimport java.io.OutputStream;\n\nimport"
},
{
"path": "src/com/hueemulator/server/Server.java",
"chars": 1297,
"preview": "package com.hueemulator.server;\n\nimport java.io.IOException;\nimport java.net.InetSocketAddress;\nimport java.util.concurr"
},
{
"path": "src/com/hueemulator/server/UPNPServer.java",
"chars": 2720,
"preview": "package com.hueemulator.server;\n\nimport java.awt.Color;\nimport java.io.IOException;\nimport java.net.DatagramPacket;\nimpo"
},
{
"path": "src/com/hueemulator/server/handlers/ConfigurationAPI.java",
"chars": 12138,
"preview": "package com.hueemulator.server.handlers;\n\nimport java.awt.Color;\nimport java.io.IOException;\nimport java.io.OutputStream"
},
{
"path": "src/com/hueemulator/server/handlers/GroupsAPI.java",
"chars": 19756,
"preview": "package com.hueemulator.server.handlers;\n\nimport java.awt.Color;\nimport java.io.IOException;\nimport java.io.OutputStream"
},
{
"path": "src/com/hueemulator/server/handlers/LightsAPI.java",
"chars": 18922,
"preview": "package com.hueemulator.server.handlers;\n\nimport java.awt.Color;\nimport java.io.IOException;\nimport java.io.OutputStream"
},
{
"path": "src/com/hueemulator/server/handlers/ScenesAPI.java",
"chars": 7344,
"preview": "package com.hueemulator.server.handlers;\n\nimport java.awt.Color;\nimport java.io.IOException;\nimport java.io.OutputStream"
},
{
"path": "src/com/hueemulator/server/handlers/SchedulesAPI.java",
"chars": 20280,
"preview": "package com.hueemulator.server.handlers;\n\nimport java.awt.Color;\nimport java.io.IOException;\nimport java.io.OutputStream"
},
{
"path": "src/com/hueemulator/utils/HueColor.java",
"chars": 7881,
"preview": "package com.hueemulator.utils;\n\nimport java.util.HashMap;\nimport java.util.Locale;\n\n/**\n * The Color class defines metho"
},
{
"path": "src/com/hueemulator/utils/OpenFileFilter.java",
"chars": 1027,
"preview": "package com.hueemulator.utils;\n\n/**\n * This class defines which file types are displayed (by default) by the JFileChoose"
},
{
"path": "src/com/hueemulator/utils/PHUtilitiesHelper.java",
"chars": 14476,
"preview": "package com.hueemulator.utils;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Locale;\n\npublic clas"
},
{
"path": "src/com/hueemulator/utils/PointF.java",
"chars": 958,
"preview": "package com.hueemulator.utils;\n\n\n/**\n * PointF holds two float coordinates\n */\npublic class PointF {\n public float x;"
},
{
"path": "src/com/hueemulator/utils/Utils.java",
"chars": 5706,
"preview": "package com.hueemulator.utils;\n\nimport java.io.BufferedReader;\nimport java.io.DataOutputStream;\nimport java.io.IOExcepti"
},
{
"path": "src/org/json/JSONArray.java",
"chars": 31022,
"preview": "package org.json;\n\n/*\n Copyright (c) 2002 JSON.org\n\n Permission is hereby granted, free of charge, to any person obtaini"
},
{
"path": "src/org/json/JSONException.java",
"chars": 1022,
"preview": "package org.json;\n\n/**\n * The JSONException is thrown by the JSON.org classes when things are amiss.\n *\n * @author JSON."
},
{
"path": "src/org/json/JSONObject.java",
"chars": 56231,
"preview": "package org.json;\n\n/*\n Copyright (c) 2002 JSON.org\n\n Permission is hereby granted, free of charge, to any person obtaini"
},
{
"path": "src/org/json/JSONString.java",
"chars": 701,
"preview": "package org.json;\n/**\n * The <code>JSONString</code> interface allows a <code>toJSONString()</code>\n * method so that a "
},
{
"path": "src/org/json/JSONTokener.java",
"chars": 12945,
"preview": "package org.json;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io"
},
{
"path": "tests/com/hueemulator/emulator/HttpTester.java",
"chars": 3211,
"preview": "package com.hueemulator.emulator;\n\n\nimport java.io.BufferedReader;\nimport java.io.DataOutputStream;\nimport java.io.IOExc"
},
{
"path": "tests/com/hueemulator/emulator/TestEmulator.java",
"chars": 2644,
"preview": "package com.hueemulator.emulator;\n\nimport java.io.IOException;\n\nimport com.hueemulator.emulator.Controller;\nimport com.h"
},
{
"path": "tests/com/hueemulator/lighting/utils/TestUtils.java",
"chars": 6539,
"preview": "package com.hueemulator.lighting.utils;\n/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more cont"
},
{
"path": "tests/com/hueemulator/server/handlers/TestConfigurationAPI.java",
"chars": 2407,
"preview": "package com.hueemulator.server.handlers;\n\nimport java.io.IOException;\n\nimport junit.framework.TestCase;\n\nimport org.juni"
},
{
"path": "tests/com/hueemulator/server/handlers/TestGroupsAPI.java",
"chars": 5119,
"preview": "package com.hueemulator.server.handlers;\n\nimport java.io.IOException;\n\nimport junit.framework.TestCase;\n\nimport org.juni"
},
{
"path": "tests/com/hueemulator/server/handlers/TestLightsAPI.java",
"chars": 7501,
"preview": "package com.hueemulator.server.handlers;\n\nimport java.io.IOException;\n\nimport junit.framework.TestCase;\n\nimport org.juni"
},
{
"path": "tests/com/hueemulator/server/handlers/TestSchedulesAPI.java",
"chars": 6706,
"preview": "package com.hueemulator.server.handlers;\n\nimport java.io.IOException;\n\nimport junit.framework.TestCase;\n\nimport org.juni"
}
]
// ... and 11 more files (download for full content)
About this extraction
This page contains the full source code of the SteveyO/Hue-Emulator GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 69 files (334.4 KB), approximately 79.2k tokens, and a symbol index with 582 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.