mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-18 00:10:20 +00:00
tested moziot and working
This commit is contained in:
2
pom.xml
2
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.2.next_a</version>
|
<version>5.2.next_b</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>HA Bridge</name>
|
<name>HA Bridge</name>
|
||||||
|
|||||||
@@ -1431,7 +1431,7 @@ public class HueMulator {
|
|||||||
anHSL.setSat(sat);
|
anHSL.setSat(sat);
|
||||||
else
|
else
|
||||||
anHSL.setSat(state.getSat());
|
anHSL.setSat(state.getSat());
|
||||||
log.info("hue/sat request - " + anHSL);
|
log.debug("hue/sat request - " + anHSL);
|
||||||
colorData = new ColorData(ColorData.ColorMode.HS, anHSL);
|
colorData = new ColorData(ColorData.ColorMode.HS, anHSL);
|
||||||
} else if (hueInc != null || satInc != null) {
|
} else if (hueInc != null || satInc != null) {
|
||||||
anHSL = new HueSatBri();
|
anHSL = new HueSatBri();
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import java.net.URI;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
|
|
||||||
import org.apache.http.client.ClientProtocolException;
|
import org.apache.http.client.ClientProtocolException;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
@@ -154,7 +152,7 @@ public class HTTPHandler {
|
|||||||
} catch (ClientProtocolException e) {
|
} catch (ClientProtocolException e) {
|
||||||
log.warn("Client Protocol Exception received, retyring....");
|
log.warn("Client Protocol Exception received, retyring....");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.warn("Error calling out to HA gateway: IOException in log: " + e.getMessage());
|
log.warn("Error calling out to HA gateway: IOException in log: " + e.getMessage(), e);
|
||||||
retryCount = 2;
|
retryCount = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ public final class HttpClientPool {
|
|||||||
// Just one of me so constructor will be called once.
|
// Just one of me so constructor will be called once.
|
||||||
SSLClient;
|
SSLClient;
|
||||||
// The thread-safe client.
|
// The thread-safe client.
|
||||||
private final CloseableHttpClient threadSafeClient;
|
private CloseableHttpClient threadSafeClient;
|
||||||
// The pool monitor.
|
// The pool monitor.
|
||||||
private final IdleConnectionMonitorThread monitor;
|
private IdleConnectionMonitorThread monitor = null;
|
||||||
private TrustStrategy acceptingTrustStrategy = null;
|
private TrustStrategy acceptingTrustStrategy = null;
|
||||||
private SSLContext sslContext = null;
|
private SSLContext sslContext = null;
|
||||||
private SSLConnectionSocketFactory sslsf = null;
|
private SSLConnectionSocketFactory sslsf = null;
|
||||||
@@ -73,27 +73,33 @@ public final class HttpClientPool {
|
|||||||
|
|
||||||
// The constructor creates it - thus late
|
// The constructor creates it - thus late
|
||||||
private SingletonSSL() {
|
private SingletonSSL() {
|
||||||
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
|
|
||||||
// Increase max total connection to 200
|
|
||||||
cm.setMaxTotal(200);
|
|
||||||
// Increase default max connection per route to 20
|
|
||||||
cm.setDefaultMaxPerRoute(20);
|
|
||||||
try {
|
try {
|
||||||
acceptingTrustStrategy = (cert, authType) -> true;
|
acceptingTrustStrategy = (cert, authType) -> true;
|
||||||
hostnameVerifier = new NoopHostnameVerifier();
|
hostnameVerifier = new NoopHostnameVerifier();
|
||||||
sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
|
sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
|
||||||
sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
|
sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
|
||||||
|
HttpClientPool.log.info("Instantiated SSL components.");
|
||||||
|
final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
|
||||||
|
.register("http", new PlainConnectionSocketFactory())
|
||||||
|
.register("https", sslsf)
|
||||||
|
.build();
|
||||||
|
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
|
||||||
|
// Increase max total connection to 200
|
||||||
|
cm.setMaxTotal(200);
|
||||||
|
// Increase default max connection per route to 20
|
||||||
|
cm.setDefaultMaxPerRoute(20);
|
||||||
|
|
||||||
|
// Build the client.
|
||||||
|
threadSafeClient = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm).build();
|
||||||
|
// Start up an eviction thread.
|
||||||
|
monitor = new IdleConnectionMonitorThread(cm);
|
||||||
|
// Don't stop quitting.
|
||||||
|
monitor.setDaemon(true);
|
||||||
|
monitor.start();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
HttpClientPool.log.warn("SingletonSSL failed on SSL init");
|
HttpClientPool.log.warn("SingletonSSL failed on SSL init");
|
||||||
|
threadSafeClient = null;
|
||||||
}
|
}
|
||||||
// Build the client.
|
|
||||||
threadSafeClient = HttpClients.custom().setConnectionManager(cm).setSSLSocketFactory(sslsf)
|
|
||||||
.setSSLHostnameVerifier(hostnameVerifier).build();
|
|
||||||
// Start up an eviction thread.
|
|
||||||
monitor = new IdleConnectionMonitorThread(cm);
|
|
||||||
// Don't stop quitting.
|
|
||||||
monitor.setDaemon(true);
|
|
||||||
monitor.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CloseableHttpClient get() {
|
public CloseableHttpClient get() {
|
||||||
|
|||||||
@@ -1,18 +1,25 @@
|
|||||||
package com.bwssystems.HABridge.plugins.moziot;
|
package com.bwssystems.HABridge.plugins.moziot;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
public class MozIotCommand {
|
public class MozIotCommand {
|
||||||
|
@SerializedName("url")
|
||||||
|
@Expose
|
||||||
private String url;
|
private String url;
|
||||||
private String command;
|
@SerializedName("command")
|
||||||
|
@Expose
|
||||||
|
private MozIotCommandDetail command;
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
public void setUrl(String url) {
|
public void setUrl(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
public String getCommand() {
|
public MozIotCommandDetail getCommand() {
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
public void setCommand(String command) {
|
public void setCommand(MozIotCommandDetail command) {
|
||||||
this.command = command;
|
this.command = command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.bwssystems.HABridge.plugins.moziot;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
public class MozIotCommandDetail {
|
||||||
|
@SerializedName("on")
|
||||||
|
@Expose
|
||||||
|
private boolean on;
|
||||||
|
@SerializedName("level")
|
||||||
|
@Expose
|
||||||
|
private String level;
|
||||||
|
@SerializedName("color")
|
||||||
|
@Expose
|
||||||
|
private String color;
|
||||||
|
|
||||||
|
public boolean isOn() {
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOn(boolean on) {
|
||||||
|
this.on = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevel(String level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColor(String color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBody() {
|
||||||
|
String theBody = "";
|
||||||
|
|
||||||
|
if(level != null && level != "") {
|
||||||
|
theBody = "{\"level\":" + level + "}";
|
||||||
|
}
|
||||||
|
else if(color != null && color != "") {
|
||||||
|
theBody = "{\"color\":\"" + color + "\"}";
|
||||||
|
} else {
|
||||||
|
theBody = "{\"on\":" + on + "}";
|
||||||
|
}
|
||||||
|
return theBody;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.bwssystems.HABridge.plugins.moziot;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
public class MozIotDevice {
|
||||||
|
@SerializedName("gatewayName")
|
||||||
|
@Expose
|
||||||
|
private String gatewayName;
|
||||||
|
@SerializedName("deviceDetail")
|
||||||
|
@Expose
|
||||||
|
private MozillaThing deviceDetail;
|
||||||
|
|
||||||
|
public String getGatewayName() {
|
||||||
|
return gatewayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGatewayName(String gatewayName) {
|
||||||
|
this.gatewayName = gatewayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MozillaThing getDeviceDetail() {
|
||||||
|
return deviceDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceDetail(MozillaThing deviceDetail) {
|
||||||
|
this.deviceDetail = deviceDetail;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,13 +26,13 @@ import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
|||||||
import com.bwssystems.HABridge.plugins.http.HTTPHome;
|
import com.bwssystems.HABridge.plugins.http.HTTPHome;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
public class MozIotHome implements Home {
|
public class MozIotHome implements Home {
|
||||||
private static final Logger log = LoggerFactory.getLogger(MozIotHome.class);
|
private static final Logger log = LoggerFactory.getLogger(MozIotHome.class);
|
||||||
private Map<String, MozIotInstance> moziotMap;
|
private Map<String, MozIotInstance> moziotMap;
|
||||||
private Boolean validMoziot;
|
private Boolean validMoziot;
|
||||||
private HTTPHandler httpClient;
|
private HTTPHandler httpClient;
|
||||||
private boolean closed;
|
private boolean closed;
|
||||||
|
|
||||||
public MozIotHome(BridgeSettings bridgeSettings) {
|
public MozIotHome(BridgeSettings bridgeSettings) {
|
||||||
super();
|
super();
|
||||||
closed = true;
|
closed = true;
|
||||||
@@ -47,71 +47,68 @@ public class MozIotHome implements Home {
|
|||||||
String theUrl = anItem.getItem().getAsString();
|
String theUrl = anItem.getItem().getAsString();
|
||||||
String responseString = null;
|
String responseString = null;
|
||||||
|
|
||||||
if(theUrl != null && !theUrl.isEmpty()) {
|
if (theUrl != null && !theUrl.isEmpty()) {
|
||||||
|
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrl, intensity, targetBri, targetBriInc,
|
||||||
|
false);
|
||||||
|
if (colorData != null) {
|
||||||
|
anUrl = ColorDecode.replaceColorData(anUrl, colorData,
|
||||||
|
BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), true);
|
||||||
|
}
|
||||||
|
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
|
||||||
|
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
||||||
|
|
||||||
|
anUrl = BrightnessDecode.calculateReplaceIntensityValue(anUrl, intensity, targetBri, targetBriInc, false);
|
||||||
|
if (colorData != null) {
|
||||||
|
anUrl = ColorDecode.replaceColorData(anUrl, colorData,
|
||||||
|
BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||||
|
}
|
||||||
|
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
|
||||||
|
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
||||||
|
|
||||||
MozIotCommand theCommand = null;
|
MozIotCommand theCommand = null;
|
||||||
try {
|
try {
|
||||||
theUrl = theUrl.replaceAll("^\"|\"$", "");
|
theUrl = theUrl.replaceAll("^\"|\"$", "");
|
||||||
theCommand = new Gson().fromJson(theUrl, MozIotCommand.class);
|
theCommand = new Gson().fromJson(anUrl, MozIotCommand.class);
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Cannot parse command to Mozilla IOT <<<" + theUrl + ">>>", e);
|
log.warn("Cannot parse command to Mozilla IOT <<<" + theUrl + ">>>", e);
|
||||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||||
"Error on calling url to change device state", "/lights/"
|
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
.getTheErrors(), HueError[].class);
|
||||||
return responseString;
|
return responseString;
|
||||||
}
|
}
|
||||||
String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("://") + 3);
|
|
||||||
String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
|
String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("/things/") + 8);
|
||||||
String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
|
String devicePortion = intermediate.substring(0, intermediate.indexOf('/'));
|
||||||
String hostAddr = null;
|
String theUrlCommand = intermediate.substring(intermediate.indexOf('/') + 1);
|
||||||
if (hostPortion.contains(":")) {
|
MozIotInstance theHandler = moziotMap.get(device.getTargetDevice());
|
||||||
hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
|
if (theHandler != null) {
|
||||||
} else
|
try {
|
||||||
hostAddr = hostPortion;
|
boolean success = theHandler.callCommand(devicePortion, theUrlCommand, theCommand.getCommand(), httpClient);
|
||||||
MozIotInstance theHandler = findHandlerByAddress(hostAddr);
|
if (!success) {
|
||||||
if(theHandler != null) {
|
log.warn("Comand had error to Mozilla IOT");
|
||||||
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody,
|
|
||||||
intensity, targetBri, targetBriInc, false);
|
|
||||||
if (colorData != null) {
|
|
||||||
anUrl = ColorDecode.replaceColorData(anUrl, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
|
||||||
}
|
|
||||||
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
|
|
||||||
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
|
||||||
|
|
||||||
String aCommand = null;
|
|
||||||
if(theCommand.getCommand() != null && !theCommand.getCommand().isEmpty()) {
|
|
||||||
aCommand = BrightnessDecode.calculateReplaceIntensityValue(theCommand.getCommand(),
|
|
||||||
intensity, targetBri, targetBriInc, false);
|
|
||||||
if (colorData != null) {
|
|
||||||
aCommand = ColorDecode.replaceColorData(aCommand, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
|
||||||
}
|
|
||||||
aCommand = DeviceDataDecode.replaceDeviceData(aCommand, device);
|
|
||||||
aCommand = TimeDecode.replaceTimeValue(aCommand);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
boolean success = theHandler.callCommand(anUrl, aCommand, httpClient);
|
|
||||||
if(!success) {
|
|
||||||
log.warn("Comand had error to Mozilla IOT");
|
|
||||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||||
"Error on calling url to change device state", "/lights/"
|
"Error on calling url to change device state", "/lights/" + lightId + "/state", null,
|
||||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
null).getTheErrors(), HueError[].class);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Cannot send comand to Mozilla IOT", e);
|
log.warn("Cannot send comand to Mozilla IOT", e);
|
||||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||||
"Error on calling url to change device state", "/lights/"
|
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
.getTheErrors(), HueError[].class);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("Mozilla IOT Call could not complete, no address found: " + theUrl);
|
log.warn("Mozilla IOT Call could not complete, no address found: " + theUrl);
|
||||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||||
"Error on calling url to change device state", "/lights/"
|
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
.getTheErrors(), HueError[].class);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("Mozilla IOT Call to be presented as http(s)://<ip_address>(:<port>)/payload, format of request unknown: " + theUrl);
|
log.warn(
|
||||||
|
"Mozilla IOT Call to be presented as http(s)://<ip_address>(:<port>)/payload, format of request unknown: "
|
||||||
|
+ theUrl);
|
||||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||||
"Error on calling url to change device state", "/lights/"
|
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
.getTheErrors(), HueError[].class);
|
||||||
}
|
}
|
||||||
return responseString;
|
return responseString;
|
||||||
}
|
}
|
||||||
@@ -119,16 +116,16 @@ public class MozIotHome implements Home {
|
|||||||
@Override
|
@Override
|
||||||
public Object getItems(String type) {
|
public Object getItems(String type) {
|
||||||
|
|
||||||
if(!validMoziot)
|
if (!validMoziot)
|
||||||
return null;
|
return null;
|
||||||
log.debug("consolidating devices for Mozilla IOT");
|
log.debug("consolidating devices for Mozilla IOT");
|
||||||
List<MozillaThing> theResponse = null;
|
List<MozillaThing> theResponse = null;
|
||||||
Iterator<String> keys = moziotMap.keySet().iterator();
|
Iterator<String> keys = moziotMap.keySet().iterator();
|
||||||
List<MozillaThing> deviceList = new ArrayList<MozillaThing>();
|
List<MozIotDevice> deviceList = new ArrayList<MozIotDevice>();
|
||||||
while(keys.hasNext()) {
|
while (keys.hasNext()) {
|
||||||
String key = keys.next();
|
String key = keys.next();
|
||||||
theResponse = moziotMap.get(key).getDevices(httpClient);
|
theResponse = moziotMap.get(key).getDevices(httpClient);
|
||||||
if(theResponse != null)
|
if (theResponse != null)
|
||||||
addMozIotDevices(deviceList, theResponse, key);
|
addMozIotDevices(deviceList, theResponse, key);
|
||||||
else {
|
else {
|
||||||
log.warn("Cannot get devices for Mozilla IOT with name: " + key + ", skipping this Mozilla IOT.");
|
log.warn("Cannot get devices for Mozilla IOT with name: " + key + ", skipping this Mozilla IOT.");
|
||||||
@@ -137,11 +134,15 @@ public class MozIotHome implements Home {
|
|||||||
}
|
}
|
||||||
return deviceList;
|
return deviceList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Boolean addMozIotDevices(List<MozillaThing> theDeviceList, List<MozillaThing> theSourceList, String theKey) {
|
private Boolean addMozIotDevices(List<MozIotDevice> theDeviceList, List<MozillaThing> theSourceList,
|
||||||
Iterator<MozillaThing> devices = theSourceList.iterator();
|
String theKey) {
|
||||||
while(devices.hasNext()) {
|
Iterator<MozillaThing> things = theSourceList.iterator();
|
||||||
MozillaThing theDevice = devices.next();
|
while (things.hasNext()) {
|
||||||
|
MozillaThing theThing = things.next();
|
||||||
|
MozIotDevice theDevice = new MozIotDevice();
|
||||||
|
theDevice.setDeviceDetail(theThing);
|
||||||
|
theDevice.setGatewayName(theKey);
|
||||||
theDeviceList.add(theDevice);
|
theDeviceList.add(theDevice);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -152,57 +153,42 @@ public class MozIotHome implements Home {
|
|||||||
moziotMap = null;
|
moziotMap = null;
|
||||||
validMoziot = bridgeSettings.getBridgeSettingsDescriptor().isValidMozIot();
|
validMoziot = bridgeSettings.getBridgeSettingsDescriptor().isValidMozIot();
|
||||||
log.info("Mozilla IOT Home created." + (validMoziot ? "" : " No Mozilla IOTs configured."));
|
log.info("Mozilla IOT Home created." + (validMoziot ? "" : " No Mozilla IOTs configured."));
|
||||||
if(validMoziot) {
|
if (validMoziot) {
|
||||||
moziotMap = new HashMap<String,MozIotInstance>();
|
moziotMap = new HashMap<String, MozIotInstance>();
|
||||||
httpClient = HTTPHome.getHandler();
|
httpClient = HTTPHome.getHandler();
|
||||||
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getMoziotaddress().getDevices().iterator();
|
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getMoziotaddress().getDevices()
|
||||||
while(theList.hasNext() && validMoziot) {
|
.iterator();
|
||||||
|
while (theList.hasNext() && validMoziot) {
|
||||||
NamedIP aMoziot = theList.next();
|
NamedIP aMoziot = theList.next();
|
||||||
try {
|
try {
|
||||||
moziotMap.put(aMoziot.getName(), new MozIotInstance(aMoziot, httpClient));
|
moziotMap.put(aMoziot.getName(), new MozIotInstance(aMoziot, httpClient));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Cannot get Mozilla IOT (" + aMoziot.getName() + ") setup, Exiting with message: " + e.getMessage(), e);
|
log.error("Cannot get Mozilla IOT (" + aMoziot.getName() + ") setup, Exiting with message: "
|
||||||
validMoziot = false;
|
+ e.getMessage(), e);
|
||||||
|
validMoziot = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MozIotInstance findHandlerByAddress(String hostAddress) {
|
|
||||||
MozIotInstance aHandler = null;
|
|
||||||
boolean found = false;
|
|
||||||
Iterator<String> keys = moziotMap.keySet().iterator();
|
|
||||||
while(keys.hasNext()) {
|
|
||||||
String key = keys.next();
|
|
||||||
aHandler = moziotMap.get(key);
|
|
||||||
if(aHandler != null && aHandler.getMozIotIP().getIp().equals(hostAddress)) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(!found)
|
return this;
|
||||||
aHandler = null;
|
|
||||||
return aHandler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeHome() {
|
public void closeHome() {
|
||||||
log.debug("Closing Home.");
|
log.debug("Closing Home.");
|
||||||
if(!closed && validMoziot) {
|
if (!closed && validMoziot) {
|
||||||
log.debug("Home is already closed....");
|
log.debug("Home is already closed....");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(httpClient != null)
|
if (httpClient != null)
|
||||||
httpClient.closeHandler();
|
httpClient.closeHandler();
|
||||||
|
|
||||||
moziotMap = null;
|
moziotMap = null;
|
||||||
closed = true;
|
closed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ public class MozIotInstance {
|
|||||||
gatewayLogin(httpClient);
|
gatewayLogin(httpClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean callCommand(String aCommand, String commandData, HTTPHandler httpClient) {
|
public Boolean callCommand(String deviceId, String aCommand, MozIotCommandDetail commandData, HTTPHandler httpClient) {
|
||||||
log.debug("calling Mozilla IOT: " + mozIotIP.getIp() + ":" + mozIotIP.getPort() + aCommand);
|
log.debug("calling Mozilla IOT: {}:{}{}{}", mozIotIP.getIp(), mozIotIP.getPort(), aCommand, commandData.getBody());
|
||||||
String aUrl = null;
|
String aUrl = null;
|
||||||
|
|
||||||
if (mozIotIP.getSecure() != null && mozIotIP.getSecure())
|
if (mozIotIP.getSecure() != null && mozIotIP.getSecure())
|
||||||
@@ -36,9 +36,9 @@ public class MozIotInstance {
|
|||||||
aUrl = "http://";
|
aUrl = "http://";
|
||||||
headers = getAuthHeader();
|
headers = getAuthHeader();
|
||||||
|
|
||||||
aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/" + aCommand;
|
aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/things/" + deviceId + "/" + aCommand;
|
||||||
String theData = httpClient.doHttpRequest(aUrl, HttpPut.METHOD_NAME, "application/json", commandData, headers);
|
String theData = httpClient.doHttpRequest(aUrl, HttpPut.METHOD_NAME, "application/json", commandData.getBody(), headers);
|
||||||
log.debug("call Command return is: <" + theData + ">");
|
log.debug("call Command return is: <<<{}>>>", theData);
|
||||||
if (theData.contains("error") || theData.contains("ERROR") || theData.contains("Error"))
|
if (theData.contains("error") || theData.contains("ERROR") || theData.contains("Error"))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@@ -70,7 +70,7 @@ public class MozIotInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Cannot get an devices for Mozilla IOT " + mozIotIP.getName() + " Gson Parse Error.");
|
log.warn("Cannot get an devices for Mozilla IOT {} Gson Parse Error.", mozIotIP.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return deviceList;
|
return deviceList;
|
||||||
@@ -78,11 +78,17 @@ public class MozIotInstance {
|
|||||||
|
|
||||||
private NameValue[] getAuthHeader() {
|
private NameValue[] getAuthHeader() {
|
||||||
if (headers == null) {
|
if (headers == null) {
|
||||||
headers = new NameValue[1];
|
headers = new NameValue[3];
|
||||||
headers[0] = new NameValue();
|
headers[0] = new NameValue();
|
||||||
headers[0].setName("Authorization");
|
headers[0].setName("Authorization");
|
||||||
headers[0].setValue("Bearer " + moziotToken.getJwt());
|
headers[0].setValue("Bearer " + moziotToken.getJwt());
|
||||||
}
|
headers[1] = new NameValue();
|
||||||
|
headers[1].setName("Content-Type");
|
||||||
|
headers[1].setValue("application/json");
|
||||||
|
headers[2] = new NameValue();
|
||||||
|
headers[2].setName("Accept");
|
||||||
|
headers[2].setValue("application/json");
|
||||||
|
}
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,20 +108,20 @@ public class MozIotInstance {
|
|||||||
headers[1].setName("Accept");
|
headers[1].setName("Accept");
|
||||||
headers[1].setValue("application/json");
|
headers[1].setValue("application/json");
|
||||||
aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/login";
|
aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/login";
|
||||||
log.info("gateway login URL: " + aUrl);
|
log.debug("gateway login URL: {}", aUrl);
|
||||||
String commandData = "{\"email\": \"" + mozIotIP.getUsername() + "\", \"password\":\"" + mozIotIP.getPassword()
|
String commandData = "{\"email\": \"" + mozIotIP.getUsername() + "\", \"password\":\"" + mozIotIP.getPassword()
|
||||||
+ "\"}";
|
+ "\"}";
|
||||||
log.info("The login body: " + commandData);
|
log.debug("The login body: {}", commandData);
|
||||||
String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", commandData, headers);
|
String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", commandData, headers);
|
||||||
if (theData != null) {
|
if (theData != null) {
|
||||||
log.info("GET Mozilla login - data: " + theData);
|
log.debug("GET Mozilla login - data: {}", theData);
|
||||||
try {
|
try {
|
||||||
moziotToken = new Gson().fromJson(theData, JWT.class);
|
moziotToken = new Gson().fromJson(theData, JWT.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Cannot get login for Mozilla IOT " + mozIotIP.getName() + " Gson Parse Error.");
|
log.warn("Cannot get login for Mozilla IOT {} Gson Parse Error.", mozIotIP.getName());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("Could not login " + mozIotIP.getName() + " error: <<<" + theData + ">>>");
|
log.warn("Could not login {} error: <<<{}>>>", mozIotIP.getName(), theData);
|
||||||
}
|
}
|
||||||
|
|
||||||
headers = null;
|
headers = null;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,8 @@
|
|||||||
<li ng-if="bridge.showHomeWizard" role="presentation"><a href="#!/homewizarddevices">HomeWizard Devices</a></li>
|
<li ng-if="bridge.showHomeWizard" role="presentation"><a href="#!/homewizarddevices">HomeWizard Devices</a></li>
|
||||||
<li ng-if="bridge.showOpenHAB" role="presentation"><a href="#!/openhabdevices">OpenHAB Devices</a></li>
|
<li ng-if="bridge.showOpenHAB" role="presentation"><a href="#!/openhabdevices">OpenHAB Devices</a></li>
|
||||||
<li ng-if="bridge.showFHEM" role="presentation"><a href="#!/fhemdevices">FHEM Devices</a></li>
|
<li ng-if="bridge.showFHEM" role="presentation"><a href="#!/fhemdevices">FHEM Devices</a></li>
|
||||||
<li ng-if="bridge.showMozIot" role="presentation" class="active"><a href="#!/moziotdevices">Mozilla IOT Devices</a></li>
|
<li ng-if="bridge.showMozIot" role="presentation" class="active"><a href="#!/moziotdevices">Mozilla IOT Devices</a>
|
||||||
|
</li>
|
||||||
<li ng-if="bridge.showBroadlink" role="presentation"><a href="#!/broadlinkdevices">Broadlink Devices</a></li>
|
<li ng-if="bridge.showBroadlink" role="presentation"><a href="#!/broadlinkdevices">Broadlink Devices</a></li>
|
||||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -31,17 +32,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<p class="text-muted">For any Mozilla IOT Device, use the build action buttons
|
<p class="text-muted">For any Mozilla IOT Device, use the build action buttons
|
||||||
to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then
|
to generate the item addition information into the ha-bridge device and this will put you into the edit
|
||||||
|
screen. Then
|
||||||
you can modify the name to anything you want that will be the keyword
|
you can modify the name to anything you want that will be the keyword
|
||||||
for the Echo or Google Home. Also, you can go back to any helper tab and click a build
|
for the Echo or Google Home. Also, you can go back to any helper tab and click a build
|
||||||
action button to add another item for a multi-command. After you are
|
action button to add another item for a multi-command. After you are
|
||||||
done in the edit tab, click the 'Add Bridge Device' to finish that selection
|
done in the edit tab, click the 'Add Bridge Device' to finish that selection
|
||||||
setup. The 'Already Configured Mozilla IOT Devices' list below will show what
|
setup. The 'Already Configured Mozilla IOT Devices' list below will show what
|
||||||
is already setup for your Mozilla IOT.</p>
|
is already setup for your Mozilla IOT.</p>
|
||||||
<p class="text-muted">
|
<p class="text-muted">
|
||||||
Also, use this select menu for which type of dim control you would
|
Also, use this select menu for which type of dim control you would
|
||||||
like to be generated: <select name="device-dim-control"
|
like to be generated: <select name="device-dim-control" id="device-dim-control"
|
||||||
id="device-dim-control" ng-model="device_dim_control">
|
ng-model="device_dim_control">
|
||||||
<option value="">none</option>
|
<option value="">none</option>
|
||||||
<option value="${intensity.byte}">Pass-thru Value</option>
|
<option value="${intensity.byte}">Pass-thru Value</option>
|
||||||
<option value="${intensity.percent}">Percentage</option>
|
<option value="${intensity.percent}">Percentage</option>
|
||||||
@@ -53,94 +55,91 @@
|
|||||||
feature. Select your items and dim control type if wanted, then click
|
feature. Select your items and dim control type if wanted, then click
|
||||||
bulk add below. Your items will be added with on and off or dim and
|
bulk add below. Your items will be added with on and off or dim and
|
||||||
off if selected with the name of the device from the Mozilla IOT.</p>
|
off if selected with the name of the device from the Mozilla IOT.</p>
|
||||||
<scrollable-table watch="bridge.moziotdevices">
|
<scrollable-table watch="bridge.moziotdevices">
|
||||||
<table class="table table-bordered table-striped table-hover">
|
<table class="table table-bordered table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Row</th>
|
<th>Row</th>
|
||||||
<th sortable-header col="name">
|
<th sortable-header col="name">
|
||||||
<span><input type="checkbox" name="selectAll"
|
<span><input type="checkbox" name="selectAll" value="{{selectAll}}" ng-checked="selectAll"
|
||||||
value="{{selectAll}}"
|
ng-click="toggleSelectAll()"> Name</span></th>
|
||||||
ng-checked="selectAll"
|
<th sortable-header col="type">Type</th>
|
||||||
ng-click="toggleSelectAll()"> Name</span></th>
|
<th sortable-header col="moziotname">Mozilla IOT</th>
|
||||||
<th sortable-header col="type">Type</th>
|
<th col="string-actions">Color Actions</th>
|
||||||
<th sortable-header col="moziotname">Mozilla IOT</th>
|
<th>Build Actions</th>
|
||||||
<th col="string-actions">Color Actions</th>
|
</tr>
|
||||||
<th>Build Actions</th>
|
</thead>
|
||||||
</tr>
|
<tr ng-repeat="moziotdevice in bridge.moziotdevices">
|
||||||
</thead>
|
<td>{{$index+1}}</td>
|
||||||
<tr ng-repeat="moziotdevice in bridge.moziotdevices">
|
<td><input type="checkbox" name="bulk.devices[]" value="{{moziotdevice.deviceDetail.name}}"
|
||||||
<td>{{$index+1}}</td>
|
ng-checked="bulk.devices.indexOf(moziotdevice.deviceDetail.name) > -1"
|
||||||
<td><input type="checkbox" name="bulk.devices[]"
|
ng-click="toggleSelection(moziotdevice.deviceDetail.name)">
|
||||||
value="{{moziotdevice.item.name}}"
|
{{moziotdevice.deviceDetail.name}}</td>
|
||||||
ng-checked="bulk.devices.indexOf(moziotdevice.item.name) > -1"
|
<td>{{moziotdevice.deviceDetail.type}}</td>
|
||||||
ng-click="toggleSelection(moziotdevice.item.name)">
|
<td>{{moziotdevice.gatewayName}}</td>
|
||||||
{{moziotdevice.name}}</td>
|
<td>
|
||||||
<td>{{moziotdevice.type}}</td>
|
<select name="color-device-action" id="color-device-action" ng-model="coloraction">
|
||||||
<td>{{moziotdevice.name}}</td>
|
<option value="">None</option>
|
||||||
<td>
|
<option value="#${color.r}${color.g}${color.b}">RGB Hex String</option>
|
||||||
<input id="color-input-device-action"
|
<option value="other">Other</option>
|
||||||
class="form-control" type="text"
|
</select>
|
||||||
ng-model="colordata"
|
<input ng-if="coloraction === 'other'" id="color-input-device-action" class="form-control"
|
||||||
placeholder="R,G,B">
|
type="text" ng-model="colordata" placeholder="Input color info">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-success" type="submit"
|
<button class="btn btn-success" type="submit"
|
||||||
ng-click="buildDeviceUrls(moziotdevice, device_dim_control, colordata, false)">Build Item</button>
|
ng-click="buildDeviceUrls(moziotdevice, device_dim_control, coloraction, colordata, false)">Build
|
||||||
</td>
|
Item</button>
|
||||||
</tr>
|
</td>
|
||||||
</table>
|
</tr>
|
||||||
</scrollable-table>
|
</table>
|
||||||
<div class="panel-footer">
|
</scrollable-table>
|
||||||
<button class="btn btn-success" type="submit"
|
<div class="panel-footer">
|
||||||
ng-click="bulkAddDevices(device_dim_control)">Bulk Add
|
<button class="btn btn-success" type="submit" ng-click="bulkAddDevices(device_dim_control)">Bulk Add
|
||||||
({{bulk.devices.length}})</button>
|
({{bulk.devices.length}})</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">
|
<h2 class="panel-title">
|
||||||
Already Configured OpenHAB Devices <a ng-click="toggleButtons()"><span
|
Already Configured OpenHAB Devices <a ng-click="toggleButtons()"><span class={{imgButtonsUrl}}
|
||||||
class={{imgButtonsUrl}} aria-hidden="true"></span></a></a>
|
aria-hidden="true"></span></a></a>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="buttonsVisible" class="panel-body">
|
<div ng-if="buttonsVisible" class="panel-body">
|
||||||
|
|
||||||
<scrollable-table watch="bridge.moziotdevices">
|
<scrollable-table watch="bridge.moziotdevices">
|
||||||
<table class="table table-bordered table-striped table-hover">
|
<table class="table table-bordered table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Row</th>
|
<th>Row</th>
|
||||||
<th sortable-header col="name">Name</th>
|
<th sortable-header col="name">Name</th>
|
||||||
<th sortable-header col="category">Category</th>
|
<th sortable-header col="category">Category</th>
|
||||||
<th sortable-header col="moziotname">Mozilla IOT</th>
|
<th sortable-header col="moziotname">Mozilla IOT</th>
|
||||||
<th>Map Id</th>
|
<th>Map Id</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tr
|
<tr ng-repeat="device in bridge.devices | configuredMozIotItems">
|
||||||
ng-repeat="device in bridge.devices | configuredMozIotItems">
|
<td>{{$index+1}}</td>
|
||||||
<td>{{$index+1}}</td>
|
<td>{{device.name}}</td>
|
||||||
<td>{{device.name}}</td>
|
<td>{{device.deviceType}}</td>
|
||||||
<td>{{device.deviceType}}</td>
|
<td>{{device.targetDevice}}</td>
|
||||||
<td>{{device.targetDevice}}</td>
|
<td>{{device.mapId}}</td>
|
||||||
<td>{{device.mapId}}</td>
|
<td>
|
||||||
<td>
|
<p>
|
||||||
<p>
|
<button class="btn btn-warning" type="submit" ng-click="editDevice(device)">Edit</button>
|
||||||
<button class="btn btn-warning" type="submit"
|
<button class="btn btn-danger" type="submit" ng-click="deleteDevice(device)">Delete</button>
|
||||||
ng-click="editDevice(device)">Edit</button>
|
</p>
|
||||||
<button class="btn btn-danger" type="submit"
|
</td>
|
||||||
ng-click="deleteDevice(device)">Delete</button>
|
</tr>
|
||||||
</p>
|
</table>
|
||||||
</td>
|
</scrollable-table>
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</scrollable-table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/ng-template" id="deleteMapandIdDialog">
|
<script type="text/ng-template" id="deleteMapandIdDialog">
|
||||||
<div class="ngdialog-message">
|
<div class="ngdialog-message">
|
||||||
<h2>Device Map and Id?</h2>
|
<h2>Device Map and Id?</h2>
|
||||||
<p>{{mapandid.mapType}} with {{mapandid.id}}</p>
|
<p>{{mapandid.mapType}} with {{mapandid.id}}</p>
|
||||||
<p>Are you Sure?</p>
|
<p>Are you Sure?</p>
|
||||||
@@ -148,4 +147,4 @@
|
|||||||
<div class="ngdialog-buttons mt">
|
<div class="ngdialog-buttons mt">
|
||||||
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteMapandId(mapandid)">Delete</button>
|
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteMapandId(mapandid)">Delete</button>
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
value="{{option.value}}">{{option.label}}</option>
|
value="{{option.value}}">{{option.label}}</option>
|
||||||
<option value="other">Other</option>
|
<option value="other">Other</option>
|
||||||
</select>
|
</select>
|
||||||
<inpu ng-if="coloraction === 'other'"t id="color-input-device-action"
|
<input ng-if="coloraction === 'other'"t id="color-input-device-action"
|
||||||
class="form-control" type="text"
|
class="form-control" type="text"
|
||||||
ng-model="colordata"
|
ng-model="colordata"
|
||||||
placeholder="Type Action if Other">
|
placeholder="Type Action if Other">
|
||||||
|
|||||||
Reference in New Issue
Block a user