Updates for RC2 fixing FHEM issues, Fiabaro Issues, adding functionality

for color tests, and sending multiple requests based on the Hue API
body.
This commit is contained in:
bsamuels
2018-01-05 14:48:20 -06:00
parent 3f3d643053
commit 037b151729
18 changed files with 599 additions and 148 deletions

View File

@@ -5,7 +5,7 @@
<groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId>
<version>5.2.0RC1</version>
<version>5.2.0RC2</version>
<packaging>jar</packaging>
<name>HA Bridge</name>

View File

@@ -80,7 +80,10 @@ public class DeviceDescriptor{
@SerializedName("deviceState")
@Expose
private DeviceState deviceState;
@SerializedName("onFirstDim")
@Expose
private boolean onFirstDim;
public String getName() {
return name;
}
@@ -275,6 +278,14 @@ public class DeviceDescriptor{
this.comments = comments;
}
public boolean isOnFirstDim() {
return onFirstDim;
}
public void setOnFirstDim(boolean onFirstDim) {
this.onFirstDim = onFirstDim;
}
public boolean containsType(String aType) {
if(aType == null)
return false;

View File

@@ -1096,10 +1096,11 @@ public class HueMulator {
DeviceState state = null;
Integer targetBri = null;
Integer targetBriInc = null;
MultiCommandUtil aMultiUtil = new MultiCommandUtil();
aMultiUtil.setTheDelay(bridgeSettings.getButtonsleep());
aMultiUtil.setDelayDefault(bridgeSettings.getButtonsleep());
aMultiUtil.setSetCount(1);
boolean isColorRequest = false;
boolean isDimRequest = false;
boolean isOnRequest = false;
boolean previousError = false;
ColorData colorData = null;
log.debug("hue state change requested: " + userId + " from " + ipAddress + " body: " + body);
HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton());
if (theErrors != null) {
@@ -1125,136 +1126,127 @@ public class HueMulator {
"Could not find device.", "/lights/" + lightId, null, null).getTheErrors(), HueError[].class);
}
if (body.contains("\"bri_inc\"")) {
targetBriInc = new Integer(theStateChanges.getBri_inc());
}
else if (body.contains("\"bri\"")) {
targetBri = new Integer(theStateChanges.getBri());
}
state = device.getDeviceState();
if (state == null) {
state = DeviceState.createDeviceState(device.isColorDevice());
device.setDeviceState(state);
}
if (targetBri != null || targetBriInc != null) {
url = device.getDimUrl();
if (body.contains("\"bri_inc\"")) {
targetBriInc = new Integer(theStateChanges.getBri_inc());
isDimRequest = true;
}
else if (body.contains("\"bri\"")) {
targetBri = new Integer(theStateChanges.getBri());
isDimRequest = true;
}
if (url == null || url.length() == 0)
url = device.getOnUrl();
} else {
if (body.contains("\"xy\"") || body.contains("\"ct\"") || body.contains("\"hue\"")) {
url = device.getColorUrl();
} else if (theStateChanges.isOn()) {
if (body.contains("\"xy\"") || body.contains("\"ct\"") || body.contains("\"hue\"") || body.contains("\"xy_inc\"") || body.contains("\"ct_inc\"") || body.contains("\"hue_inc\"")) {
List<Double> xy = theStateChanges.getXy();
List<Double> xyInc = theStateChanges.getXy_inc();
Integer ct = theStateChanges.getCt();
Integer ctInc = theStateChanges.getCt_inc();
if (xy != null && xy.size() == 2) {
colorData = new ColorData(ColorData.ColorMode.XY, xy);
} else if (xyInc != null && xyInc.size() == 2) {
List<Double> current = state.getXy();
current.set(0, current.get(0) + xyInc.get(0));
current.set(1, current.get(1) + xyInc.get(1));
colorData = new ColorData(ColorData.ColorMode.XY, current);
} else if (ct != null && ct != 0) {
colorData = new ColorData(ColorData.ColorMode.CT, ct);
} else if (ctInc != null && ctInc != 0) {
colorData = new ColorData(ColorData.ColorMode.CT, state.getCt() + ctInc);
}
if(colorData != null)
isColorRequest = true;
}
if (body.contains("\"on\"")) {
isOnRequest = true;
}
if(isOnRequest || (isDimRequest && device.isOnFirstDim() && !device.getDeviceState().isOn())) {
if (theStateChanges.isOn()) {
url = device.getOnUrl();
} else if (!theStateChanges.isOn()) {
url = device.getOffUrl();
}
}
// code for backwards compatibility
if(device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) {
if(url == null)
url = device.getOnUrl();
}
if (url != null && !url.equals("")) {
if (!url.startsWith("[")) {
if (url.startsWith("{\"item"))
url = "[" + url + "]";
else {
if(url.startsWith("{"))
url = "[{\"item\":" + url + "}]";
else
url = "[{\"item\":\"" + url + "\"}]";
}
} else if(!url.startsWith("[{\"item\""))
url = "[{\"item\":" + url + "}]";
log.debug("Decode Json for url items: " + url);
CallItem[] callItems = null;
try {
callItems = aGsonHandler.fromJson(url, CallItem[].class);
} catch(JsonSyntaxException e) {
log.warn("Could not decode Json for url items: " + lightId + " for hue state change request: " + userId + " from "
+ ipAddress + " body: " + body + " url items: " + url);
return aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/lights/" + lightId,
"Could decode json in request", "/lights/" + lightId, null, null).getTheErrors(), HueError[].class);
// code for backwards compatibility
if(device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) {
if(url == null)
url = device.getOnUrl();
}
for (int i = 0; callItems != null && i < callItems.length; i++) {
if (!ignoreRequester) {
if(!filterByRequester(device.getRequesterAddress(), ipAddress) || !filterByRequester(callItems[i].getFilterIPs(), ipAddress)) {
log.warn("filter for requester address not present in: (device)" + device.getRequesterAddress() + " OR then (item)" + 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().isEmpty())) {
if(validMapTypes.validateType(device.getMapType()))
callItems[i].setType(device.getMapType().trim());
else if(validMapTypes.validateType(device.getDeviceType()))
callItems[i].setType(device.getDeviceType().trim());
else
callItems[i].setType(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex]);
}
if (callItems[i].getType() != null) {
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());
else
aMultiUtil.setTheDelay(aMultiUtil.getDelayDefault());
ColorData colorData = null;
List<Double> xy = theStateChanges.getXy();
List<Double> xyInc = theStateChanges.getXy_inc();
Integer ct = theStateChanges.getCt();
Integer ctInc = theStateChanges.getCt_inc();
if (xy != null && xy.size() == 2) {
colorData = new ColorData(ColorData.ColorMode.XY, xy);
} else if (xyInc != null && xyInc.size() == 2) {
List<Double> current = state.getXy();
current.set(0, current.get(0) + xyInc.get(0));
current.set(1, current.get(1) + xyInc.get(1));
colorData = new ColorData(ColorData.ColorMode.XY, current);
} else if (ct != null && ct != 0) {
colorData = new ColorData(ColorData.ColorMode.CT, ct);
} else if (ctInc != null && ctInc != 0) {
colorData = new ColorData(ColorData.ColorMode.CT, state.getCt() + ctInc);
}
log.debug("Calling Home device handler for type : " + callItems[i].getType().trim());
responseString = homeManager.findHome(callItems[i].getType().trim()).deviceHandler(callItems[i], aMultiUtil, lightId, state.getBri(), targetBri, targetBriInc, colorData, device, body);
if(responseString != null && responseString.contains("{\"error\":")) {
x = aMultiUtil.getSetCount();
}
if (url != null && !url.equals("")) {
responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, targetBriInc, colorData);
} else {
log.warn("Could not find on/off url: " + lightId + " for hue state change request: " + userId + " from "
+ ipAddress + " body: " + body);
responseString = aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/lights/" + lightId,
"Could not find on/off url.", "/lights/" + lightId, null, null).getTheErrors(), HueError[].class);
previousError = true;
}
}
if (isDimRequest && !previousError) {
if(!device.isOnFirstDim() )
url = device.getDimUrl();
if (url == null || url.length() == 0)
url = device.getOnUrl();
// code for backwards compatibility
if(device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) {
if(url == null)
url = device.getOnUrl();
}
if (url != null && !url.equals("")) {
if(isOnRequest) {
try {
Thread.sleep(bridgeSettings.getButtonsleep());
} catch (InterruptedException e) {
// ignore
}
}
else
log.warn("Call Items type is null <<<" + callItems[i] + ">>>");
responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, targetBriInc, colorData);
} else {
log.warn("Could not find dim url: " + lightId + " for hue state change request: " + userId + " from "
+ ipAddress + " body: " + body);
responseString = aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/lights/" + lightId,
"Could not find dim url.", "/lights/" + lightId, null, null).getTheErrors(), HueError[].class);
previousError = true;
}
if(callItems.length == 0)
log.warn("No call items were available: <<<" + url + ">>>");
} else {
log.warn("Could not find url: " + lightId + " for hue state change request: " + userId + " from "
+ ipAddress + " body: " + body);
responseString = aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/lights/" + lightId,
"Could not find url.", "/lights/" + lightId, null, null).getTheErrors(), HueError[].class);
}
if (isColorRequest && !previousError) {
url = device.getColorUrl();
// code for backwards compatibility
if(device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) {
if(url == null)
url = device.getOnUrl();
}
if (url != null && !url.equals("")) {
if((isOnRequest && !isDimRequest) || isDimRequest) {
try {
Thread.sleep(bridgeSettings.getButtonsleep());
} catch (InterruptedException e) {
// ignore
}
}
responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, targetBriInc, colorData);
} else {
log.warn("Could not find color url: " + lightId + " for hue state change request: " + userId + " from "
+ ipAddress + " body: " + body);
responseString = aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/lights/" + lightId,
"Could not find color url.", "/lights/" + lightId, null, null).getTheErrors(), HueError[].class);
previousError = true;
}
}
if (responseString == null || !responseString.contains("[{\"error\":")) {
log.debug("Response is in error: " + ((responseString == null) ? "null" : responseString));
if(!device.isNoState()) {
@@ -1375,4 +1367,87 @@ public class HueMulator {
return aGsonHandler.toJson(theErrors);
}
protected String callUrl(String url, DeviceDescriptor device, String userId, String lightId, String body, String ipAddress, boolean ignoreRequester, Integer targetBri, Integer targetBriInc, ColorData colorData) {
String responseString = null;
MultiCommandUtil aMultiUtil = new MultiCommandUtil();
aMultiUtil.setTheDelay(bridgeSettings.getButtonsleep());
aMultiUtil.setDelayDefault(bridgeSettings.getButtonsleep());
aMultiUtil.setSetCount(1);
if (!url.startsWith("[")) {
if (url.startsWith("{\"item"))
url = "[" + url + "]";
else {
if(url.startsWith("{"))
url = "[{\"item\":" + url + "}]";
else
url = "[{\"item\":\"" + url + "\"}]";
}
} else if(!url.startsWith("[{\"item\""))
url = "[{\"item\":" + url + "}]";
log.debug("Decode Json for url items: " + url);
CallItem[] callItems = null;
try {
callItems = aGsonHandler.fromJson(url, CallItem[].class);
} catch(JsonSyntaxException e) {
log.warn("Could not decode Json for url items: " + lightId + " for hue state change request: " + userId + " from "
+ ipAddress + " body: " + body + " url items: " + url);
return aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/lights/" + lightId,
"Could decode json in request", "/lights/" + lightId, null, null).getTheErrors(), HueError[].class);
}
for (int i = 0; callItems != null && i < callItems.length; i++) {
if (!ignoreRequester) {
if(!filterByRequester(device.getRequesterAddress(), ipAddress) || !filterByRequester(callItems[i].getFilterIPs(), ipAddress)) {
log.warn("filter for requester address not present in: (device)" + device.getRequesterAddress() + " OR then (item)" + 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().isEmpty())) {
if(validMapTypes.validateType(device.getMapType()))
callItems[i].setType(device.getMapType().trim());
else if(validMapTypes.validateType(device.getDeviceType()))
callItems[i].setType(device.getDeviceType().trim());
else
callItems[i].setType(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex]);
}
if (callItems[i].getType() != null) {
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());
else
aMultiUtil.setTheDelay(aMultiUtil.getDelayDefault());
log.debug("Calling Home device handler for type : " + callItems[i].getType().trim());
responseString = homeManager.findHome(callItems[i].getType().trim()).deviceHandler(callItems[i], aMultiUtil, lightId, device.getDeviceState().getBri(), targetBri, targetBriInc, colorData, device, body);
if(responseString != null && responseString.contains("{\"error\":")) {
x = aMultiUtil.getSetCount();
}
}
}
else
log.warn("Call Items type is null <<<" + callItems[i] + ">>>");
}
if(callItems.length == 0)
log.warn("No call items were available: <<<" + url + ">>>");
return responseString;
}
}

