mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-19 00:20:26 +00:00
Refactoring ready for testing
This commit is contained in:
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user