Basic OpenHAB functionality added. Need to add String selection

functionality.
This commit is contained in:
Admin
2017-12-15 16:34:58 -06:00
parent 4b247557d4
commit fe613f7688
16 changed files with 670 additions and 132 deletions

View File

@@ -210,6 +210,7 @@ public class BridgeSettings extends BackupHandler {
theBridgeSettings.setDomoticzconfigured(theBridgeSettings.isValidDomoticz());
theBridgeSettings.setSomfyconfigured(theBridgeSettings.isValidSomfy());
theBridgeSettings.setHomeWizardConfigured(theBridgeSettings.isValidHomeWizard());
theBridgeSettings.setOpenhabconfigured(theBridgeSettings.isValidOpenhab());
// Lifx is either configured or not, so it does not need an update.
if(serverPortOverride != null)
theBridgeSettings.setServerPort(serverPortOverride);

View File

@@ -31,6 +31,7 @@ public class DeviceMapTypes {
public final static String[] DOMOTICZ_DEVICE = { "domoticzDevice", "Domoticz Device"};
public final static String[] SOMFY_DEVICE = { "somfyDevice", "Somfy Device"};
public final static String[] LIFX_DEVICE = { "lifxDevice", "LIFX Device"};
public final static String[] OPENHAB_DEVICE = { "openhabDevice", "OpenHAB Device"};
public final static int typeIndex = 0;
public final static int displayIndex = 1;
@@ -56,7 +57,6 @@ public class DeviceMapTypes {
deviceMapTypes.add(MQTT_MESSAGE);
deviceMapTypes.add(NEST_HOMEAWAY);
deviceMapTypes.add(NEST_THERMO_SET);
deviceMapTypes.add(SOMFY_DEVICE);
deviceMapTypes.add(TCP_DEVICE);
deviceMapTypes.add(UDP_DEVICE);
deviceMapTypes.add(VERA_DEVICE);
@@ -64,6 +64,7 @@ public class DeviceMapTypes {
deviceMapTypes.add(FIBARO_DEVICE);
deviceMapTypes.add(FIBARO_SCENE);
deviceMapTypes.add(SOMFY_DEVICE);
deviceMapTypes.add(OPENHAB_DEVICE);
}
public static int getTypeIndex() {
return typeIndex;

View File

@@ -19,6 +19,7 @@ import com.bwssystems.HABridge.plugins.http.HTTPHome;
import com.bwssystems.HABridge.plugins.hue.HueHome;
import com.bwssystems.HABridge.plugins.lifx.LifxHome;
import com.bwssystems.HABridge.plugins.mqtt.MQTTHome;
import com.bwssystems.HABridge.plugins.openhab.OpenHABHome;
import com.bwssystems.HABridge.plugins.somfy.SomfyHome;
import com.bwssystems.HABridge.plugins.tcp.TCPHome;
import com.bwssystems.HABridge.plugins.udp.UDPHome;
@@ -113,6 +114,10 @@ public class HomeManager {
aHome = new LifxHome(bridgeSettings);
resourceList.put(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex], aHome);
homeList.put(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex], aHome);
//setup the OpenHAB configuration if available
aHome = new OpenHABHome(bridgeSettings);
resourceList.put(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex], aHome);
homeList.put(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex], aHome);
}
public Home findHome(String type) {

View File

@@ -315,6 +315,12 @@ public class DeviceResource {
return homeManager.findResource(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex]);
}, new JsonTransformer());
get (API_CONTEXT + "/openhab/devices", "application/json", (request, response) -> {
log.debug("Get OpenHAB devices");
response.status(HttpStatus.SC_OK);
return homeManager.findResource(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex]);
}, new JsonTransformer());
get (API_CONTEXT + "/map/types", "application/json", (request, response) -> {
log.debug("Get map types");
return new DeviceMapTypes().getDeviceMapTypes();

View File

@@ -18,7 +18,10 @@ import com.bwssystems.HABridge.api.hue.HueErrorResponse;
import com.bwssystems.HABridge.dao.DeviceDescriptor;
import com.bwssystems.HABridge.hue.BrightnessDecode;
import com.bwssystems.HABridge.hue.ColorData;
import com.bwssystems.HABridge.hue.ColorDecode;
import com.bwssystems.HABridge.hue.DeviceDataDecode;
import com.bwssystems.HABridge.hue.MultiCommandUtil;
import com.bwssystems.HABridge.hue.TimeDecode;
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
import com.bwssystems.HABridge.plugins.http.HTTPHome;
import com.google.gson.Gson;
@@ -41,7 +44,7 @@ public class DomoticzHome implements Home {
public Object getItems(String type) {
if(!validDomoticz)
return null;
log.debug("consolidating devices for hues");
log.debug("consolidating devices for Domoticzs");
List<DomoticzDevice> theResponse = null;
Iterator<String> keys = domoticzs.keySet().iterator();
List<DomoticzDevice> deviceList = new ArrayList<DomoticzDevice>();
@@ -95,7 +98,23 @@ public class DomoticzHome implements Home {
String theData;
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody,
intensity, targetBri, targetBriInc, false);
theData = httpClient.doHttpRequest(theHandler.buildUrl(anUrl), null, null, null, theHandler.buildHeaders());
if (colorData != null) {
anUrl = ColorDecode.replaceColorData(anUrl, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
}
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
anUrl = TimeDecode.replaceTimeValue(anUrl);
String aBody = null;
if(anItem.getHttpBody()!= null && !anItem.getHttpBody().isEmpty()) {
aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(),
intensity, targetBri, targetBriInc, false);
if (colorData != null) {
aBody = ColorDecode.replaceColorData(aBody, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
}
aBody = DeviceDataDecode.replaceDeviceData(aBody, device);
aBody = TimeDecode.replaceTimeValue(aBody);
}
theData = httpClient.doHttpRequest(theHandler.buildUrl(anUrl), null, null, aBody, theHandler.buildHeaders());
try {
theDomoticzApiResponse = new Gson().fromJson(theData, Devices.class);
if(theDomoticzApiResponse.getStatus().equals("OK"))
@@ -167,7 +186,7 @@ public class DomoticzHome implements Home {
@Override
public void closeHome() {
log.debug("Closing Home.");
if(closed) {
if(closed || !validDomoticz) {
log.debug("Home is already closed....");
return;
}
@@ -175,6 +194,7 @@ public class DomoticzHome implements Home {
if(httpClient != null)
httpClient.closeHandler();
domoticzs = null;
closed = true;
}
}

View File

@@ -85,7 +85,7 @@ public class HomeWizardHome implements Home {
public List<HomeWizardSmartPlugDevice> getDevices() {
log.debug("consolidating devices for plug gateways");
log.debug("consolidating devices for HomeWizard plug gateways");
Iterator<String> keys = plugGateways.keySet().iterator();
ArrayList<HomeWizardSmartPlugDevice> deviceList = new ArrayList<>();

View File

@@ -0,0 +1,19 @@
package com.bwssystems.HABridge.plugins.openhab;
public class OpenHABCommand {
private String url;
private String command;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
}

View File

@@ -0,0 +1,27 @@
package com.bwssystems.HABridge.plugins.openhab;
public class OpenHABDevice {
private String address;
private String name;
private OpenHABItem item;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public OpenHABItem getItem() {
return item;
}
public void setItem(OpenHABItem item) {
this.item = item;
}
}

View File

@@ -1,7 +1,9 @@
package com.bwssystems.HABridge.plugins.openhab;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
@@ -11,17 +13,24 @@ import com.bwssystems.HABridge.BridgeSettings;
import com.bwssystems.HABridge.Home;
import com.bwssystems.HABridge.NamedIP;
import com.bwssystems.HABridge.api.CallItem;
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.ColorData;
import com.bwssystems.HABridge.hue.ColorDecode;
import com.bwssystems.HABridge.hue.DeviceDataDecode;
import com.bwssystems.HABridge.hue.MultiCommandUtil;
import com.bwssystems.HABridge.hue.TimeDecode;
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
import com.bwssystems.HABridge.plugins.http.HTTPHome;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class OpenHABHome implements Home {
private static final Logger log = LoggerFactory.getLogger(OpenHABHome.class);
private Map<String, OpenHABInstance> openhabMap;
private Boolean validOpenhab;
private Gson aGsonHandler;
private HTTPHandler httpClient;
private boolean closed;
public OpenHABHome(BridgeSettings bridgeSettings) {
@@ -35,34 +44,118 @@ public class OpenHABHome implements Home {
@Override
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
// TODO Auto-generated method stub
return null;
String theUrl = anItem.getItem().getAsString();
String responseString = null;
if(theUrl != null && !theUrl.isEmpty()) {
OpenHABCommand theCommand = null;
try {
theCommand = new Gson().fromJson(theUrl, OpenHABCommand.class);
} catch(Exception e) {
log.warn("Cannot parse command to OpenHAB <<<" + theUrl + ">>>", e);
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;
}
String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("://") + 3);
String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
String hostAddr = null;
if (hostPortion.contains(":")) {
hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
} else
hostAddr = hostPortion;
OpenHABInstance theHandler = findHandlerByAddress(hostAddr);
if(theHandler != null) {
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 {
theHandler.callCommand(anUrl, aCommand, httpClient);
} catch (Exception e) {
log.warn("Cannot send comand to OpenHAB", e);
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);
}
} else {
log.warn("OpenHAB Call could not complete, no address found: " + theUrl);
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);
}
} else {
log.warn("OpenHAB 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,
"Error on calling url to change device state", "/lights/"
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
}
return responseString;
}
@Override
public Object getItems(String type) {
// TODO Auto-generated method stub
return null;
if(!validOpenhab)
return null;
log.debug("consolidating devices for OpenHAB");
List<OpenHABDevice> theResponse = null;
Iterator<String> keys = openhabMap.keySet().iterator();
List<OpenHABDevice> deviceList = new ArrayList<OpenHABDevice>();
while(keys.hasNext()) {
String key = keys.next();
theResponse = openhabMap.get(key).getDevices(httpClient);
if(theResponse != null)
addOpenhabDevices(deviceList, theResponse, key);
else {
log.warn("Cannot get devices for OpenHAB with name: " + key + ", skipping this OpenHAB.");
continue;
}
}
return deviceList;
}
private Boolean addOpenhabDevices(List<OpenHABDevice> theDeviceList, List<OpenHABDevice> theSourceList, String theKey) {
Iterator<OpenHABDevice> devices = theSourceList.iterator();
while(devices.hasNext()) {
OpenHABDevice theDevice = devices.next();
theDeviceList.add(theDevice);
}
return true;
}
@Override
public Home createHome(BridgeSettings bridgeSettings) {
openhabMap = null;
aGsonHandler = null;
validOpenhab = bridgeSettings.getBridgeSettingsDescriptor().isValidOpenhab();
log.info("OpenHAB Home created." + (validOpenhab ? "" : " No OpenHABs configured."));
if(validOpenhab) {
openhabMap = new HashMap<String,OpenHABInstance>();
aGsonHandler =
new GsonBuilder()
.create();
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getHassaddress().getDevices().iterator();
httpClient = HTTPHome.getHandler();
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getOpenhabaddress().getDevices().iterator();
while(theList.hasNext() && validOpenhab) {
NamedIP anOpenhab = theList.next();
try {
openhabMap.put(anOpenhab.getName(), new OpenHABInstance(anOpenhab));
} catch (Exception e) {
log.error("Cannot get hass (" + anOpenhab.getName() + ") setup, Exiting with message: " + e.getMessage(), e);
log.error("Cannot get OpenHAB (" + anOpenhab.getName() + ") setup, Exiting with message: " + e.getMessage(), e);
validOpenhab = false;
}
}
@@ -70,12 +163,36 @@ public class OpenHABHome implements Home {
return this;
}
private OpenHABInstance findHandlerByAddress(String hostAddress) {
OpenHABInstance aHandler = null;
boolean found = false;
Iterator<String> keys = openhabMap.keySet().iterator();
while(keys.hasNext()) {
String key = keys.next();
aHandler = openhabMap.get(key);
if(aHandler != null && aHandler.getOpenHABAddress().getIp().equals(hostAddress)) {
found = true;
break;
}
}
if(!found)
aHandler = null;
return aHandler;
}
@Override
public void closeHome() {
if(!closed) {
log.debug("Closing Home.");
if(!closed && validOpenhab) {
log.debug("Home is already closed....");
return;
}
if(httpClient != null)
httpClient.closeHandler();
openhabMap = null;
closed = true;
}

View File

@@ -1,7 +1,6 @@
package com.bwssystems.HABridge.plugins.openhab;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.http.client.methods.HttpGet;
@@ -12,17 +11,14 @@ import org.slf4j.LoggerFactory;
import com.bwssystems.HABridge.NamedIP;
import com.bwssystems.HABridge.api.NameValue;
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
import com.bwssystems.HABridge.plugins.http.HTTPHome;
import com.google.gson.Gson;
public class OpenHABInstance {
private static final Logger log = LoggerFactory.getLogger(OpenHABInstance.class);
private NamedIP theOpenHAB;
private HTTPHandler anHttpHandler;
public OpenHABInstance(NamedIP openhabLocation) {
super();
anHttpHandler = HTTPHome.getHandler();
theOpenHAB = openhabLocation;
}
@@ -34,65 +30,38 @@ public class OpenHABInstance {
this.theOpenHAB = openhabAddress;
}
public Boolean callCommand(String aCommand) {
log.debug("calling HomeAssistant: " + aCommand);
public Boolean callCommand(String aCommand, String commandData, HTTPHandler httpClient) {
log.debug("calling OpenHAB: " + theOpenHAB.getIp() + ":" + theOpenHAB.getPort() + aCommand);
String aUrl = null;
if(theOpenHAB.getSecure() != null && theOpenHAB.getSecure())
aUrl = "https";
else
aUrl = "http";
/* String domain = aCommand.getEntityId().substring(0, aCommand.getEntityId().indexOf("."));
aUrl = aUrl + "://" + theOpenHAB.getIp() + ":" + theOpenHAB.getPort() + "/api/services/";
if(domain.equals("group"))
aUrl = aUrl + "homeassistant";
else
aUrl = aUrl + domain;
String aBody = "{\"entity_id\":\"" + aCommand.getEntityId() + "\"";
NameValue[] headers = null;
if(theOpenHAB.getPassword() != null && !theOpenHAB.getPassword().isEmpty()) {
NameValue password = new NameValue();
password.setName("x-ha-access");
password.setValue(theOpenHAB.getPassword());
headers = new NameValue[1];
headers[0] = password;
if(theOpenHAB.getSecure() != null && theOpenHAB.getSecure())
aUrl = "https://";
else
aUrl = "http://";
if(theOpenHAB.getUsername() != null && !theOpenHAB.getUsername().isEmpty() && theOpenHAB.getPassword() != null && !theOpenHAB.getPassword().isEmpty()) {
aUrl = aUrl + theOpenHAB.getUsername() + ":" + theOpenHAB.getPassword() + "@";
}
if(aCommand.getState().equalsIgnoreCase("on")) {
aUrl = aUrl + "/turn_on";
if(aCommand.getBri() != null)
aBody = aBody + ",\"brightness\":" + aCommand.getBri() + "}";
else
aBody = aBody + "}";
}
else {
aUrl = aUrl + "/turn_off";
aBody = aBody + "}";
}
log.debug("Calling HomeAssistant with url: " + aUrl);
String theData = anHttpHandler.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", aBody, headers);
aUrl = aUrl + theOpenHAB.getIp() + ":" + theOpenHAB.getPort() + "/" + aCommand;
String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "text/plain", commandData, headers);
log.debug("call Command return is: <" + theData + ">");
*/
return true;
}
public List<OpenHABItem> getDevices() {
List<OpenHABItem> theDeviceStates = null;
public List<OpenHABDevice> getDevices(HTTPHandler httpClient) {
List<OpenHABDevice> deviceList = null;
OpenHABItem[] theOpenhabStates;
String theUrl = null;
String theData;
NameValue[] headers = null;
if(theOpenHAB.getPassword() != null && !theOpenHAB.getPassword().isEmpty()) {
NameValue password = new NameValue();
password.setName("x-ha-access");
password.setValue(theOpenHAB.getPassword());
headers = new NameValue[1];
headers[0] = password;
}
if(theOpenHAB.getSecure() != null && theOpenHAB.getSecure())
theUrl = "https";
theUrl = "https://";
else
theUrl = "http";
theUrl = theUrl + "://" + theOpenHAB.getIp() + ":" + theOpenHAB.getPort() + "/rest/items?recursive=false";
theData = anHttpHandler.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers);
theUrl = "http://";
if(theOpenHAB.getUsername() != null && !theOpenHAB.getUsername().isEmpty() && theOpenHAB.getPassword() != null && !theOpenHAB.getPassword().isEmpty()) {
theUrl = theUrl + theOpenHAB.getUsername() + ":" + theOpenHAB.getPassword() + "@";
}
theUrl = theUrl + theOpenHAB.getIp() + ":" + theOpenHAB.getPort() + "/rest/items?recursive=false";
theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers);
if(theData != null) {
log.debug("GET OpenHAB States - data: " + theData);
theOpenhabStates = new Gson().fromJson(theData, OpenHABItem[].class);
@@ -100,17 +69,24 @@ public class OpenHABInstance {
log.warn("Cannot get an devices for OpenHAB " + theOpenHAB.getName() + " as response is not parsable.");
}
else {
theDeviceStates = new ArrayList<OpenHABItem>(Arrays.asList(theOpenhabStates));
deviceList = new ArrayList<OpenHABDevice>();
for (int i = 0; i < theOpenhabStates.length; i++) {
OpenHABDevice aNewOpenHABDeviceDevice = new OpenHABDevice();
aNewOpenHABDeviceDevice.setItem(theOpenhabStates[i]);
aNewOpenHABDeviceDevice.setAddress(theOpenHAB.getIp() + ":" + theOpenHAB.getPort());
aNewOpenHABDeviceDevice.setName(theOpenHAB.getName());
deviceList.add(aNewOpenHABDeviceDevice);
}
}
}
else
log.warn("Cannot get an devices for OpenHAB " + theOpenHAB.getName() + " http call failed.");
return theDeviceStates;
return deviceList;
}
protected void closeClient() {
anHttpHandler.closeHandler();
anHttpHandler = null;
}
}