mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-18 00:10:20 +00:00
Added hex color codes, added swith to utilize groups/rooms. updated exec
to use new path parsing. Revert back to Spark 2.3 due to issues.
This commit is contained in:
4
pom.xml
4
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.bwssystems.HABridge</groupId>
|
<groupId>com.bwssystems.HABridge</groupId>
|
||||||
<artifactId>ha-bridge</artifactId>
|
<artifactId>ha-bridge</artifactId>
|
||||||
<version>5.0.0</version>
|
<version>5.0.0a</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>HA Bridge</name>
|
<name>HA Bridge</name>
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sparkjava</groupId>
|
<groupId>com.sparkjava</groupId>
|
||||||
<artifactId>spark-core</artifactId>
|
<artifactId>spark-core</artifactId>
|
||||||
<version>2.7.1</version>
|
<version>2.3</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<artifactId>slf4j-simple</artifactId>
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
|||||||
@@ -238,6 +238,31 @@ public class BridgeSecurity {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String findWhitelistUserByDeviceType(String aDeviceType) {
|
||||||
|
String validUser = null;
|
||||||
|
boolean found = false;
|
||||||
|
WhitelistEntry anEntry = null;
|
||||||
|
if (aDeviceType != null) {
|
||||||
|
if (securityDescriptor.getWhitelist() != null) {
|
||||||
|
Set<String> theUserIds = securityDescriptor.getWhitelist().keySet();
|
||||||
|
Iterator<String> userIterator = theUserIds.iterator();
|
||||||
|
while (!found && userIterator.hasNext()) {
|
||||||
|
validUser = userIterator.next();
|
||||||
|
anEntry = securityDescriptor.getWhitelist().get(validUser);
|
||||||
|
if (anEntry.getName().equals(aDeviceType)) {
|
||||||
|
found = true;
|
||||||
|
log.debug("findWhitelistUserByDeviceType: found a user <" + validUser + "> for device type <" + aDeviceType + ">");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found)
|
||||||
|
validUser = null;
|
||||||
|
|
||||||
|
return validUser;
|
||||||
|
}
|
||||||
|
|
||||||
private void newWhitelistUser(String aUser, String userDescription) {
|
private void newWhitelistUser(String aUser, String userDescription) {
|
||||||
if (securityDescriptor.getWhitelist() == null) {
|
if (securityDescriptor.getWhitelist() == null) {
|
||||||
securityDescriptor.setWhitelist(new HashMap<>());
|
securityDescriptor.setWhitelist(new HashMap<>());
|
||||||
@@ -250,8 +275,14 @@ public class BridgeSecurity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String createWhitelistUser(String userDescription) {
|
public String createWhitelistUser(String userDescription) {
|
||||||
String aUser = getNewUserID();
|
String aUser = null;
|
||||||
newWhitelistUser(aUser, userDescription);
|
String theEntry = findWhitelistUserByDeviceType(userDescription);
|
||||||
|
if(theEntry == null) {
|
||||||
|
aUser = getNewUserID();
|
||||||
|
newWhitelistUser(aUser, userDescription);
|
||||||
|
} else {
|
||||||
|
aUser = theEntry;
|
||||||
|
}
|
||||||
return aUser;
|
return aUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ public class BridgeSettingsDescriptor {
|
|||||||
@SerializedName("useupnpiface")
|
@SerializedName("useupnpiface")
|
||||||
@Expose
|
@Expose
|
||||||
private boolean useupnpiface;
|
private boolean useupnpiface;
|
||||||
|
@SerializedName("userooms")
|
||||||
|
@Expose
|
||||||
|
private boolean userooms;
|
||||||
@SerializedName("serverport")
|
@SerializedName("serverport")
|
||||||
@Expose
|
@Expose
|
||||||
private Integer serverport;
|
private Integer serverport;
|
||||||
@@ -119,6 +122,7 @@ public class BridgeSettingsDescriptor {
|
|||||||
super();
|
super();
|
||||||
this.upnpstrict = true;
|
this.upnpstrict = true;
|
||||||
this.useupnpiface = false;
|
this.useupnpiface = false;
|
||||||
|
this.userooms = false;
|
||||||
this.traceupnp = false;
|
this.traceupnp = false;
|
||||||
this.nestconfigured = false;
|
this.nestconfigured = false;
|
||||||
this.veraconfigured = false;
|
this.veraconfigured = false;
|
||||||
@@ -152,6 +156,12 @@ public class BridgeSettingsDescriptor {
|
|||||||
public void setUseupnpiface(boolean useupnpiface) {
|
public void setUseupnpiface(boolean useupnpiface) {
|
||||||
this.useupnpiface = useupnpiface;
|
this.useupnpiface = useupnpiface;
|
||||||
}
|
}
|
||||||
|
public boolean isUserooms() {
|
||||||
|
return userooms;
|
||||||
|
}
|
||||||
|
public void setUserooms(boolean userooms) {
|
||||||
|
this.userooms = userooms;
|
||||||
|
}
|
||||||
public Integer getServerPort() {
|
public Integer getServerPort() {
|
||||||
return serverport;
|
return serverport;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class HABridge {
|
|||||||
// sparkjava config directive to set port for the web server to listen on
|
// sparkjava config directive to set port for the web server to listen on
|
||||||
port(bridgeSettings.getBridgeSettingsDescriptor().getServerPort());
|
port(bridgeSettings.getBridgeSettingsDescriptor().getServerPort());
|
||||||
staticFileLocation("/public");
|
staticFileLocation("/public");
|
||||||
initExceptionHandler((e) -> HABridge.theExceptionHandler(e, bridgeSettings.getBridgeSettingsDescriptor().getServerPort()));
|
// initExceptionHandler((e) -> HABridge.theExceptionHandler(e, bridgeSettings.getBridgeSettingsDescriptor().getServerPort()));
|
||||||
if(!bridgeSettings.getBridgeControl().isReinit())
|
if(!bridgeSettings.getBridgeControl().isReinit())
|
||||||
init();
|
init();
|
||||||
bridgeSettings.getBridgeControl().setReinit(false);
|
bridgeSettings.getBridgeControl().setReinit(false);
|
||||||
|
|||||||
@@ -48,7 +48,10 @@ public class DeviceResource {
|
|||||||
public DeviceResource(BridgeSettings theSettings, HomeManager aHomeManager) {
|
public DeviceResource(BridgeSettings theSettings, HomeManager aHomeManager) {
|
||||||
bridgeSettings = theSettings;
|
bridgeSettings = theSettings;
|
||||||
this.deviceRepository = new DeviceRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpDeviceDb());
|
this.deviceRepository = new DeviceRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpDeviceDb());
|
||||||
this.groupRepository = new GroupRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpGroupDb());
|
if(bridgeSettings.getBridgeSettingsDescriptor().isUserooms())
|
||||||
|
this.groupRepository = new GroupRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpGroupDb());
|
||||||
|
else
|
||||||
|
this.groupRepository = null;
|
||||||
homeManager = aHomeManager;
|
homeManager = aHomeManager;
|
||||||
aGsonHandler = new GsonBuilder().create();
|
aGsonHandler = new GsonBuilder().create();
|
||||||
setupEndpoints();
|
setupEndpoints();
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ public class ColorDecode {
|
|||||||
private static final String COLOR_R = "${color.r}";
|
private static final String COLOR_R = "${color.r}";
|
||||||
private static final String COLOR_G = "${color.g}";
|
private static final String COLOR_G = "${color.g}";
|
||||||
private static final String COLOR_B = "${color.b}";
|
private static final String COLOR_B = "${color.b}";
|
||||||
|
private static final String COLOR_RX = "${color.rx}";
|
||||||
|
private static final String COLOR_GX = "${color.gx}";
|
||||||
|
private static final String COLOR_BX = "${color.bx}";
|
||||||
|
private static final String COLOR_RGBX = "${color.rgbx}";
|
||||||
private static final Pattern COLOR_MILIGHT = Pattern.compile("\\$\\{color.milight\\:([01234])\\}");
|
private static final Pattern COLOR_MILIGHT = Pattern.compile("\\$\\{color.milight\\:([01234])\\}");
|
||||||
|
|
||||||
public static List<Integer> convertCIEtoRGB(List<Double> xy, int brightness) {
|
public static List<Integer> convertCIEtoRGB(List<Double> xy, int brightness) {
|
||||||
@@ -175,6 +179,26 @@ public class ColorDecode {
|
|||||||
notDone = true;
|
notDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (request.contains(COLOR_RX)) {
|
||||||
|
request = request.replace(COLOR_RX, String.format("%02X", rgb.get(0)));
|
||||||
|
notDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.contains(COLOR_GX)) {
|
||||||
|
request = request.replace(COLOR_GX, String.format("%02X", rgb.get(1)));
|
||||||
|
notDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.contains(COLOR_BX)) {
|
||||||
|
request = request.replace(COLOR_BX, String.format("%02X", rgb.get(2)));
|
||||||
|
notDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.contains(COLOR_RGBX)) {
|
||||||
|
request = request.replace(COLOR_RGBX, String.format("%02X%02X%02X", rgb.get(0), rgb.get(1), rgb.get(2)));
|
||||||
|
notDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
Matcher m = COLOR_MILIGHT.matcher(request);
|
Matcher m = COLOR_MILIGHT.matcher(request);
|
||||||
while (m.find()) {
|
while (m.find()) {
|
||||||
int group = Integer.parseInt(m.group(1));
|
int group = Integer.parseInt(m.group(1));
|
||||||
|
|||||||
@@ -127,7 +127,12 @@ public class HueMulator {
|
|||||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||||
response.type("application/json");
|
response.type("application/json");
|
||||||
response.status(HttpStatus.SC_OK);
|
response.status(HttpStatus.SC_OK);
|
||||||
return addGroup(request.params(":userid"), request.ip(), request.body());
|
if(bridgeSettings.isUserooms()) {
|
||||||
|
return addGroup(request.params(":userid"), request.ip(), request.body());
|
||||||
|
} else {
|
||||||
|
log.debug("group add requested from (No Use Rooms) " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||||
|
return "[{\"success\":{\"id\":\"1\"}}]";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// http://ip_address:port/api/:userid/groups/<groupid>
|
// http://ip_address:port/api/:userid/groups/<groupid>
|
||||||
// delete a group
|
// delete a group
|
||||||
@@ -135,7 +140,12 @@ public class HueMulator {
|
|||||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||||
response.type("application/json");
|
response.type("application/json");
|
||||||
response.status(HttpStatus.SC_OK);
|
response.status(HttpStatus.SC_OK);
|
||||||
return deleteGroup(request.params(":userid"), request.params(":groupid"), request.ip());
|
if(bridgeSettings.isUserooms()) {
|
||||||
|
return deleteGroup(request.params(":userid"), request.params(":groupid"), request.ip());
|
||||||
|
} else {
|
||||||
|
log.debug("delete to groups API from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||||
|
return "[{\"error\":{\"address\": \"/groups/0/action/scene\", \"type\":7, \"description\": \"invalid value, dummy for parameter, scene\"}}]";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// http://ip_address:port/api/:userid/groups/<groupid>
|
// http://ip_address:port/api/:userid/groups/<groupid>
|
||||||
// modify a single group
|
// modify a single group
|
||||||
@@ -143,7 +153,12 @@ public class HueMulator {
|
|||||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||||
response.type("application/json");
|
response.type("application/json");
|
||||||
response.status(HttpStatus.SC_OK);
|
response.status(HttpStatus.SC_OK);
|
||||||
return modifyGroup(request.params(":userid"), request.params(":groupid"), request.ip(), request.body());
|
if(bridgeSettings.isUserooms()) {
|
||||||
|
return modifyGroup(request.params(":userid"), request.params(":groupid"), request.ip(), request.body());
|
||||||
|
} else {
|
||||||
|
log.debug("put to groups API from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||||
|
return "[{\"error\":{\"address\": \"/groups/0/action/scene\", \"type\":7, \"description\": \"invalid value, dummy for parameter, scene\"}}]";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// http://ip_address:port/api/:userid/groups/<groupid>/action
|
// http://ip_address:port/api/:userid/groups/<groupid>/action
|
||||||
// group acions
|
// group acions
|
||||||
@@ -151,7 +166,12 @@ public class HueMulator {
|
|||||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||||
response.type("application/json");
|
response.type("application/json");
|
||||||
response.status(HttpStatus.SC_OK);
|
response.status(HttpStatus.SC_OK);
|
||||||
return changeGroupState(request.params(":userid"), request.params(":groupid"), request.body(), request.ip(), false);
|
if(bridgeSettings.isUserooms()) {
|
||||||
|
return changeGroupState(request.params(":userid"), request.params(":groupid"), request.body(), request.ip(), false);
|
||||||
|
} else {
|
||||||
|
log.debug("put action to groups API from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||||
|
return "[{\"error\":{\"address\": \"/groups/0/action/scene\", \"type\":7, \"description\": \"invalid value, dummy for parameter, scene\"}}]";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// http://ip_address:port/api/{userId}/scenes returns json objects of
|
// http://ip_address:port/api/{userId}/scenes returns json objects of
|
||||||
// all scenes configured
|
// all scenes configured
|
||||||
@@ -922,7 +942,7 @@ public class HueMulator {
|
|||||||
toContinue = true;
|
toContinue = true;
|
||||||
|
|
||||||
if(toContinue) {
|
if(toContinue) {
|
||||||
log.debug("hue api user create requested: " + body + " from " + ipAddress);
|
log.debug("user add toContinue was true, creating user.");
|
||||||
|
|
||||||
if (body != null && !body.isEmpty()) {
|
if (body != null && !body.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
@@ -938,6 +958,8 @@ public class HueMulator {
|
|||||||
|
|
||||||
if (aDeviceType == null)
|
if (aDeviceType == null)
|
||||||
aDeviceType = "<not given>";
|
aDeviceType = "<not given>";
|
||||||
|
else
|
||||||
|
aDeviceType = aDeviceType + "#" + ipAddress;
|
||||||
|
|
||||||
if (newUser == null) {
|
if (newUser == null) {
|
||||||
newUser = bridgeSettingMaster.getBridgeSecurity().createWhitelistUser(aDeviceType);
|
newUser = bridgeSettingMaster.getBridgeSecurity().createWhitelistUser(aDeviceType);
|
||||||
@@ -1084,7 +1106,7 @@ public class HueMulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String changeState(String userId, String lightId, String body, String ipAddress, boolean ignoreRequester) {
|
private String changeState(String userId, String lightId, String body, String ipAddress, boolean ignoreRequester) {
|
||||||
if (Integer.parseInt(lightId) >= 10000) {
|
if (bridgeSettings.isUserooms() && Integer.parseInt(lightId) >= 10000) {
|
||||||
return changeGroupState(userId, String.valueOf(Integer.parseInt(lightId) - 10000), body, ipAddress, true);
|
return changeGroupState(userId, String.valueOf(Integer.parseInt(lightId) - 10000), body, ipAddress, true);
|
||||||
}
|
}
|
||||||
String responseString = null;
|
String responseString = null;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.bwssystems.HABridge.plugins.exec;
|
package com.bwssystems.HABridge.plugins.exec;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -45,10 +46,7 @@ public class CommandHome implements Home {
|
|||||||
intermediate = TimeDecode.replaceTimeValue(intermediate);
|
intermediate = TimeDecode.replaceTimeValue(intermediate);
|
||||||
String execGarden = theSettings.getBridgeSecurity().getExecGarden();
|
String execGarden = theSettings.getBridgeSecurity().getExecGarden();
|
||||||
if(execGarden != null && !execGarden.trim().isEmpty()) {
|
if(execGarden != null && !execGarden.trim().isEmpty()) {
|
||||||
if(System.getProperty("os.name").toLowerCase().indexOf("win") >= 0)
|
intermediate = new File(execGarden.trim(), intermediate).getAbsolutePath();
|
||||||
intermediate = execGarden + "\\" + intermediate;
|
|
||||||
else
|
|
||||||
intermediate = execGarden + "/" + intermediate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String anError = doExecRequest(intermediate, lightId);
|
String anError = doExecRequest(intermediate, lightId);
|
||||||
|
|||||||
@@ -2068,7 +2068,7 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n
|
|||||||
onpayload = "http://" + fibarodevice.fibaroaddress + ":" + fibarodevice.fibaroport + "/api/callAction?deviceID=" + fibarodevice.id + "&name=turnOn";
|
onpayload = "http://" + fibarodevice.fibaroaddress + ":" + fibarodevice.fibaroport + "/api/callAction?deviceID=" + fibarodevice.id + "&name=turnOn";
|
||||||
offpayload = "http://" + fibarodevice.fibaroaddress + ":" + fibarodevice.fibaroport + "/api/callAction?deviceID=" + fibarodevice.id + "&name=turnOff";
|
offpayload = "http://" + fibarodevice.fibaroaddress + ":" + fibarodevice.fibaroport + "/api/callAction?deviceID=" + fibarodevice.id + "&name=turnOff";
|
||||||
|
|
||||||
bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, fibarodevice.id, fibarodevice.name, fibarodevice.fibaroname, "switch", "fibaroDevice", null, null);
|
bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, fibarodevice.id, fibarodevice.name, fibarodevice.fibaroname, "switch", "fibaroDevice", null, null);
|
||||||
bridgeService.state.device.headers = "[{\"name\":\"Authorization\",\"value\":\"" + fibarodevice.fibaroAuth + "\"}]";
|
bridgeService.state.device.headers = "[{\"name\":\"Authorization\",\"value\":\"" + fibarodevice.fibaroAuth + "\"}]";
|
||||||
$scope.device = bridgeService.state.device;
|
$scope.device = bridgeService.state.device;
|
||||||
if (!buildonly) {
|
if (!buildonly) {
|
||||||
@@ -2081,7 +2081,7 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n
|
|||||||
onpayload = "http://" + fibaroscene.fibaroaddress + ":" + fibaroscene.fibaroport + "/api/sceneControl?id=" + fibaroscene.id + "&action=start";
|
onpayload = "http://" + fibaroscene.fibaroaddress + ":" + fibaroscene.fibaroport + "/api/sceneControl?id=" + fibaroscene.id + "&action=start";
|
||||||
offpayload = "http://" + fibaroscene.fibaroaddress + ":" + fibaroscene.fibaroport + "/api/sceneControl?id=" + fibaroscene.id + "&action=stop";
|
offpayload = "http://" + fibaroscene.fibaroaddress + ":" + fibaroscene.fibaroport + "/api/sceneControl?id=" + fibaroscene.id + "&action=stop";
|
||||||
|
|
||||||
bridgeService.buildUrls(onpayload, null, offpayload, false, fibaroscene.id, fibaroscene.name, fibaroscene.fibaroname, "scene", "fibaroScene", null, null);
|
bridgeService.buildUrls(onpayload, null, offpayload, null, false, fibaroscene.id, fibaroscene.name, fibaroscene.fibaroname, "scene", "fibaroScene", null, null);
|
||||||
bridgeService.state.device.headers = "[{\"name\":\"Authorization\",\"value\":\"" + fibaroscene.fibaroAuth + "\"}]";
|
bridgeService.state.device.headers = "[{\"name\":\"Authorization\",\"value\":\"" + fibaroscene.fibaroAuth + "\"}]";
|
||||||
$scope.device = bridgeService.state.device;
|
$scope.device = bridgeService.state.device;
|
||||||
bridgeService.editNewDevice($scope.device);
|
bridgeService.editNewDevice($scope.device);
|
||||||
|
|||||||
@@ -100,6 +100,12 @@
|
|||||||
ng-model="bridge.settings.useupnpiface" ng-true-value=true
|
ng-model="bridge.settings.useupnpiface" ng-true-value=true
|
||||||
ng-false-value=false> {{bridge.settings.useupnpiface}}</td>
|
ng-false-value=false> {{bridge.settings.useupnpiface}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Use Rooms for Alexa</td>
|
||||||
|
<td><input type="checkbox"
|
||||||
|
ng-model="bridge.settings.userooms" ng-true-value=true
|
||||||
|
ng-false-value=false> {{bridge.settings.userooms}}</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Web Server IP Address</td>
|
<td>Web Server IP Address</td>
|
||||||
<td><input id="bridge-settings-webaddress"
|
<td><input id="bridge-settings-webaddress"
|
||||||
|
|||||||
Reference in New Issue
Block a user