Refactoring ready for testing

This commit is contained in:
bwssystems
2016-12-26 22:34:19 -06:00
parent d827605fa5
commit 2e177f3d4a
8 changed files with 197 additions and 229 deletions

View File

@@ -4,7 +4,6 @@ import com.bwssystems.HABridge.BridgeSettingsDescriptor;
import com.bwssystems.HABridge.DeviceMapTypes;
import com.bwssystems.HABridge.HomeManager;
import com.bwssystems.HABridge.api.CallItem;
import com.bwssystems.HABridge.api.NameValue;
import com.bwssystems.HABridge.api.UserCreateRequest;
import com.bwssystems.HABridge.api.hue.DeviceResponse;
import com.bwssystems.HABridge.api.hue.DeviceState;
@@ -21,7 +20,6 @@ import com.bwssystems.hue.HueDeviceIdentifier;
import com.bwssystems.hue.HueHome;
import com.bwssystems.hue.HueUtil;
import com.bwssystems.util.JsonTransformer;
import com.bwssystems.util.UDPDatagramSender;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -36,10 +34,6 @@ import org.apache.http.client.methods.HttpGet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -48,8 +42,6 @@ import java.util.Set;
import java.util.StringTokenizer;
import java.util.UUID;
import javax.xml.bind.DatatypeConverter;
/**
* Based on Armzilla's HueMulator - a Philips Hue emulator using sparkjava rest server
*/
@@ -62,20 +54,15 @@ public class HueMulator {
private HomeManager homeManager;
private HueHome myHueHome;
private BridgeSettingsDescriptor bridgeSettings;
private UDPDatagramSender theUDPDatagramSender;
private byte[] sendData;
private Gson aGsonHandler;
private HTTPHandler anHttpHandler;
public HueMulator(BridgeSettingsDescriptor theBridgeSettings, DeviceRepository aDeviceRepository, HomeManager aHomeManager, UDPDatagramSender aUdpDatagramSender) {
public HueMulator(BridgeSettingsDescriptor theBridgeSettings, DeviceRepository aDeviceRepository, HomeManager aHomeManager) {
repository = aDeviceRepository;
bridgeSettings = theBridgeSettings;
theUDPDatagramSender = aUdpDatagramSender;
homeManager= aHomeManager;
myHueHome = (HueHome) homeManager.findHome(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex]);
aGsonHandler =
new GsonBuilder()
.create();
aGsonHandler = new GsonBuilder().create();
anHttpHandler = new HTTPHandler();
}
@@ -276,30 +263,7 @@ public class HueMulator {
return changeState(request.params(":userid"), request.params(":id"), request.body(), request.ip());
});
}
private String doExecRequest(String anItem, int intensity, String lightId) {
log.debug("Executing request: " + anItem);
String responseString = null;
if (anItem != null && !anItem.equalsIgnoreCase("")) {
try {
Process p = Runtime.getRuntime().exec(BrightnessDecode.replaceIntensityValue(anItem, intensity, false));
log.debug("Process running: " + p.isAlive());
} catch (IOException e) {
log.warn("Could not execute request: " + anItem, e);
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/" + lightId
+ "state\"}}]";
}
} else {
log.warn("Could not execute request. Request is empty.");
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/" + lightId
+ "state\"}}]";
}
return responseString;
}
private String formatSuccessHueResponse(StateChangeBody state, String body, String lightId,
DeviceState deviceState) {
@@ -571,11 +535,13 @@ public class HueMulator {
deviceResponse = DeviceResponse.createResponse(device);
} else {
deviceResponse = aGsonHandler.fromJson(responseString, DeviceResponse.class);
if (deviceResponse == null)
deviceResponse = DeviceResponse.createResponse(device);
if (deviceResponse != null)
deviceResponse.setName(device.getName());
}
}
} else
}
if (deviceResponse == null)
deviceResponse = DeviceResponse.createResponse(device);
deviceResponseMap.put(device.getId(), deviceResponse);
}
@@ -786,7 +752,6 @@ public class HueMulator {
private String changeState(String userId, String lightId, String body, String ipAddress) {
String responseString = null;
String url = null;
NameValue[] theHeaders = null;
StateChangeBody theStateChanges = null;
DeviceState state = null;
MultiCommandUtil aMultiUtil = new MultiCommandUtil();
@@ -827,8 +792,6 @@ public class HueMulator {
if (state == null)
state = DeviceState.createDeviceState();
theHeaders = aGsonHandler.fromJson(device.getHeaders(), NameValue[].class);
if (stateHasBri) {
if(!state.isOn())
state.setOn(true);
@@ -851,12 +814,9 @@ public class HueMulator {
if (theStateChanges.isOn()) {
url = device.getOnUrl();
state.setOn(true);
// if (state.getBri() <= 0)
// state.setBri(255);
} else if (!theStateChanges.isOn()) {
url = device.getOffUrl();
state.setOn(false);
// state.setBri(0);
}
}
@@ -865,14 +825,7 @@ public class HueMulator {
if(url == null)
url = device.getOnUrl();
}
CallItem[] callItems = null;
if (url == null) {
log.warn("Could not find url: " + lightId + " for hue state change request: " + userId + " from "
+ ipAddress + " body: " + body);
responseString = "[{\"error\":{\"type\": 3, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Could not find url\", \"resource\": \"/lights/" + lightId + "\"}}]";
}
else {
if (url != null) {
if (!url.startsWith("[")) {
if (url.startsWith("{\"item"))
url = "[" + url + "]";
@@ -880,152 +833,37 @@ public class HueMulator {
url = "[{\"item\":\"" + url + "\"}]";
}
// CallItem[] callItems = callItemGson.fromJson(url,
// CallItem[].class);
CallItem[] callItems = null;
callItems = aGsonHandler.fromJson(url, CallItem[].class);
}
for (int i = 0; callItems != null && i < callItems.length; i++) {
if(!filterByRequester(callItems[i].getFilterIPs(), ipAddress)) {
log.debug("filter for requester address not present in list: " + callItems[i].getFilterIPs() + " with request ip of: " + ipAddress);
continue;
}
if (callItems[i].getCount() != null && callItems[i].getCount() > 0)
aMultiUtil.setSetCount(callItems[i].getCount());
else
aMultiUtil.setSetCount(1);
// code for backwards compatibility
if((callItems[i].getType() == null || callItems[i].getType().trim().length() == 0)) {
if(device.getMapType() != null && device.getMapType().length() > 0)
callItems[i].setType(device.getMapType());
else if(device.getDeviceType() != null && device.getDeviceType().length() > 0)
callItems[i].setType(device.getDeviceType());
for (int i = 0; callItems != null && i < callItems.length; i++) {
if(!filterByRequester(callItems[i].getFilterIPs(), ipAddress)) {
log.debug("filter for requester address not present in list: " + callItems[i].getFilterIPs() + " with request ip of: " + ipAddress);
continue;
}
if (callItems[i].getCount() != null && callItems[i].getCount() > 0)
aMultiUtil.setSetCount(callItems[i].getCount());
else
callItems[i].setType(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex]);
}
if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) {
return homeManager.findHome(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex]).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc, device, body);
} else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.HARMONY_ACTIVITY[DeviceMapTypes.typeIndex])) {
return homeManager.findHome(DeviceMapTypes.HARMONY_ACTIVITY[DeviceMapTypes.typeIndex]).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc, device, body);
} else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.HARMONY_BUTTON[DeviceMapTypes.typeIndex])) {
return homeManager.findHome(DeviceMapTypes.HARMONY_BUTTON[DeviceMapTypes.typeIndex]).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc, device, body);
} else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.NEST_HOMEAWAY[DeviceMapTypes.typeIndex])) {
return homeManager.findHome(DeviceMapTypes.NEST_HOMEAWAY[DeviceMapTypes.typeIndex]).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc, device, body);
} else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.NEST_THERMO_SET[DeviceMapTypes.typeIndex])) {
return homeManager.findHome(DeviceMapTypes.NEST_THERMO_SET[DeviceMapTypes.typeIndex]).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc, device, body);
} else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.MQTT_MESSAGE[DeviceMapTypes.typeIndex])) {
return homeManager.findHome(DeviceMapTypes.MQTT_MESSAGE[DeviceMapTypes.typeIndex]).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc, device, body);
} else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.HASS_DEVICE[DeviceMapTypes.typeIndex])) {
responseString = homeManager.findHome(DeviceMapTypes.HASS_DEVICE[DeviceMapTypes.typeIndex]).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc, device, body);
} else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.EXEC_DEVICE[DeviceMapTypes.typeIndex])) {
responseString = homeManager.findHome(DeviceMapTypes.EXEC_DEVICE[DeviceMapTypes.typeIndex]).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc, device, body);
} else // This section allows the usage of http/tcp/udp/exec
// calls in a given set of items
{
log.debug("executing HUE api request for network call: " + url);
for (int x = 0; x < aMultiUtil.getSetCount(); x++) {
if (x > 0 || i > 0) {
try {
Thread.sleep(aMultiUtil.getTheDelay());
} catch (InterruptedException e) {
// ignore
}
}
if (callItems[i].getDelay() != null && callItems[i].getDelay() > 0)
aMultiUtil.setTheDelay(callItems[i].getDelay());
aMultiUtil.setSetCount(1);
// code for backwards compatibility
if((callItems[i].getType() == null || callItems[i].getType().trim().length() == 0)) {
if(device.getMapType() != null && device.getMapType().length() > 0)
callItems[i].setType(device.getMapType());
else if(device.getDeviceType() != null && device.getDeviceType().length() > 0)
callItems[i].setType(device.getDeviceType());
else
aMultiUtil.setTheDelay(bridgeSettings.getButtonsleep());
try {
if (callItems[i].getItem().getAsString().contains("udp://")
|| callItems[i].getItem().getAsString().contains("tcp://")) {
String intermediate = callItems[i].getItem().getAsString()
.substring(callItems[i].getItem().getAsString().indexOf("://") + 3);
String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
String hostAddr = null;
String port = null;
if (hostPortion.contains(":")) {
hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
port = hostPortion.substring(intermediate.indexOf(':') + 1);
} else
hostAddr = hostPortion;
InetAddress IPAddress = InetAddress.getByName(hostAddr);
if (theUrlBody.startsWith("0x")) {
theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody,
state, theStateChanges, stateHasBri, stateHasBriInc,
true);
sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2));
} else {
theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody,
state, theStateChanges, stateHasBri, stateHasBriInc,
false);
sendData = theUrlBody.getBytes();
}
if (callItems[i].getItem().getAsString().contains("udp://")) {
log.debug("executing HUE api request to UDP: " + callItems[i].getItem().getAsString());
theUDPDatagramSender.sendUDPResponse(new String(sendData), IPAddress,
Integer.parseInt(port));
} else if (callItems[i].getItem().getAsString().contains("tcp://")) {
log.debug("executing HUE api request to TCP: " + callItems[i].getItem().getAsString());
Socket dataSendSocket = new Socket(IPAddress, Integer.parseInt(port));
DataOutputStream outToClient = new DataOutputStream(
dataSendSocket.getOutputStream());
outToClient.write(sendData);
outToClient.flush();
dataSendSocket.close();
}
} else if (callItems[i].getItem().getAsString().contains("exec://")) {
String intermediate = callItems[i].getItem().getAsString()
.substring(callItems[i].getItem().getAsString().indexOf("://") + 3);
String anError = doExecRequest(intermediate,
BrightnessDecode.calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc),
lightId);
if (anError != null) {
responseString = anError;
x = aMultiUtil.getSetCount();
}
} else {
log.debug("executing HUE api request to Http "
+ (device.getHttpVerb() == null ? "GET" : device.getHttpVerb()) + ": "
+ callItems[i].getItem().getAsString());
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(callItems[i].getItem().getAsString(),
state, theStateChanges, stateHasBri, stateHasBriInc, false);
String aBody;
if (stateHasBri || stateHasBriInc)
aBody = BrightnessDecode.calculateReplaceIntensityValue(device.getContentBodyDim(),
state, theStateChanges, stateHasBri, stateHasBriInc,
false);
else if (state.isOn())
aBody = BrightnessDecode.calculateReplaceIntensityValue(device.getContentBody(),
state, theStateChanges, stateHasBri, stateHasBriInc,
false);
else
aBody = BrightnessDecode.calculateReplaceIntensityValue(device.getContentBodyOff(),
state, theStateChanges, stateHasBri, stateHasBriInc,
false);
// make call
if (anHttpHandler.doHttpRequest(anUrl, device.getHttpVerb(), device.getContentType(), aBody,
theHeaders) == null) {
log.warn("Error on calling url to change device state: " + anUrl);
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling url to change device state\", \"parameter\": \"/lights/"
+ lightId + "state\"}}]";
x = aMultiUtil.getSetCount();
}
}
} catch (Exception e) {
log.warn("Change device state, Could not send data for network request: "
+ callItems[i].getItem().getAsString() + " with Message: " + e.getMessage());
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/"
+ lightId + "state\"}}]";
x = aMultiUtil.getSetCount();
}
callItems[i].setType(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex]);
}
if (callItems[i].getType() != null) {
responseString = homeManager.findHome(callItems[i].getType().trim()).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc, device, body);
}
}
} else {
log.warn("Could not find url: " + lightId + " for hue state change request: " + userId + " from "
+ ipAddress + " body: " + body);
responseString = "[{\"error\":{\"type\": 3, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Could not find url\", \"resource\": \"/lights/" + lightId + "\"}}]";
}
if (responseString == null || !responseString.contains("[{\"error\":")) {
@@ -1036,5 +874,4 @@ public class HueMulator {
return responseString;
}
}