View File

@@ -137,7 +137,7 @@ public class FHEMHome implements Home {
List<FHEMDevice> deviceList = new ArrayList<FHEMDevice>();
while(keys.hasNext()) {
String key = keys.next();
theResponse = fhemMap.get(key).getDevices(httpClient);
theResponse = fhemMap.get(key).testGetDevices(httpClient);
if(theResponse != null)
addFHEMDevices(deviceList, theResponse, key);
else {

View File

@@ -88,6 +88,275 @@ public class FHEMInstance {
return deviceList;
}
public List<FHEMDevice> testGetDevices(HTTPHandler httpClient) {
String TestData = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" +
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
" <head root=\"/fhem\">\n" +
" <title>Home, Sweet Home</title>\n" +
" <link rel=\"shortcut icon\" href=\"/fhem/icons/favicon\" />\n" +
" <meta charset=\"UTF-8\">\n" +
" <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n" +
" <link href=\"/fhem/pgm2/style.css?v=1513026539\" rel=\"stylesheet\"/>\n" +
" <link href=\"/fhem/pgm2/jquery-ui.min.css\" rel=\"stylesheet\"/>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/jquery.min.js\"></script>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/jquery-ui.min.js\"></script>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb.js\"></script>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_colorpicker.js\"></script>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_fbcalllist.js\"></script>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_knob.js\"></script>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_readingsGroup.js\"></script>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_readingsHistory.js\"></script>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_sortable.js\"></script>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_uzsu.js\"></script>\n" +
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_weekprofile.js\"></script>\n" +
" </head>\n" +
" <body name='Home, Sweet Home' fw_id='7880' generated=\"1513272732\" longpoll=\"1\" data-confirmDelete='1' data-confirmJSError='1' data-webName='haBridgeWeb '>\n" +
" <div id=\"menuScrollArea\">\n" +
" <div>\n" +
" <a href=\"/fhem?\">\n" +
" <div id=\"logo\"></div>\n" +
" </a>\n" +
" </div>\n" +
" <div id=\"menu\">\n" +
" <table>\n" +
" <tr>\n" +
" <td>\n" +
" <table class=\"room roomBlock1\">\n" +
" <tr>\n" +
" <td>\n" +
" <div class=\"menu_Save_config\">\n" +
" <a href=\"/fhem?cmd=save\">Save config</a>\n" +
" <a id=\"saveCheck\" class=\"changed\" style=\"visibility:visible\">?</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" </table>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <table class=\"room roomBlock2\">\n" +
" <tr>\n" +
" <td>\n" +
" <div class=\"menu_Alexa\">\n" +
" <a href=\"/fhem?room=Alexa\">Alexa</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <div class=\"menu_System\">\n" +
" <a href=\"/fhem?room=System\">System</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <div class=\"menu_WG_Zimmer\">\n" +
" <a href=\"/fhem?room=WG%2dZimmer\">WG-Zimmer</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <div class=\"menu_habridge\">\n" +
" <a href=\"/fhem?room=habridge\">habridge</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <div class=\"menu_Everything\">\n" +
" <a href=\"/fhem?room=all\">\n" +
" <img class='icon icoEverything' src=\"/fhem/images/default/icoEverything.png\" alt=\"icoEverything\" title=\"icoEverything\">&nbsp;Everything\n" +
" </a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" </table>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <table class=\"room roomBlock3\">\n" +
" <tr>\n" +
" <td>\n" +
" <div class=\"menu_Logfile\">\n" +
" <a href=\"/fhem/FileLog_logWrapper?dev=Logfile&type=text&file=fhem-2017-12.log\">Logfile</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <div>\n" +
" <a href=\"/fhem/docs/commandref.html\" target=\"_blank\" >Commandref</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <div>\n" +
" <a href=\"http://fhem.de/fhem.html#Documentation\" target=\"_blank\" >Remote doc</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <div class=\"menu_Edit_files\">\n" +
" <a href=\"/fhem?cmd=style%20list\">Edit files</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <div class=\"menu_Select_style\">\n" +
" <a href=\"/fhem?cmd=style%20select\">Select style</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>\n" +
" <div class=\"menu_Event_monitor\">\n" +
" <a href=\"/fhem?cmd=style%20eventMonitor\">Event monitor</a>\n" +
" </div>\n" +
" </td>\n" +
" </tr>\n" +
" </table>\n" +
" </td>\n" +
" </tr>\n" +
" </table>\n" +
" </div>\n" +
" </div>\n" +
" <div id=\"hdr\">\n" +
" <table border=\"0\" class=\"header\">\n" +
" <tr>\n" +
" <td style=\"padding:0\">\n" +
" <form method=\"post\" action=\"/fhem\">\n" +
" <input type=\"hidden\" name=\"fw_id\" value=\"7880\"/>\n" +
" <input type=\"text\" name=\"cmd\" class=\"maininput\" size=\"40\" value=\"\"/>\n" +
" </form>\n" +
" </td>\n" +
" </tr>\n" +
" </table>\n" +
" </div>\n" +
" <div id='content' >\n" +
" <pre>{ \n" +
" \"Arg\":\"room=habridge\", \n" +
" \"Results\": [ \n" +
" { \n" +
" \"Name\":\"Arbeitslicht\", \n" +
" \"PossibleSets\":\"on off\", \n" +
" \"PossibleAttrs\":\"alias comment:textField-long eventMap group room suppressReading userReadings:textField-long verbose:0,1,2,3,4,5 readingList setList useSetExtensions disable disabledForIntervals event-on-change-reading event-on-update-reading event-aggregator event-min-interval stateFormat:textField-long timestamp-on-change-reading alexaName alexaRoom cmdIcon devStateIcon devStateStyle fhem_widget_command fhem_widget_command_2 fhem_widget_command_3 genericDeviceType:security,ignore,switch,outlet,light,blind,thermometer,thermostat,contact,garage,window,lock homebridgeMapping:textField-long icon sortby webCmd widgetOverride userattr\", \n" +
" \"Internals\": { \n" +
" \"NAME\": \"Arbeitslicht\", \n" +
" \"NR\": \"28\", \n" +
" \"STATE\": \"-\", \n" +
" \"TYPE\": \"dummy\" \n" +
" }, \n" +
" \"Readings\": { \"state\": { \"Value\":\"on\", \"Time\":\"2017-12-14 15:41:05\" } }, \n" +
" \"Attributes\": { \n" +
" \"alexaName\": \"Arbeitslicht\", \n" +
" \"alexaRoom\": \"alexaroom\", \n" +
" \"fhem_widget_command\": \"{ \\u0022allowed_values\\u0022 : [ \\u0022on\\u0022 ], \\u0022order\\u0022 : 0}\", \n" +
" \"icon\": \"scene_office\", \n" +
" \"room\": \"Alexa,habridge\", \n" +
" \"setList\": \"on off\", \n" +
" \"stateFormat\": \"-\", \n" +
" \"webCmd\": \"on\" \n" +
" } \n" +
" }, \n" +
" { \n" +
" \"Name\":\"DeckenlampeLinks\", \n" +
" \"PossibleSets\":\"on off dim dimup dimdown HSV RGB sync pair unpair\", \n" +
" \"PossibleAttrs\":\"alias comment:textField-long eventMap group room suppressReading userReadings:textField-long verbose:0,1,2,3,4,5 gamma dimStep defaultColor defaultRamp colorCast whitePoint event-on-change-reading event-on-update-reading event-aggregator event-min-interval stateFormat:textField-long timestamp-on-change-reading alexaName alexaRoom cmdIcon devStateIcon devStateStyle fhem_widget_command fhem_widget_command_2 fhem_widget_command_3 genericDeviceType:security,ignore,switch,outlet,light,blind,thermometer,thermostat,contact,garage,window,lock homebridgeMapping:textField-long icon sortby webCmd widgetOverride \n" +
" <a href=\"/fhem?detail=AlleLampen\">AlleLampen</a> AlleLampen_map\n" +
" <a href=\"/fhem?detail=DeckenLampen\">DeckenLampen</a> DeckenLampen_map structexclude userattr\", \n" +
" \"Internals\": { \n" +
" \"CONNECTION\": \"bridge-V3\", \n" +
" \"DEF\": \"RGBW2 bridge-V3:10.2.3.3\", \n" +
" \"IP\": \"10.2.3.3\", \n" +
" \"LEDTYPE\": \"RGBW2\", \n" +
" \"NAME\": \"DeckenlampeLinks\", \n" +
" \"NR\": \"18\", \n" +
" \"NTFY_ORDER\": \"50-DeckenlampeLinks\", \n" +
" \"PORT\": \"8899\", \n" +
" \"PROTO\": \"0\", \n" +
" \"SLOT\": \"5\", \n" +
" \"STATE\": \"off\", \n" +
" \"TYPE\": \"WifiLight\" \n" +
" }, \n" +
" \"Readings\": { \n" +
" \"RGB\": { \"Value\":\"000000\", \"Time\":\"2017-12-14 15:41:10\" }, \n" +
" \"brightness\": { \"Value\":\"0\", \"Time\":\"2017-12-14 15:41:10\" }, \n" +
" \"hue\": { \"Value\":\"0\", \"Time\":\"2017-12-14 15:41:10\" }, \n" +
" \"saturation\": { \"Value\":\"0\", \"Time\":\"2017-12-14 15:41:10\" }, \n" +
" \"state\": { \"Value\":\"off\", \"Time\":\"2017-12-14 15:41:10\" } \n" +
" }, \n" +
" \"Attributes\": { \n" +
" \"AlleLampen\": \"AlleLampen\", \n" +
" \"DeckenLampen\": \"DeckenLampen\", \n" +
" \"fhem_widget_command\": \"{ \\u0022locations\\u0022 : [ \\u0022APP\\u0022, \\u0022WATCH\\u0022, \\u0022WIDGET\\u0022 ], \\u0022allowed_values\\u0022 : [ \\u0022off\\u0022, \\u0022on\\u0022 ], \\u0022order\\u0022 : 6}\", \n" +
" \"room\": \"habridge,Alexa,WG-Zimmer\", \n" +
" \"userattr\": \"AlleLampen AlleLampen_map\n" +
" <a href=\"/fhem?detail=DeckenLampen\">DeckenLampen</a> DeckenLampen_map structexclude\", \n" +
" \"webCmd\": \"RGB\", \n" +
" \"widgetOverride\": \"RGB:colorpicker,RGB\" \n" +
" } \n" +
" } ], \n" +
" \"totalResultsReturned\":2 \n" +
"}\n" +
" </pre>\n" +
" </div>\n" +
" </body>\n" +
"</html>";
String TestData2 = " <div id='content' >\n" +
" <pre>\n" + "{ \"Arg\":\"room=HaBridge\", \"Results\": [ { \"Name\":\"wifi_steckdose3\", \"PossibleSets\":\"on:noArg off:noArg off on toggle\", \"PossibleAttrs\":\"alias comment:textField-long eventMap group room suppressReading userReadings:textField-long verbose:0,1,2,3,4,5 IODev qos retain publishSet publishSet_.* subscribeReading_.* autoSubscribeReadings event-on-change-reading event-on-update-reading event-aggregator event-min-interval stateFormat:textField-long timestamp-on-change-reading alarmDevice:Actor,Sensor alarmSettings cmdIcon devStateIcon devStateStyle icon lightSceneParamsToSave lightSceneRestoreOnlyIfChanged:1,0 sortby structexclude webCmd webCmdLabel:textField-long widgetOverride userattr\", \"Internals\": { \"CHANGED\": \"null\", \"NAME\": \"wifi_steckdose3\", \"NR\": \"270\", \"STATE\": \"off\", \"TYPE\": \"MQTT_DEVICE\", \"retain\": \"*:1 \" }, \"Readings\": { \"state\": { \"Value\":\"OFF\", \"Time\":\"2018-01-01 23:01:21\" }, \"transmission-state\": { \"Value\":\"subscription acknowledged\", \"Time\":\"2018-01-03 22:34:00\" } }, \"Attributes\": { \"IODev\": \"myBroker\", \"alias\": \"Stecki\", \"devStateIcon\": \"on:black_Steckdose.on off:black_Steckdose.off\", \"event-on-change-reading\": \"state\", \"eventMap\": \"ON:on OFF:off\", \"publishSet\": \"on off toggle /SmartHome/az/stecker/cmnd/POWER\", \"retain\": \"1\", \"room\": \"HaBridge,Arbeitszimmer,mqtt\", \"stateFormat\": \"state\", \"subscribeReading_state\": \"/SmartHome/az/stecker/stat/POWER\", \"webCmd\": \"on:off:toggle\" } } ], \"totalResultsReturned\":1 }" +
" </pre>\n" +
" </div>\n" +
" </body>\n" +
"</html>";
List<FHEMDevice> deviceList = null;
FHEMItem theFhemStates;
String theUrl = null;
String theData;
NameValue[] headers = null;
if(theFhem.getSecure() != null && theFhem.getSecure())
theUrl = "https://";
else
theUrl = "http://";
if(theFhem.getUsername() != null && !theFhem.getUsername().isEmpty() && theFhem.getPassword() != null && !theFhem.getPassword().isEmpty()) {
theUrl = theUrl + theFhem.getUsername() + ":" + theFhem.getPassword() + "@";
}
theUrl = theUrl + theFhem.getIp() + ":" + theFhem.getPort() + "/fhem?cmd=jsonlist2";
if(theFhem.getWebhook() != null && !theFhem.getWebhook().trim().isEmpty())
theUrl = theUrl + "%20room=" + theFhem.getWebhook().trim();
// theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers);
theData = TestData;
if(theData != null) {
log.debug("GET FHEM States - data: " + theData);
theData = getJSONData(theData);
theFhemStates = new Gson().fromJson(theData, FHEMItem.class);
if(theFhemStates == null) {
log.warn("Cannot get any devices for FHEM " + theFhem.getName() + " as response is not parsable.");
}
else {
deviceList = new ArrayList<FHEMDevice>();
for (Result aResult:theFhemStates.getResults()) {
FHEMDevice aNewFhemDeviceDevice = new FHEMDevice();
aNewFhemDeviceDevice.setItem(aResult);
aNewFhemDeviceDevice.setAddress(theFhem.getIp() + ":" + theFhem.getPort());
aNewFhemDeviceDevice.setName(theFhem.getName());
deviceList.add(aNewFhemDeviceDevice);
}
}
}
else
log.warn("Cannot get an devices for FHEM " + theFhem.getName() + " http call failed.");
return deviceList;
}
public String getJSONData(String response) {
String theData;
theData = response.substring(response.indexOf("<pre>") + 4);

View File

@@ -103,9 +103,10 @@ public class HTTPHandler {
retryCount = 2;
} else if (response != null) {
log.warn("HTTP response code was not an expected successful response of between 200 - 299, the code was: "
+ response.getStatusLine());
+ response.getStatusLine() + " with the content of <<<" + theContent + ">>>");
if (response.getStatusLine().getStatusCode() == 504) {
log.warn("HTTP response code was 504, retrying...");
log.debug("The 504 error content is <<<" + theContent + ">>>");
} else
retryCount = 2;

View File

@@ -75,7 +75,7 @@ public class SomfyInfo {
urlEncodedFormEntity.writeTo(bos);
String body = bos.toString();
String response = httpClient.doHttpRequest(BASE_URL + "json/login",HttpPost.METHOD_NAME, "application/x-www-form-urlencoded", body,httpHeader);
log.debug(response);
log.debug("Somfy login response <<<" + response + ">>>");
}
private NameValue[] getHttpHeaders() {
@@ -89,7 +89,7 @@ public class SomfyInfo {
NameValue[] httpHeader = getHttpHeaders();
log.info("Making SOMFY http setup call");
String response = httpClient.doHttpRequest(BASE_URL + "json/getSetup", HttpGet.METHOD_NAME, "", "", httpHeader );
log.debug(response);
log.debug("Somfy getSetup response <<<" + response + ">>>");
GetSetup setupData = new Gson().fromJson(response, GetSetup.class);
return setupData;
}
@@ -98,7 +98,7 @@ public class SomfyInfo {
login(namedIP.getUsername(), namedIP.getPassword());
log.info("Making SOMFY http exec call");
String response = httpClient.doHttpRequest(BASE_URL_ENDUSER + "exec/apply", HttpPost.METHOD_NAME, "application/json;charset=UTF-8", jsonToPost, getHttpHeaders());
log.info(response);
log.debug("Somfy exec reply response <<<" + response + ">>>");
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@@ -15,6 +15,7 @@
<link href="css/ngDialog-theme-default.min.css" rel="stylesheet">
<link href="css/scrollable-table.css" rel="stylesheet">
<link href="css/strength-meter.min.css" rel="stylesheet">
<link href="css/colorpicker.min.css" rel="stylesheet">
<!--[if lt IE 9]>
<script type="text/javascript" src="js/html5shiv.min.js"></script>
@@ -88,6 +89,7 @@
<script src="js/angular-base64.min.js"></script>
<script src="js/angular-resource.min.js"></script>
<script src="js/ngStorage.min.js"></script>
<script src="js/bootstrap-colorpicker-module.min.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
var app = angular.module ('habridge', ['ngRoute', 'ngToast', 'rzModule', 'ngDialog', 'base64', 'scrollable-table', 'ngResource', 'ngStorage']);
var app = angular.module ('habridge', ['ngRoute', 'ngToast', 'rzModule', 'ngDialog', 'base64', 'scrollable-table', 'ngResource', 'ngStorage', 'colorpicker.module']);
app.config (function ($locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!');
@@ -1303,18 +1303,53 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n
self.state.device = device;
};
this.testUrl = function (device, type, value) {
this.toXY = function (red, green, blue) {
//Gamma corrective
red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92);
green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92);
blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92);
//Apply wide gamut conversion D65
var X = red * 0.664511 + green * 0.154324 + blue * 0.162028;
var Y = red * 0.283881 + green * 0.668433 + blue * 0.047685;
var Z = red * 0.000088 + green * 0.072310 + blue * 0.986039;
var fx = X / (X + Y + Z);
var fy = Y / (X + Y + Z);
if (isNaN(fx)) {
fx = 0.0;
}
if (isNaN(fy)) {
fy = 0.0;
}
return [fx.toPrecision(4),fy.toPrecision(4)];
};
this.testUrl = function (device, type, value, valueType) {
var msgDescription = "unknown";
self.getTestUser();
var testUrl = this.state.huebase + "/" + this.state.testuser + "/lights/" + device.id + "/state";
var testBody = "{\"on\":";
var addComma = false;
var testBody = "{";
if (type === "off") {
testBody = testBody + "false";
} else {
testBody = testBody + "true";
testBody = testBody + "\"on\":false";
addComma = true
}
if (value) {
testBody = testBody + ",\"bri\":" + value;
if (type === "on") {
testBody = testBody + "\"on\":true";
addComma = true
}
if (valueType === "dim" && value) {
if(addComma)
testBody = testBody + ",";
testBody = testBody + "\"bri\":" + value;
addComma = true
}
if (valueType === "color" && value) {
if(addComma)
testBody = testBody + ",";
testBody = testBody + "\"xy\": [" + value[0] +"," + value[1] + "]";
}
testBody = testBody + "}";
$http.put(testUrl, testBody).then(
@@ -1940,7 +1975,7 @@ app.controller('ViewingController', function ($scope, $location, bridgeService,
var dialogNeeded = false;
if ((type === "on" && device.onUrl !== undefined && bridgeService.aContainsB(device.onUrl, "${intensity")) ||
(type === "off" && device.offUrl !== undefined && bridgeService.aContainsB(device.offUrl, "${intensity")) ||
(type === "dim" && device.dimUrl !== undefined) || (type === "color" && device.colorUrl !== undefined)) {
(type === "dim" && device.dimUrl !== undefined)) {
$scope.bridge.device = device;
$scope.bridge.type = type;
ngDialog.open({
@@ -1949,8 +1984,19 @@ app.controller('ViewingController', function ($scope, $location, bridgeService,
className: 'ngdialog-theme-default'
});
}
else if ((type === "on" && device.onUrl !== undefined && bridgeService.aContainsB(device.onUrl, "${color")) ||
(type === "off" && device.offUrl !== undefined && bridgeService.aContainsB(device.offUrl, "${color")) ||
(type === "color" && device.colorUrl !== undefined)) {
$scope.bridge.device = device;
$scope.bridge.type = type;
ngDialog.open({
template: 'colorDialog',
controller: 'ColorDialogCtrl',
className: 'ngdialog-theme-default'
});
}
else
bridgeService.testUrl(device, type);
bridgeService.testUrl(device, type, null, type);
};
$scope.deleteDevice = function (device) {
$scope.bridge.device = device;
@@ -2039,7 +2085,28 @@ app.controller('ValueDialogCtrl', function ($scope, bridgeService, ngDialog) {
theValue = Math.round(($scope.slider.value * .01) * 255);
else
theValue = $scope.slider.value;
bridgeService.testUrl($scope.bridge.device, $scope.bridge.type, theValue);
bridgeService.testUrl($scope.bridge.device, $scope.bridge.type, theValue, "dim");
$scope.bridge.device = null;
$scope.bridge.type = "";
};
});
app.controller('ColorDialogCtrl', function ($scope, bridgeService, ngDialog) {
$scope.rgbPicker = {
color: 'rgb(255,255,255)'
};
$scope.bridge = bridgeService.state;
$scope.setValue = function () {
ngDialog.close('ngdialog1');
var next = $scope.rgbPicker.color.substr($scope.rgbPicker.color.indexOf('(') + 1);
var red = next.substr(0, next.indexOf(','));
next = next.substr(next.indexOf(',') + 1);
var green = next.substr(0, next.indexOf(','));
next = next.substr(next.indexOf(',') + 1);
var blue = next.substr(0, next.indexOf(')'));
var theValue = bridgeService.toXY(red, green, blue);
bridgeService.testUrl($scope.bridge.device, $scope.bridge.type, theValue, "color");
$scope.bridge.device = null;
$scope.bridge.type = "";
};
@@ -2232,6 +2299,7 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n
};
$scope.buildDeviceUrls = function (fibarodevice, dim_control, buildonly) {
var dimpayload = null;
if(dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)
dimpayload = "http://" + fibarodevice.fibaroaddress + ":" + fibarodevice.fibaroport + "/api/callAction?deviceID=" + fibarodevice.id + "&name=setValue&arg1=" + dim_control;
@@ -2248,6 +2316,8 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n
};
$scope.buildSceneUrls = function (fibaroscene) {
var onpayload = null;
var offpayload = null;
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";
@@ -3533,7 +3603,7 @@ app.controller('SomfyController', function ($scope, $location, bridgeService, ng
$scope.buildDeviceUrls = function (somfydevice, dim_control, buildonly) {
//TODO - support partial window opening - add back 'dim_control' second param in here, and in somfydevice.html
dimpayload = "";
dimpayload = null;
onpayload = "{\"label\":\"Label that is ignored probably\",\"actions\":[{\"deviceURL\":\""+ somfydevice.deviceUrl+"\",\"commands\":[{\"name\":\"open\",\"parameters\":[]}]}]}";
offpayload = "{\"label\":\"Label that is ignored probably\",\"actions\":[{\"deviceURL\":\""+ somfydevice.deviceUrl+"\",\"commands\":[{\"name\":\"close\",\"parameters\":[]}]}]}";
@@ -3800,28 +3870,24 @@ app.controller('FhemController', function ($scope, $location, bridgeService, ngD
};
$scope.buildDeviceUrls = function (fhemdevice, dim_control, ondeviceaction, oninputdeviceaction, offdeviceaction, offinputdeviceaction, buildonly) {
var preCmd = "/fhem?cmd=set%20" + fhemdevice.item.name + "%20";
if(fhemdevice.item.possibleSets.indexOf("dim" >= 0)) {
var preCmd = "/fhem?cmd=set%20" + fhemdevice.item.Name + "%20";
if(fhemdevice.item.PossibleSets.indexOf("dim") >= 0) {
if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)) {
dimpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"dim%20" + dim_control + "\"}";
}
else
dimpayload = null;
dimpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"dim%20${intensity.percent}\"}";
}
else
dimpayload = null;
if(fhemdevice.item.possibleSets.indexOf("RGB" >= 0)) {
if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)) {
colorpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"RGB%20${color.rgbx}\"}";
}
else
colorpayload = null;
if(fhemdevice.item.PossibleSets.indexOf("RGB") >= 0) {
colorpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"RGB%20${color.rgbx}\"}";
}
else
colorpayload = null;
onpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"on\"}";
offpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"off\"}";
bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, fhemdevice.item.name + "-" + fhemdevice.name, fhemdevice.item.name, fhemdevice.name, fhemdevice.item.type, "fhemDevice", null, null);
bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, fhemdevice.item.Name + "-" + fhemdevice.name, fhemdevice.item.Name, fhemdevice.name, fhemdevice.item.type, "fhemDevice", null, null);
$scope.device = bridgeService.state.device;
if (!buildonly) {
bridgeService.editNewDevice($scope.device);

View File

@@ -78,7 +78,7 @@
<td>{{device.id}}</td>
<td>{{device.name}}</td>
<td class="cr">{{device.description}}</td>
<td class="cr">on={{device.deviceState.on}},bri={{device.deviceState.on}},hue={{device.deviceState.hue}},sat={{device.deviceState.sat}},effect={{device.deviceState.effect}},ct={{device.deviceState.ct}},alert={{device.deviceState.alert}},colormode={{device.deviceState.colormode}},reachable={{device.deviceState.reachable}},XYList={{device.deviceState.xy}}</td>
<td class="cr">on={{device.deviceState.on}},bri={{device.deviceState.bri}},hue={{device.deviceState.hue}},sat={{device.deviceState.sat}},effect={{device.deviceState.effect}},ct={{device.deviceState.ct}},alert={{device.deviceState.alert}},colormode={{device.deviceState.colormode}},reachable={{device.deviceState.reachable}},XYList={{device.deviceState.xy}}</td>
<td>{{device.deviceType}}</td>
<td>{{device.targetDevice}}</td>
<td>{{device.inactive}}</td>
@@ -91,6 +91,8 @@
ng-click="testUrl(device, 'dim')">Test Dim</button>
<button class="btn btn-info" type="submit"
ng-click="testUrl(device, 'off')">Test OFF</button>
<button class="btn btn-info" type="submit"
ng-click="testUrl(device, 'color')">Test Color</button>
<button class="btn btn-warning" type="submit"
ng-click="editDevice(device)">Edit/Copy</button>
<button class="btn btn-danger" type="submit"
@@ -161,6 +163,17 @@
<button type="button" class="ngdialog-button ngdialog-button-primary" ng-click="setValue()">Set</button>
</div>
</script>
<script type="text/ng-template" id="colorDialog">
<div class="ngdialog-message">
<h2>Select Color</h2>
<p>
<input colorpicker="rgb" ng-model="rgbPicker.color" type="text">
</p>
</div>
<div class="ngdialog-buttons mt">
<button type="button" class="ngdialog-button ngdialog-button-primary" ng-click="setValue()">Set</button>
</div>
</script>
<script type="text/ng-template" id="deleteDialog">
<div class="ngdialog-message">
<h2>Device to Delete?</h2>

View File

@@ -93,6 +93,12 @@
ng-model="device.offState" ng-true-value=true
ng-false-value=false> {{device.offState}}</td>
</tr>
<tr>
<td><label>On with First Dim (If the device is not on in the ha-bridge state, it will send on instead of the dim.)</label></td>
<td><input type="checkbox"
ng-model="device.onFirstDim" ng-true-value=true
ng-false-value=false> {{device.onFirstDim}}</td>
</tr>
<tr>
<td><label>Filter Address (comma separated list)</label></td>
<td><input type="text" class="form-control" id="device-requester-addr"

View File

@@ -72,9 +72,9 @@
value="{{fhemdevice.item.name}}"
ng-checked="bulk.devices.indexOf(fhemdevice.item.name) > -1"
ng-click="toggleSelection(fhemdevice.item.name)">
{{fhemdevice.item.name}}</td>
{{fhemdevice.item.Name}}</td>
<td>{{fhemdevice.name}}</td>
<td>{{fhemdevice.item.possibleSets}}</td>
<td>{{fhemdevice.item.PossibleSets}}</td>
<td>
<button class="btn btn-success" type="submit"
ng-click="buildDeviceUrls(fhemdevice, device_dim_control, false)">Build Item</button>

View File

@@ -231,6 +231,12 @@ public class FHEMInstanceConstructor {
" </body>\n" +
"</html>";
public final static String TestData2 = " <div id='content' >\n" +
" <pre>\n" + "{ \"Arg\":\"room=HaBridge\", \"Results\": [ { \"Name\":\"wifi_steckdose3\", \"PossibleSets\":\"on:noArg off:noArg off on toggle\", \"PossibleAttrs\":\"alias comment:textField-long eventMap group room suppressReading userReadings:textField-long verbose:0,1,2,3,4,5 IODev qos retain publishSet publishSet_.* subscribeReading_.* autoSubscribeReadings event-on-change-reading event-on-update-reading event-aggregator event-min-interval stateFormat:textField-long timestamp-on-change-reading alarmDevice:Actor,Sensor alarmSettings cmdIcon devStateIcon devStateStyle icon lightSceneParamsToSave lightSceneRestoreOnlyIfChanged:1,0 sortby structexclude webCmd webCmdLabel:textField-long widgetOverride userattr\", \"Internals\": { \"CHANGED\": \"null\", \"NAME\": \"wifi_steckdose3\", \"NR\": \"270\", \"STATE\": \"off\", \"TYPE\": \"MQTT_DEVICE\", \"retain\": \"*:1 \" }, \"Readings\": { \"state\": { \"Value\":\"OFF\", \"Time\":\"2018-01-01 23:01:21\" }, \"transmission-state\": { \"Value\":\"subscription acknowledged\", \"Time\":\"2018-01-03 22:34:00\" } }, \"Attributes\": { \"IODev\": \"myBroker\", \"alias\": \"Stecki\", \"devStateIcon\": \"on:black_Steckdose.on off:black_Steckdose.off\", \"event-on-change-reading\": \"state\", \"eventMap\": \"ON:on OFF:off\", \"publishSet\": \"on off toggle /SmartHome/az/stecker/cmnd/POWER\", \"retain\": \"1\", \"room\": \"HaBridge,Arbeitszimmer,mqtt\", \"stateFormat\": \"state\", \"subscribeReading_state\": \"/SmartHome/az/stecker/stat/POWER\", \"webCmd\": \"on:off:toggle\" } } ], \"totalResultsReturned\":1 }" +
" </pre>\n" +
" </div>\n" +
" </body>\n" +
"</html>";
public static void main(String[] args){
FHEMInstanceConstructor aTestService = new FHEMInstanceConstructor();
if(aTestService.validateStructure())
@@ -243,7 +249,7 @@ public class FHEMInstanceConstructor {
anAddress.setName("testName");
anAddress.setIp("10.0.0.1");
FHEMInstance anInstance = new FHEMInstance(anAddress);
String decodeData = anInstance.getJSONData(TestData);
String decodeData = anInstance.getJSONData(TestData2);
try {
aGson = new GsonBuilder()
.create();