v4.1.0 Added feature for Domoticz and fixed some major bugs, ie: mqtt,

and some enhancements.
This commit is contained in:
Admin
2017-01-27 15:11:30 -06:00
parent 611cc7be4a
commit b5e6e3ad60
28 changed files with 339 additions and 127 deletions

View File

@@ -5,7 +5,7 @@
<groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId>
<version>4.1.0beta5</version>
<version>4.1.0</version>
<packaging>jar</packaging>

View File

@@ -70,6 +70,7 @@ public class HomeManager {
homeList.put(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex], aHome);
homeList.put(DeviceMapTypes.VERA_DEVICE[DeviceMapTypes.typeIndex], aHome);
homeList.put(DeviceMapTypes.VERA_SCENE[DeviceMapTypes.typeIndex], aHome);
homeList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome);
//setup the tcp handler Home
aHome = new TCPHome(bridgeSettings);
homeList.put(DeviceMapTypes.TCP_DEVICE[DeviceMapTypes.typeIndex], aHome);
@@ -85,7 +86,6 @@ public class HomeManager {
//setup the HomeAssistant configuration if available
aHome = new DomoticzHome(bridgeSettings);
resourceList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome);
homeList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome);
}
public Home findHome(String type) {

View File

@@ -3,11 +3,20 @@ package com.bwssystems.HABridge.api.hue;
import java.util.List;
import com.bwssystems.HABridge.dao.DeviceDescriptor;
import com.google.gson.annotations.SerializedName;
public class GroupResponse {
@SerializedName("action")
private DeviceState action;
@SerializedName("lights")
private String[] lights;
@SerializedName("name")
private String name;
@SerializedName("type")
private String type;
@SerializedName("class")
String class_name;
public DeviceState getAction() {
return action;
}
@@ -27,7 +36,19 @@ public class GroupResponse {
this.name = name;
}
public static GroupResponse createGroupResponse(List<DeviceDescriptor> deviceList) {
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getClass_name() {
return class_name;
}
public void setClass_name(String class_name) {
this.class_name = class_name;
}
public static GroupResponse createDefaultGroupResponse(List<DeviceDescriptor> deviceList) {
String[] theList = new String[deviceList.size()];
int i = 0;
for (DeviceDescriptor device : deviceList) {
@@ -38,6 +59,23 @@ public class GroupResponse {
theResponse.setAction(DeviceState.createDeviceState());
theResponse.setName("Lightset 0");
theResponse.setLights(theList);
theResponse.setType("LightGroup");
return theResponse;
}
public static GroupResponse createOtherGroupResponse(List<DeviceDescriptor> deviceList) {
String[] theList = new String[deviceList.size()];
int i = 0;
for (DeviceDescriptor device : deviceList) {
theList[i] = device.getId();
i++;
}
GroupResponse theResponse = new GroupResponse();
theResponse.setAction(DeviceState.createDeviceState());
theResponse.setName("AGroup");
theResponse.setLights(theList);
theResponse.setType("Room");
theResponse.setClass_name("Other");
return theResponse;
}
}

View File

@@ -12,7 +12,7 @@ import com.google.gson.JsonObject;
public class HueApiResponse {
private Map<String, DeviceResponse> lights;
private Map<String, JsonObject> scenes;
private Map<String, JsonObject> groups;
private Map<String, GroupResponse> groups;
private Map<String, JsonObject> schedules;
private Map<String, JsonObject> sensors;
private Map<String, JsonObject> rules;
@@ -44,11 +44,11 @@ public class HueApiResponse {
this.scenes = scenes;
}
public Map<String, JsonObject> getGroups() {
public Map<String, GroupResponse> getGroups() {
return groups;
}
public void setGroups(Map<String, JsonObject> groups) {
public void setGroups(Map<String, GroupResponse> groups) {
this.groups = groups;
}

View File

@@ -1,7 +1,7 @@
package com.bwssystems.HABridge.api.hue;
public class HueConstants {
public final static String HUB_VERSION = "01036562";
public final static String HUB_VERSION = "01036659";
public final static String API_VERSION = "1.15.0";
public final static String MODEL_ID = "BSB002";
public final static String UUID_PREFIX = "2f402f80-da50-11e1-9b23-";

View File

@@ -58,7 +58,10 @@ public class DeviceDescriptor{
private String contentBodyDim;
@SerializedName("inactive")
@Expose
private Boolean inactive;
private boolean inactive;
@SerializedName("noState")
@Expose
private boolean noState;
private DeviceState deviceState;
@@ -200,12 +203,38 @@ public class DeviceDescriptor{
this.deviceState = deviceState;
}
public Boolean getInactive() {
public boolean isInactive() {
return inactive;
}
public void setInactive(Boolean inactive) {
public void setInactive(boolean inactive) {
this.inactive = inactive;
}
}
public boolean isNoState() {
return noState;
}
public void setNoState(boolean noState) {
this.noState = noState;
}
public boolean containsType(String aType) {
if(this.mapType.contains(aType))
return true;
if(this.deviceType.contains(aType))
return true;
if(this.onUrl.contains(aType))
return true;
if(this.dimUrl.contains(aType))
return true;
if(this.offUrl.contains(aType))
return true;
return false;
}
}

View File

@@ -77,7 +77,7 @@ public class DeviceRepository extends BackupHandler {
public List<DeviceDescriptor> findActive() {
List<DeviceDescriptor> list = new ArrayList<DeviceDescriptor>();
for(DeviceDescriptor aDevice : new ArrayList<DeviceDescriptor>(devices.values())) {
if(aDevice.getInactive() == null || !aDevice.getInactive())
if(!aDevice.isInactive())
list.add(aDevice);
}
return list;

View File

@@ -9,6 +9,7 @@ import com.bwssystems.HABridge.api.hue.DeviceResponse;
import com.bwssystems.HABridge.api.hue.DeviceState;
import com.bwssystems.HABridge.api.hue.GroupResponse;
import com.bwssystems.HABridge.api.hue.HueApiResponse;
import com.bwssystems.HABridge.api.hue.HueConfig;
import com.bwssystems.HABridge.api.hue.HueError;
import com.bwssystems.HABridge.api.hue.HueErrorResponse;
import com.bwssystems.HABridge.api.hue.HuePublicConfig;
@@ -73,16 +74,34 @@ public class HueMulator {
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json");
response.status(HttpStatus.SC_OK);
return basicListHandler("groups", request.params(":userid"), request.ip());
});
return groupsListHandler(request.params(":userid"), request.ip());
} , new JsonTransformer());
// http://ip_address:port/api/{userId}/groups/{groupId} returns json
// object for specified group. Only 0 is supported
get(HUE_CONTEXT + "/:userid/groups/:groupid", "application/json", (request, response) -> {
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json");
response.status(HttpStatus.SC_OK);
return groupsListHandler(request.params(":groupid"), request.params(":userid"), request.ip());
return groupsIdHandler(request.params(":groupid"), request.params(":userid"), request.ip());
} , new JsonTransformer());
// http://ip_address:port/:userid/groups CORS request
options(HUE_CONTEXT + "/:userid/groups", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html");
return "";
});
// http://ip_address:port/:userid/groups
// dummy handler
post(HUE_CONTEXT + "/:userid/groups", "application/json", (request, response) -> {
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json");
response.status(HttpStatus.SC_OK);
log.debug("group add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
return "[{\"success\":{\"id\":\"1\"}}]";
});
// http://ip_address:port/api/{userId}/scenes returns json objects of
// all scenes configured
get(HUE_CONTEXT + "/:userid/scenes", "application/json", (request, response) -> {
@@ -91,6 +110,24 @@ public class HueMulator {
response.status(HttpStatus.SC_OK);
return basicListHandler("scenes", request.params(":userid"), request.ip());
});
// http://ip_address:port/:userid/scenes CORS request
options(HUE_CONTEXT + "/:userid/scenes", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html");
return "";
});
// http://ip_address:port/:userid/scenes
// dummy handler
post(HUE_CONTEXT + "/:userid/scenes", "application/json", (request, response) -> {
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json");
response.status(HttpStatus.SC_OK);
log.debug("scene add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
return "[{\"success\":{\"id\":\"1\"}}]";
});
// http://ip_address:port/api/{userId}/schedules returns json objects of
// all schedules configured
get(HUE_CONTEXT + "/:userid/schedules", "application/json", (request, response) -> {
@@ -99,6 +136,24 @@ public class HueMulator {
response.status(HttpStatus.SC_OK);
return basicListHandler("schedules", request.params(":userid"), request.ip());
});
// http://ip_address:port/:userid/schedules CORS request
options(HUE_CONTEXT + "/:userid/schedules", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html");
return "";
});
// http://ip_address:port/:userid/schedules
// dummy handler
post(HUE_CONTEXT + "/:userid/schedules", "application/json", (request, response) -> {
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json");
response.status(HttpStatus.SC_OK);
log.debug("schedules add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
return "[{\"success\":{\"id\":\"1\"}}]";
});
// http://ip_address:port/api/{userId}/sensors returns json objects of
// all sensors configured
get(HUE_CONTEXT + "/:userid/sensors", "application/json", (request, response) -> {
@@ -107,6 +162,24 @@ public class HueMulator {
response.status(HttpStatus.SC_OK);
return basicListHandler("sensors", request.params(":userid"), request.ip());
});
// http://ip_address:port/:userid/sensors CORS request
options(HUE_CONTEXT + "/:userid/sensors", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html");
return "";
});
// http://ip_address:port/:userid/sensors
// dummy handler
post(HUE_CONTEXT + "/:userid/sensors", "application/json", (request, response) -> {
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json");
response.status(HttpStatus.SC_OK);
log.debug("sensors add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
return "[{\"success\":{\"id\":\"1\"}}]";
});
// http://ip_address:port/api/{userId}/rules returns json objects of all
// rules configured
get(HUE_CONTEXT + "/:userid/rules", "application/json", (request, response) -> {
@@ -115,6 +188,24 @@ public class HueMulator {
response.status(HttpStatus.SC_OK);
return basicListHandler("rules", request.params(":userid"), request.ip());
});
// http://ip_address:port/:userid/rules CORS request
options(HUE_CONTEXT + "/:userid/rules", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html");
return "";
});
// http://ip_address:port/:userid/rules
// dummy handler
post(HUE_CONTEXT + "/:userid/rules", "application/json", (request, response) -> {
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json");
response.status(HttpStatus.SC_OK);
log.debug("rules add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
return "[{\"success\":{\"id\":\"1\"}}]";
});
// http://ip_address:port/api/{userId}/resourcelinks returns json
// objects of all resourcelinks configured
get(HUE_CONTEXT + "/:userid/resourcelinks", "application/json", (request, response) -> {
@@ -123,6 +214,24 @@ public class HueMulator {
response.status(HttpStatus.SC_OK);
return basicListHandler("resourcelinks", request.params(":userid"), request.ip());
});
// http://ip_address:port/:userid/resourcelinks CORS request
options(HUE_CONTEXT + "/:userid/resourcelinks", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html");
return "";
});
// http://ip_address:port/:userid/resourcelinks
// dummy handler
post(HUE_CONTEXT + "/:userid/resourcelinks", "application/json", (request, response) -> {
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json");
response.status(HttpStatus.SC_OK);
log.debug("resourcelinks add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
return "[{\"success\":{\"id\":\"1\"}}]";
});
// http://ip_address:port/api/{userId}/lights returns json objects of
// all lights configured
get(HUE_CONTEXT + "/:userid/lights", "application/json", (request, response) -> {
@@ -194,6 +303,28 @@ public class HueMulator {
response.status(HttpStatus.SC_OK);
return getConfig(request.params(":userid"), request.ip());
} , new JsonTransformer());
// http://ip_address:port/:userid/config CORS request
options(HUE_CONTEXT + "/:userid/config", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html");
return "";
});
// http://ip_address:port/:userid/config uses json
// object to set the config. this is to handle swupdates
put(HUE_CONTEXT + "/:userid/config", "application/json", (request, response) -> {
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json");
response.status(HttpStatus.SC_OK);
log.debug("Config change requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
HueConfig aConfig = aGsonHandler.fromJson(request.body(), HueConfig.class);
if(aConfig.getPortalservices() != null) {
return "[{\"success\":{\"/config/portalservices\":true}}]";
}
return "[{\"success\":{\"/config/name\":\"My bridge\"}}]";
});
// http://ip_address:port/api/{userId} returns json objects for the full
// state
@@ -463,7 +594,7 @@ public class HueMulator {
}
if (!found) {
log.debug("Valudate user, No User supplied");
log.debug("Validate user, No User supplied");
return HueErrorResponse.createResponse("1", "/api/" + aUser, "unauthorized user", null, null, null).getTheErrors();
}
@@ -496,14 +627,32 @@ public class HueMulator {
return "{}";
}
private Object groupsListHandler(String userId, String requestIp) {
log.debug("hue group list requested: " + userId + " from " + requestIp);
HueError[] theErrors = null;
Map<String, GroupResponse> groupResponseMap = null;
theErrors = validateWhitelistUser(userId, false);
if (theErrors == null) {
groupResponseMap = new HashMap<String, GroupResponse>();
groupResponseMap.put("1", (GroupResponse) this.groupsIdHandler("1", userId, requestIp));
return groupResponseMap;
}
private Object groupsListHandler(String groupId, String userId, String requestIp) {
log.debug("hue group 0 list requested: " + userId + " from " + requestIp);
return theErrors;
}
private Object groupsIdHandler(String groupId, String userId, String requestIp) {
log.debug("hue group id: <" + groupId + "> requested: " + userId + " from " + requestIp);
HueError[] theErrors = null;
theErrors = validateWhitelistUser(userId, false);
if (theErrors == null) {
if (groupId.equalsIgnoreCase("0")) {
GroupResponse theResponse = GroupResponse.createGroupResponse(repository.findAll());
GroupResponse theResponse = GroupResponse.createDefaultGroupResponse(repository.findActive());
return theResponse;
}
if (!groupId.equalsIgnoreCase("0")) {
GroupResponse theResponse = GroupResponse.createOtherGroupResponse(repository.findActive());
return theResponse;
}
theErrors = HueErrorResponse.createResponse("3", userId + "/groups/" + groupId, "Object not found", null, null, null).getTheErrors();
@@ -582,7 +731,7 @@ public class HueMulator {
log.info("Traceupnp: hue api/:userid/config config requested: " + userId + " from " + ipAddress);
log.debug("hue api config requested: " + userId + " from " + ipAddress);
if (validateWhitelistUser(userId, true) != null) {
log.debug("Valudate user, No User supplied, returning public config");
log.debug("hue api config requested, No User supplied, returning public config");
HuePublicConfig apiResponse = HuePublicConfig.createConfig("Philips hue",
bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getHubversion());
return apiResponse;
@@ -603,15 +752,8 @@ public class HueMulator {
HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(),
bridgeSettings.getWhitelist(), bridgeSettings.getHubversion());
Object aReturn = this.lightsListHandler(userId, ipAddress);
Map<String, DeviceResponse> deviceList = new HashMap<String, DeviceResponse>();
if(aReturn.getClass() == deviceList.getClass()) {
deviceList = (Map<String, DeviceResponse>) aReturn;
apiResponse.setLights(deviceList);
}
else {
return aReturn;
}
apiResponse.setLights((Map<String, DeviceResponse>) this.lightsListHandler(userId, ipAddress));
apiResponse.setGroups((Map<String, GroupResponse>) this.groupsListHandler(userId, ipAddress));
return apiResponse;
}
@@ -727,8 +869,10 @@ public class HueMulator {
}
state = device.getDeviceState();
if (state == null)
if (state == null) {
state = DeviceState.createDeviceState();
device.setDeviceState(state);
}
if (targetBri != null || targetBriInc != null) {
url = device.getDimUrl();
@@ -816,8 +960,13 @@ public class HueMulator {
}
if (responseString == null || !responseString.contains("[{\"error\":")) {
responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, state, targetBri, targetBriInc);
device.setDeviceState(state);
if(!device.isNoState()) {
responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, state, targetBri, targetBriInc);
device.setDeviceState(state);
} else {
DeviceState dummyState = DeviceState.createDeviceState();
responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, dummyState, targetBri, targetBriInc);
}
}
return responseString;

View File

@@ -13,20 +13,13 @@ import com.bwssystems.HABridge.BridgeSettingsDescriptor;
import com.bwssystems.HABridge.Home;
import com.bwssystems.HABridge.NamedIP;
import com.bwssystems.HABridge.api.CallItem;
import com.bwssystems.HABridge.api.NameValue;
import com.bwssystems.HABridge.api.hue.HueError;
import com.bwssystems.HABridge.api.hue.HueErrorResponse;
import com.bwssystems.HABridge.dao.DeviceDescriptor;
import com.bwssystems.HABridge.hue.BrightnessDecode;
import com.bwssystems.HABridge.hue.MultiCommandUtil;
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
import com.google.gson.Gson;
public class DomoticzHome implements Home {
private static final Logger log = LoggerFactory.getLogger(DomoticzHome.class);
private Map<String, DomoticzHandler> domoticzs;
private Boolean validDomoticz;
private HTTPHandler anHttpHandler;
public DomoticzHome(BridgeSettingsDescriptor bridgeSettings) {
super();
@@ -67,30 +60,14 @@ public class DomoticzHome implements Home {
DomoticzDevice theDevice = devices.next();
theDeviceList.add(theDevice);
}
anHttpHandler = new HTTPHandler();
return true;
}
@Override
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
Integer targetBri,Integer targetBriInc, DeviceDescriptor device, String body) {
log.debug("executing HUE api request to Domoticz Http " + anItem.getItem().getAsString());
String responseString = null;
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(),
intensity, targetBri, targetBriInc, false);
String aBody;
aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(),
intensity, targetBri, targetBriInc, false);
// make call
if (anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody,
new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class)) == null) {
log.warn("Error on calling url to change device state: " + anUrl);
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
"Error on calling url to change device state", "/lights/"
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
}
return responseString;
// Not a device handler
return null;
}
@Override

View File

@@ -13,21 +13,13 @@ import com.bwssystems.HABridge.BridgeSettingsDescriptor;
import com.bwssystems.HABridge.Home;
import com.bwssystems.HABridge.NamedIP;
import com.bwssystems.HABridge.api.CallItem;
import com.bwssystems.HABridge.api.NameValue;
import com.bwssystems.HABridge.api.hue.HueError;
import com.bwssystems.HABridge.api.hue.HueErrorResponse;
import com.bwssystems.HABridge.dao.DeviceDescriptor;
import com.bwssystems.HABridge.hue.BrightnessDecode;
import com.bwssystems.HABridge.hue.MultiCommandUtil;
import com.bwssystems.HABridge.hue.TimeDecode;
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
import com.google.gson.Gson;
public class HalHome implements Home {
private static final Logger log = LoggerFactory.getLogger(HalHome.class);
private Map<String, HalInfo> hals;
private Boolean validHal;
private HTTPHandler anHttpHandler;
public HalHome(BridgeSettingsDescriptor bridgeSettings) {
super();
@@ -106,42 +98,16 @@ public class HalHome implements Home {
Iterator<HalDevice> devices = theSourceList.iterator();
while(devices.hasNext()) {
HalDevice theDevice = devices.next();
HalDevice aNewHalDevice = new HalDevice();
aNewHalDevice.setHaldevicetype(theDevice.getHaldevicetype());
aNewHalDevice.setHaldevicename(theDevice.getHaldevicename());
aNewHalDevice.setButtons(theDevice.getButtons());
aNewHalDevice.setHaladdress(hals.get(theKey).getHalAddress().getIp());
aNewHalDevice.setHalname(theKey);
theDeviceList.add(aNewHalDevice);
theDeviceList.add(theDevice);
}
anHttpHandler = new HTTPHandler();
return true;
}
@Override
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
Integer targetBri,Integer targetBriInc, DeviceDescriptor device, String body) {
log.debug("executing HUE api request to HAL Http " + anItem.getItem().getAsString());
String responseString = null;
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(),
intensity, targetBri, targetBriInc, false);
anUrl = TimeDecode.replaceTimeValue(anUrl);
String aBody = null;
if(anItem.getHttpBody()!= null && !anItem.getHttpBody().isEmpty()) {
aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(),
intensity, targetBri, targetBriInc, false);
aBody = TimeDecode.replaceTimeValue(aBody);
}
// make call
if (anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody,
new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class)) == null) {
log.warn("Error on calling url to change device state: " + anUrl);
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
"Error on calling url to change device state", "/lights/"
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
}
return responseString;
// Not a device handler
return null;
}
@Override

View File

@@ -121,6 +121,8 @@ public class HalInfo {
HalDevice aNewHalDevice = new HalDevice();
aNewHalDevice.setHaldevicetype(deviceType);
aNewHalDevice.setHaldevicename(theDevice.getDeviceName());
aNewHalDevice.setHaladdress(halAddress.getIp());
aNewHalDevice.setHalname(halAddress.getName());
deviceList.add(aNewHalDevice);
}

View File

@@ -37,7 +37,7 @@ public class HomeAssistant {
log.debug("calling HomeAssistant: " + aCommand.getHassName() + " - "
+ aCommand.getEntityId() + " - " + aCommand.getState() + " - " + aCommand.getBri());
String aUrl = null;
if(hassAddress.getSecure())
if(hassAddress.getSecure() != null && hassAddress.getSecure())
aUrl = "https";
else
aUrl = "http";
@@ -80,7 +80,7 @@ public class HomeAssistant {
headers = new NameValue[1];
headers[0] = password;
}
if(hassAddress.getSecure())
if(hassAddress.getSecure() != null && hassAddress.getSecure())
theUrl = "https";
else
theUrl = "http";

View File

@@ -97,18 +97,16 @@ public class MQTTHome implements Home {
if(mqttMessages[z].getCount() != null && mqttMessages[z].getCount() > 0)
theCount = mqttMessages[z].getCount();
for(int y = 0; y < theCount; y++) {
if( y > 0 || z > 0) {
log.debug("publishing message: " + mqttMessages[y].getClientId() + " - "
+ mqttMessages[y].getTopic() + " - " + mqttMessages[y].getMessage()
+ " - count: " + String.valueOf(z));
log.debug("publishing message: " + mqttMessages[y].getClientId() + " - "
+ mqttMessages[y].getTopic() + " - " + mqttMessages[y].getMessage()
+ " - count: " + String.valueOf(z));
MQTTHandler mqttHandler = getMQTTHandler(mqttMessages[y].getClientId());
if (mqttHandler == null) {
log.warn("Should not get here, no mqtt hanlder available");
} else {
mqttHandler.publishMessage(mqttMessages[y].getTopic(), mqttMessages[y].getMessage());
}
}
MQTTHandler mqttHandler = getMQTTHandler(mqttMessages[y].getClientId());
if (mqttHandler == null) {
log.warn("Should not get here, no mqtt hanlder available");
} else {
mqttHandler.publishMessage(mqttMessages[y].getTopic(), mqttMessages[y].getMessage());
}
}
}
} else {

View File

@@ -161,6 +161,25 @@ app.service ('bridgeService', function ($http, $window, ngToast) {
return a.indexOf(b) >= 0;
}
this.deviceContainsType = function (device, aType) {
if(device.mapType !== undefined && device.mapType !== null && device.mapType.indexOf(aType) >= 0)
return true;
if(device.deviceType !== undefined && device.deviceType !== null && device.deviceType.indexOf(aType) >= 0)
return true;
if(device.onUrl !== undefined && device.onUrl !== null && device.onUrl.indexOf(aType) >= 0)
return true;
if(device.dimUrl !== undefined && device.dimUrl !== null && device.dimUrl.indexOf(aType) >= 0)
return true;
if(device.offUrl !== undefined && device.offUrl !== null && device.offUrl.indexOf(aType) >= 0)
return true;
return false;
}
this.compareHarmonyNumber = function(r1, r2) {
if (r1.device !== undefined) {
if (r1.device.id === r2.device.id)
@@ -2338,8 +2357,10 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi
bridgeService.addDevice($scope.device).then(
function () {
$scope.clearDevice();
$location.path('/');
},
function (error) {
bridgeService.displayWarn("Error adding/updating device....", error);
}
);
@@ -2405,13 +2426,13 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi
});
app.filter('configuredVeraDevices', function () {
app.filter('configuredVeraDevices', function (bridgeService) {
return function(input) {
var out = [];
if(input === undefined || input === null || input.length === undefined)
return out;
for (var i = 0; i < input.length; i++) {
if(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "veraDevice"){
if(bridgeService.deviceContainsType(input[i], "veraDevice")){
out.push(input[i]);
}
}
@@ -2419,13 +2440,13 @@ app.filter('configuredVeraDevices', function () {
}
});
app.filter('configuredVeraScenes', function () {
app.filter('configuredVeraScenes', function (bridgeService) {
return function(input) {
var out = [];
if(input === undefined || input === null || input.length === undefined)
return out;
for (var i = 0; i < input.length; i++) {
if(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "veraScene"){
if(bridgeService.deviceContainsType(input[i], "veraScene")){
out.push(input[i]);
}
}
@@ -2439,7 +2460,7 @@ app.filter('configuredNestItems', function (bridgeService) {
if(input === undefined || input === null || input.length === undefined)
return out;
for (var i = 0; i < input.length; i++) {
if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "nest")){
if(bridgeService.deviceContainsType(input[i], "nest")){
out.push(input[i]);
}
}
@@ -2453,7 +2474,7 @@ app.filter('configuredHueItems', function (bridgeService) {
if(input === undefined || input === null || input.length === undefined)
return out;
for (var i = 0; i < input.length; i++) {
if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "hue")){
if(bridgeService.deviceContainsType(input[i], "hue")){
out.push(input[i]);
}
}
@@ -2467,7 +2488,7 @@ app.filter('configuredHalItems', function (bridgeService) {
if(input === undefined || input === null || input.length === undefined)
return out;
for (var i = 0; i < input.length; i++) {
if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "hal")){
if(bridgeService.deviceContainsType(input[i], "hal")){
out.push(input[i]);
}
}
@@ -2475,13 +2496,13 @@ app.filter('configuredHalItems', function (bridgeService) {
}
});
app.filter('configuredHarmonyActivities', function () {
app.filter('configuredHarmonyActivities', function (bridgeService) {
return function(input) {
var out = [];
if(input === undefined || input === null || input.length === undefined)
return out;
for (var i = 0; i < input.length; i++) {
if(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "harmonyActivity"){
if(bridgeService.deviceContainsType(input[i], "harmonyActivity")){
out.push(input[i]);
}
}
@@ -2489,13 +2510,13 @@ app.filter('configuredHarmonyActivities', function () {
}
});
app.filter('configuredHarmonyButtons', function () {
return function(input) {
app.filter('configuredHarmonyButtons', function (bridgeService) {
return function (input) {
var out = [];
if(input === undefined || input === null || input.length === undefined)
return out;
for (var i = 0; i < input.length; i++) {
if(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "harmonyButtons"){
if (bridgeService.deviceContainsType(input[i], "harmonyButton")) {
out.push(input[i]);
}
}
@@ -2503,13 +2524,13 @@ app.filter('configuredHarmonyButtons', function () {
}
});
app.filter('configuredMqttMsgs', function () {
app.filter('configuredMqttMsgs', function (bridgeService) {
return function(input) {
var out = [];
if(input === undefined || input === null || input.length === undefined)
return out;
for (var i = 0; i < input.length; i++) {
if(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "mqttMessage"){
if (bridgeService.deviceContainsType(input[i], "mqtt")) {
out.push(input[i]);
}
}
@@ -2523,7 +2544,21 @@ app.filter('configuredHassItems', function (bridgeService) {
if(input === undefined || input === null || input.length === undefined)
return out;
for (var i = 0; i < input.length; i++) {
if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "hass")){
if (bridgeService.deviceContainsType(input[i], "hass")) {
out.push(input[i]);
}
}
return out;
}
});
app.filter('configuredDomoticzItems', function (bridgeService) {
return function(input) {
var out = [];
if(input === undefined || input === null || input.length === undefined)
return out;
for (var i = 0; i < input.length; i++) {
if (bridgeService.deviceContainsType(input[i], "domoticz")) {
out.push(input[i]);
}
}

View File

@@ -43,6 +43,7 @@
<th sortable-header col="deviceType">Type</th>
<th sortable-header col="targetDevice">Target</th>
<th sortable-header col="inactive">Inactive</th>
<th sortable-header col="noState">No State</th>
<th>Actions</th>
</tr>
</thead>
@@ -53,6 +54,7 @@
<td>{{device.deviceType}}</td>
<td>{{device.targetDevice}}</td>
<td>{{device.inactive}}</td>
<td>{{device.noState}}</td>
<td>
<p>
<button class="btn btn-info" type="submit"

View File

@@ -10,14 +10,14 @@
href="#!/harmonyactivities">Harmony Activities</a></li>
<li ng-if="bridge.showHarmony" role="presentation"><a
href="#!/harmonydevices">Harmony Devices</a></li>
<li ng-if="bridge.showNest" role="presentation"><a href="#!/nest">Nest</a></li>
<li ng-if="bridge.showHue" role="presentation"><a
href="#!/huedevices">Hue Devices</a></li>
<li ng-if="bridge.showHal" role="presentation"><a href="#!/domoticzdevices">HAL
Devices</a></li>
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li role="presentation" class="active"><a href="#!/domoticzdevices">Domoticz
Devices</a></li>
<li role="presentation" class="active"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>

View File

@@ -19,6 +19,7 @@
href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a
href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation" class="active"><a href="#!/editdevice">Add/Edit</a></li>
</ul>
@@ -68,6 +69,12 @@
ng-model="device.inactive" ng-true-value=true
ng-false-value=false> {{device.inactive}}</td>
</tr>
<tr>
<td>No State (Do not update state for device)</td>
<td><input type="checkbox"
ng-model="device.noState" ng-true-value=true
ng-false-value=false> {{device.noState}}</td>
</tr>
<tr>
<td><label>Target</label></td>

View File

@@ -16,6 +16,7 @@
Devices</a></li>
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>

View File

@@ -17,6 +17,7 @@
href="#!/haldevices">HAL Devices</a></li>
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>

View File

@@ -17,6 +17,7 @@
href="#!/haldevices">HAL Devices</a></li>
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>

View File

@@ -16,8 +16,8 @@
<li ng-if="bridge.showHal" role="presentation" class="active"><a href="#!/haldevices">HAL
Devices</a></li>
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li role="presentation" class="active"><a href="#!/hassdevices">HomeAssistant
Devices</a></li>
<li role="presentation" class="active"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>

View File

@@ -17,6 +17,7 @@
href="#!/haldevices">HAL Devices</a></li>
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>

View File

@@ -17,6 +17,7 @@
href="#!/haldevices">HAL Devices</a></li>
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>

View File

@@ -11,6 +11,7 @@
<li ng-if="bridge.showHal" role="presentation"><a href="#!/haldevices">HAL Devices</a></li>
<li role="presentation" class="active"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>

View File

@@ -17,6 +17,7 @@
href="#!/haldevices">HAL Devices</a></li>
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>

View File

@@ -420,7 +420,7 @@
<div class="panel-heading">
<h1 class="panel-title">
Bridge Settings Backup <a ng-click="toggle()"><span
class={{imgUrl}} aria-hidden="true"></a>
class={{imgUrl}} aria-hidden="true"></span></a>
</h1>
</div>
<div ng-if="visible" class="panel-body">

View File

@@ -16,6 +16,7 @@
href="#!/haldevices">HAL Devices</a></li>
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>

View File

@@ -16,6 +16,7 @@
href="#!/haldevices">HAL Devices</a></li>
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
</ul>