diff --git a/pom.xml b/pom.xml
index 7800189..228aac1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.bwssystems.HABridge
ha-bridge
- 3.5.1a
+ 3.5.1b
jar
HA Bridge
diff --git a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java
new file mode 100644
index 0000000..ccc8cac
--- /dev/null
+++ b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java
@@ -0,0 +1,18 @@
+package com.bwssystems.HABridge;
+
+public class DeviceMapTypes {
+ public final static String CUSTOM_DEVICE = "custom";
+ public final static String VERA_DEVICE = "veraDevice";
+ public final static String VERA_SCENE = "veraScene";
+ public final static String HARMONY_ACTIVITY = "harmonyActivity";
+ public final static String HARMONY_BUTTON = "harmonyButton";
+ public final static String NEST_HOMEAWAY = "nestHomeAway";
+ public final static String NEST_THERMO_SET = "nestThermoSet";
+ public final static String HUE_DEVICE = "hueDevice";
+ public final static String HAL_DEVICE = "halDevice";
+ public final static String HAL_BUTTON = "halButton";
+ public final static String HAL_HOME = "halHome";
+ public final static String HAL_THERMO_SET = "halThermoSet";
+ public final static String MQTT_MESSAGE = "mqttMessage";
+ public final static String EXEC_DEVICE = "execDevice";
+}
diff --git a/src/main/java/com/bwssystems/HABridge/api/CallItem.java b/src/main/java/com/bwssystems/HABridge/api/CallItem.java
index 9495cde..a69dc57 100644
--- a/src/main/java/com/bwssystems/HABridge/api/CallItem.java
+++ b/src/main/java/com/bwssystems/HABridge/api/CallItem.java
@@ -1,11 +1,11 @@
package com.bwssystems.HABridge.api;
public class CallItem {
- private String type;
- private String requesterAddress;
private String item;
private Integer count;
private Integer delay;
+ private String type;
+ private String requesterAddress;
public String getType() {
return type;
diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
index 51350ee..4ee0478 100644
--- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
+++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
@@ -1,6 +1,7 @@
package com.bwssystems.HABridge.hue;
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
+import com.bwssystems.HABridge.DeviceMapTypes;
import com.bwssystems.HABridge.api.CallItem;
import com.bwssystems.HABridge.api.CallItemDeserializer;
import com.bwssystems.HABridge.api.NameValue;
@@ -749,7 +750,9 @@ public class HueMulator implements HueErrorStringSet {
state.setBri(0);
}
}
- if(!(device.getMapType() != null && device.getMapType().equalsIgnoreCase("hueDevice"))) {
+
+ // code for backwards compatibility
+ if(!(device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE))) {
if(url == null)
url = device.getOnUrl();
}
@@ -774,15 +777,25 @@ public class HueMulator implements HueErrorStringSet {
}
Integer setCount = 1;
for (int i = 0; callItems != null && i < callItems.length; i++) {
+ if(!filterByRequester(callItems[i].getRequesterAddress(), request.ip())) {
+ log.debug("filter for requester address not present in list: " + callItems[i].getRequesterAddress() + " with request ip of: " + request.ip());
+ continue;
+ }
if (callItems[i].getCount() != null && callItems[i].getCount() > 0)
setCount = callItems[i].getCount();
else
setCount = 1;
+ // code for backwards compatibility
+ if((callItems[i].getType() == null || callItems[i].getType().trim().length() == 0) && (device.getMapType() != null && device.getMapType().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
+ callItems[i].setType(DeviceMapTypes.CUSTOM_DEVICE);
+ }
- if((callItems[i].getType() == null || callItems[i].getType().trim().length() == 0) && (device.getMapType() != null && device.getMapType().trim().length() > 0))
- callItems[i].setType(device.getMapType());
-
- if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase("hueDevice")) {
+ if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE)) {
if (myHueHome != null) {
HueDeviceIdentifier deviceId = new Gson().fromJson(callItems[i].getItem(), HueDeviceIdentifier.class);
@@ -796,55 +809,50 @@ public class HueMulator implements HueErrorStringSet {
}
// make call
- responseString = doHttpRequest(
- "http://" + deviceId.getIpAddress() + "/api/" + myHueHome.getTheHUERegisteredUser()
- + "/lights/" + deviceId.getDeviceId() + "/state",
- HttpPut.METHOD_NAME, device.getContentType(), request.body(), null);
+ for (int x = 0; x < setCount; x++) {
+ if (x > 0 || i > 0) {
+ Thread.sleep(theDelay);
+ }
+ if (callItems[i].getDelay() != null && callItems[i].getDelay() > 0)
+ theDelay = callItems[i].getDelay();
+ else
+ theDelay = bridgeSettings.getButtonsleep();
+ responseString = doHttpRequest(
+ "http://" + deviceId.getIpAddress() + "/api/" + myHueHome.getTheHUERegisteredUser()
+ + "/lights/" + deviceId.getDeviceId() + "/state",
+ HttpPut.METHOD_NAME, device.getContentType(), request.body(), null);
+ if (responseString.contains("[{\"error\":"))
+ x = setCount;
+ }
if (responseString == null) {
log.warn("Error on calling url to change device state: " + url);
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling HUE to change device state\", \"parameter\": \"/lights/"
+ lightId + "state\"}}]";
- } else if (responseString.contains("[{\"error\":")
- && responseString.contains("unauthorized user")) {
- myHueHome.setTheHUERegisteredUser(null);
- hueUser = HueUtil.registerWithHue(httpClient, deviceId.getIpAddress(), device.getName(),
- myHueHome.getTheHUERegisteredUser(), this);
- if (hueUser == null) {
- return errorString;
+ } else if (responseString.contains("[{\"error\":")) {
+ if(responseString.contains("unauthorized user")) {
+ myHueHome.setTheHUERegisteredUser(null);
+ hueUser = HueUtil.registerWithHue(httpClient, deviceId.getIpAddress(), device.getName(),
+ myHueHome.getTheHUERegisteredUser(), this);
+ if (hueUser == null) {
+ return errorString;
+ }
+ myHueHome.setTheHUERegisteredUser(hueUser);
}
- myHueHome.setTheHUERegisteredUser(hueUser);
+ else
+ log.warn("Error occurred when calling Hue Passthru: " + responseString);
}
- } else
+ } else {
+ log.warn("No HUE home configured for HUE device passthru call for deviceID: " + device.getId());
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"No HUE configured\", \"parameter\": \"/lights/" + lightId
+ "state\"}}]";
- } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase("harmonyActivity")) {
+ }
+ } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.HARMONY_ACTIVITY)) {
log.debug("executing HUE api request to change activity to Harmony: " + url);
if (myHarmonyHome != null) {
RunActivity anActivity = new Gson().fromJson(url, RunActivity.class);
HarmonyHandler myHarmony = myHarmonyHome.getHarmonyHandler(device.getTargetDevice());
- if (myHarmony == null) {
- log.warn("Should not get here, no harmony hub available");
- responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
- + "\",\"description\": \"Should not get here, no harmony hub available\", \"parameter\": \"/lights/"
- + lightId + "state\"}}]";
- } else
- myHarmony.startActivity(anActivity);
- } else {
- log.warn("Should not get here, no harmony configured");
- responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
- + "\",\"description\": \"Should not get here, no harmony configured\", \"parameter\": \"/lights/"
- + lightId + "state\"}}]";
- }
- } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase("harmonyButton")) {
- log.debug("executing HUE api request to button press(es) to Harmony: " + url);
- if (myHarmonyHome != null) {
- if (url.substring(0, 1).equalsIgnoreCase("{")) {
- url = "[" + url + "]";
- }
- ButtonPress[] deviceButtons = new Gson().fromJson(url, ButtonPress[].class);
- HarmonyHandler myHarmony = myHarmonyHome.getHarmonyHandler(device.getTargetDevice());
if (myHarmony == null) {
log.warn("Should not get here, no harmony hub available");
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
@@ -859,10 +867,64 @@ public class HueMulator implements HueErrorStringSet {
theDelay = callItems[i].getDelay();
else
theDelay = bridgeSettings.getButtonsleep();
- log.debug("pressing button: " + deviceButtons[i].getDevice() + " - "
- + deviceButtons[i].getButton() + " - iteration: " + String.valueOf(i)
- + " - count: " + String.valueOf(x));
- myHarmony.pressButton(deviceButtons[i]);
+ myHarmony.startActivity(anActivity);
+ }
+ }
+ } else {
+ log.warn("Should not get here, no harmony configured");
+ responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ + "\",\"description\": \"Should not get here, no harmony configured\", \"parameter\": \"/lights/"
+ + lightId + "state\"}}]";
+ }
+ } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.HARMONY_BUTTON)) {
+ log.debug("executing HUE api request to button press(es) to Harmony: " + url);
+ if (myHarmonyHome != null) {
+ if (url.substring(0, 1).equalsIgnoreCase("{")) {
+ url = "[" + url + "]";
+ }
+ ButtonPress[] deviceButtons = new Gson().fromJson(url, ButtonPress[].class);
+ HarmonyHandler myHarmony = myHarmonyHome.getHarmonyHandler(device.getTargetDevice());
+ if (myHarmony == null) {
+ log.warn("Should not get here, no harmony hub available");
+ responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ + "\",\"description\": \"Should not get here, no harmony hub available\", \"parameter\": \"/lights/"
+ + lightId + "state\"}}]";
+ } else {
+ if(deviceButtons.length > 1) {
+ Integer theCount = 1;
+ for(int z = 0; z < deviceButtons.length; z++) {
+ if(deviceButtons[z].getCount() != null && deviceButtons[z].getCount() > 0)
+ theCount = deviceButtons[z].getCount();
+ else
+ theCount = 1;
+ for(int y = 0; y < theCount; y++) {
+ if( y > 0 || z > 0) {
+ Thread.sleep(theDelay);
+ }
+ if(deviceButtons[z].getDelay() != null && deviceButtons[z].getDelay() > 0)
+ theDelay = deviceButtons[z].getDelay();
+ else
+ theDelay = bridgeSettings.getButtonsleep();
+ log.debug("pressing button: " + deviceButtons[z].getDevice() + " - " + deviceButtons[z].getButton() + " - iteration: " + String.valueOf(z) + " - count: " + String.valueOf(y));
+ myHarmony.pressButton(deviceButtons[z]);
+ }
+ }
+ }
+ else {
+ for (int x = 0; x < setCount; x++) {
+ if (x > 0 || i > 0) {
+ Thread.sleep(theDelay);
+ }
+ if (callItems[i].getDelay() != null && callItems[i].getDelay() > 0) {
+ theDelay = callItems[i].getDelay();
+ }
+ else
+ theDelay = bridgeSettings.getButtonsleep();
+ log.debug("pressing button: " + deviceButtons[i].getDevice() + " - "
+ + deviceButtons[i].getButton() + " - iteration: " + String.valueOf(i)
+ + " - count: " + String.valueOf(x));
+ myHarmony.pressButton(deviceButtons[i]);
+ }
}
}
} else {
@@ -872,7 +934,7 @@ public class HueMulator implements HueErrorStringSet {
+ lightId + "state\"}}]";
}
- } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase("nestHomeAway")) {
+ } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.NEST_HOMEAWAY)) {
log.debug("executing HUE api request to set away for nest home: " + url);
if (theNest == null) {
log.warn("Should not get here, no Nest available");
@@ -883,7 +945,7 @@ public class HueMulator implements HueErrorStringSet {
NestInstruction homeAway = new Gson().fromJson(url, NestInstruction.class);
theNest.getHome(homeAway.getName()).setAway(homeAway.getAway());
}
- } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase("nestThermoSet")) {
+ } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.NEST_THERMO_SET)) {
log.debug("executing HUE api request to set thermostat for nest: " + url);
if (theNest == null) {
log.warn("Should not get here, no Nest available");
@@ -934,7 +996,7 @@ public class HueMulator implements HueErrorStringSet {
+ lightId + "state\"}}]";
}
}
- } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase("mqttMessage")) {
+ } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.MQTT_MESSAGE)) {
log.debug("executing HUE api request to send message to MQTT broker: " + url);
if (mqttHome != null) {
MQTTMessage[] mqttMessages = new Gson().fromJson(url, MQTTMessage[].class);
@@ -965,8 +1027,13 @@ public class HueMulator implements HueErrorStringSet {
+ lightId + "state\"}}]";
}
- } else if (callItems[i].getType() != null && callItems[i].getType().trim().startsWith("exec")) {
+ } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.EXEC_DEVICE)) {
log.debug("Exec Request called with url: " + url);
+ String intermediate;
+ if (callItems[i].getItem().contains("exec://"))
+ intermediate = callItems[i].getItem().substring(callItems[i].getItem().indexOf("://") + 3);
+ else
+ intermediate = callItems[i].getItem();
for (int x = 0; x < setCount; x++) {
if (x > 0 || i > 0) {
Thread.sleep(theDelay);
@@ -975,16 +1042,11 @@ public class HueMulator implements HueErrorStringSet {
theDelay = callItems[i].getDelay();
else
theDelay = bridgeSettings.getButtonsleep();
- String intermediate;
- if (callItems[i].getItem().contains("exec://"))
- intermediate = callItems[i].getItem().substring(callItems[i].getItem().indexOf("://") + 3);
- else
- intermediate = callItems[i].getItem();
String anError = doExecRequest(intermediate,
calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), lightId);
if (anError != null) {
responseString = anError;
- i = callItems.length + 1;
+ x = setCount;
}
}
} else // This section allows the usage of http/tcp/udp/exec
@@ -1014,7 +1076,7 @@ public class HueMulator implements HueErrorStringSet {
} else
hostAddr = hostPortion;
InetAddress IPAddress = InetAddress.getByName(hostAddr);
- ;
+
if (theUrlBody.startsWith("0x")) {
theUrlBody = replaceIntensityValue(theUrlBody,
calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc),
@@ -1047,7 +1109,7 @@ public class HueMulator implements HueErrorStringSet {
lightId);
if (anError != null) {
responseString = anError;
- i = callItems.length + 1;
+ x = setCount;
}
} else {
log.debug("executing HUE api request to Http "
@@ -1076,7 +1138,7 @@ public class HueMulator implements HueErrorStringSet {
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling url to change device state\", \"parameter\": \"/lights/"
+ lightId + "state\"}}]";
- i = callItems.length + 1;
+ x = setCount;
}
}
} catch (Exception e) {
@@ -1085,7 +1147,7 @@ public class HueMulator implements HueErrorStringSet {
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/"
+ lightId + "state\"}}]";
- i = callItems.length + 1;
+ x = setCount;
}
}
}
@@ -1477,4 +1539,22 @@ public class HueMulator implements HueErrorStringSet {
public void setErrorString(String anError) {
errorString = anError;
}
+
+ private Boolean filterByRequester(String requesterFilterList, String anAddress) {
+ if (requesterFilterList == null || requesterFilterList.length() == 0)
+ return true;
+
+ HashMap addressMap;
+ addressMap = new HashMap();
+ if (requesterFilterList.contains(",")) {
+ String[] theArray = requesterFilterList.split(",");
+ for (String v : theArray) {
+ addressMap.put(v.trim(), v.trim());
+ }
+ } else
+ addressMap.put(requesterFilterList.trim(), requesterFilterList.trim());
+ if (addressMap.containsKey(anAddress))
+ return true;
+ return false;
+ }
}