Added Requester logic filtering. Added logic for count and delay in

items and buttons.
This commit is contained in:
Admin
2016-11-11 14:38:37 -06:00
parent 407b0e0bd5
commit 7d39b79e05
12 changed files with 218 additions and 94 deletions

View File

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

View File

@@ -2,6 +2,8 @@ package com.bwssystems.HABridge.api;
public class CallItem {
private String item;
private Integer count;
private Integer delay;
public String getItem() {
return item;
@@ -10,4 +12,20 @@ public class CallItem {
public void setItem(String anitem) {
item = anitem;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public Integer getDelay() {
return delay;
}
public void setDelay(Integer delay) {
this.delay = delay;
}
}

View File

@@ -3,7 +3,6 @@ package com.bwssystems.HABridge.api.hue;
import java.util.List;
import com.bwssystems.HABridge.dao.DeviceDescriptor;
import com.bwssystems.HABridge.dao.DeviceRepository;
public class GroupResponse {
private DeviceState action;

View File

@@ -56,6 +56,9 @@ public class DeviceDescriptor{
@SerializedName("contentBodyDim")
@Expose
private String contentBodyDim;
@SerializedName("requesterAddress")
@Expose
private String requesterAddress;
private DeviceState deviceState;
@@ -187,6 +190,14 @@ public class DeviceDescriptor{
this.contentBodyDim = contentBodyDim;
}
public String getRequesterAddress() {
return requesterAddress;
}
public void setRequesterAddress(String requesterAddress) {
this.requesterAddress = requesterAddress;
}
public DeviceState getDeviceState() {
if(deviceState == null)
deviceState = DeviceState.createDeviceState();

View File

@@ -73,12 +73,46 @@ public class DeviceRepository extends BackupHandler {
List<DeviceDescriptor> list = new ArrayList<DeviceDescriptor>(devices.values());
return list;
}
public List<DeviceDescriptor> findByDeviceType(String aType) {
/*
public List<DeviceDescriptor> findAllByRequester(String anAddress) {
List<DeviceDescriptor> list = new ArrayList<DeviceDescriptor>(devices.values());
return list;
List<DeviceDescriptor> theReturnList = new ArrayList<DeviceDescriptor>();
Iterator<DeviceDescriptor> anIterator = list.iterator();
DeviceDescriptor theDevice;
String theRequesterAddress;
while(anIterator.hasNext()) {
theDevice = anIterator.next();
theRequesterAddress = theDevice.getRequesterAddress();
if(theRequesterAddress == null || theRequesterAddress.length() == 0 || theRequesterAddress.contains(anAddress))
theReturnList.add(theDevice);
}
return theReturnList;
}
*/
public List<DeviceDescriptor> findAllByRequester(String anAddress) {
List<DeviceDescriptor> list = new ArrayList<DeviceDescriptor>(devices.values());
List<DeviceDescriptor> theReturnList = new ArrayList<DeviceDescriptor>();
Iterator<DeviceDescriptor> anIterator = list.iterator();
DeviceDescriptor theDevice;
String theRequesterAddress;
HashMap<String,String > addressMap;
while (anIterator.hasNext()) {
theDevice = anIterator.next();
theRequesterAddress = theDevice.getRequesterAddress();
addressMap = new HashMap<String, String>();
if (theRequesterAddress.contains(",")) {
String[] theArray = theRequesterAddress.split(",");
for (String v : theArray) {
addressMap.put(v, v);
}
} else
addressMap.put(theRequesterAddress, theRequesterAddress);
if (theRequesterAddress == null || theRequesterAddress.length() == 0 || addressMap.containsKey(anAddress))
theReturnList.add(theDevice);
}
return theReturnList;
}
public DeviceDescriptor findOne(String id) {
return devices.get(id);
}

View File

@@ -8,7 +8,6 @@ import static spark.Spark.delete;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

View File

@@ -174,7 +174,7 @@ public class HueMulator implements HueErrorStringSet {
}
if(groupId.equalsIgnoreCase("0")) {
GroupResponse theResponse = GroupResponse.createGroupResponse(repository.findAll());
GroupResponse theResponse = GroupResponse.createGroupResponse(repository.findAllByRequester(request.ip()));
return new Gson().toJson(theResponse, GroupResponse.class);
}
@@ -271,7 +271,7 @@ public class HueMulator implements HueErrorStringSet {
return theErrorResp.getTheErrors();
}
List<DeviceDescriptor> deviceList = repository.findAll();
List<DeviceDescriptor> deviceList = repository.findAllByRequester(request.ip());
Map<String, DeviceResponse> deviceResponseMap = new HashMap<>();
for (DeviceDescriptor device : deviceList) {
DeviceResponse deviceResponse = null;
@@ -437,7 +437,7 @@ public class HueMulator implements HueErrorStringSet {
return theErrorResp.getTheErrors();
}
List<DeviceDescriptor> descriptorList = repository.findAll();
List<DeviceDescriptor> descriptorList = repository.findAllByRequester(request.ip());
HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getWhitelist());
Map<String, DeviceResponse> deviceList = new HashMap<>();
if (descriptorList != null) {
@@ -623,6 +623,7 @@ public class HueMulator implements HueErrorStringSet {
DeviceState state = null;
boolean stateHasBri = false;
boolean stateHasBriInc = false;
Integer theDelay = bridgeSettings.getButtonsleep();
log.debug("hue state change requested: " + userId + " from " + request.ip() + " body: " + request.body());
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json");
@@ -661,7 +662,6 @@ public class HueMulator implements HueErrorStringSet {
state = device.getDeviceState();
if(state == null)
state = DeviceState.createDeviceState();
state.fillIn();
theHeaders = new Gson().fromJson(device.getHeaders(), NameValue[].class);
@@ -782,11 +782,21 @@ public class HueMulator implements HueErrorStringSet {
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no harmony hub available\", \"parameter\": \"/lights/" + lightId + "state\"}}]";
}
else {
Integer setCount = 1;
for(int i = 0; i < deviceButtons.length; i++) {
if( i > 0)
Thread.sleep(bridgeSettings.getButtonsleep());
log.debug("pressing button: " + deviceButtons[i].getDevice() + " - " + deviceButtons[i].getButton() + " - iteration: " + String.valueOf(i));
myHarmony.pressButton(deviceButtons[i]);
if(deviceButtons[i].getCount() != null && deviceButtons[i].getCount() > 0)
setCount = deviceButtons[i].getCount();
else
setCount = 1;
for(int x = 0; x < setCount; x++) {
if( x > 0) {
Thread.sleep(theDelay);
}
if(deviceButtons[i].getDelay() != null &&deviceButtons[i].getDelay() > 0)
theDelay = deviceButtons[i].getDelay();
log.debug("pressing button: " + deviceButtons[i].getDevice() + " - " + deviceButtons[i].getButton() + " - iteration: " + String.valueOf(i) + " - count: " + String.valueOf(x));
myHarmony.pressButton(deviceButtons[i]);
}
}
}
}
@@ -852,20 +862,29 @@ public class HueMulator implements HueErrorStringSet {
url = "[{\"item\":\"" + url +"\"}]";
}
CallItem[] callItems = new Gson().fromJson(url, CallItem[].class);
Integer setCount = 1;
for(int i = 0; i < callItems.length; i++) {
if( i > 0) {
Thread.sleep(bridgeSettings.getButtonsleep());
}
String intermediate;
if(callItems[i].getItem().contains("exec://"))
intermediate = callItems[i].getItem().substring(callItems[i].getItem().indexOf("://") + 3);
else
intermediate = callItems[i].getItem();
String anError = doExecRequest(intermediate, calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), lightId);
if(anError != null) {
responseString = anError;
i = callItems.length+1;
}
if(callItems[i].getCount() != null && callItems[i].getCount() > 0)
setCount = callItems[i].getCount();
else
setCount = 1;
for(int x = 0; x < setCount; x++) {
if( x > 0) {
Thread.sleep(theDelay);
}
if(callItems[i].getDelay() != null && callItems[i].getDelay() > 0)
theDelay = callItems[i].getDelay();
String intermediate;
if(callItems[i].getItem().contains("exec://"))
intermediate = callItems[i].getItem().substring(callItems[i].getItem().indexOf("://") + 3);
else
intermediate = callItems[i].getItem();
String anError = doExecRequest(intermediate, calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), lightId);
if(anError != null) {
responseString = anError;
i = callItems.length+1;
}
}
}
}
else // This section allows the usage of http/tcp/udp/exec calls in a given set of items
@@ -878,77 +897,86 @@ public class HueMulator implements HueErrorStringSet {
url = "[{\"item\":\"" + url +"\"}]";
}
CallItem[] callItems = new Gson().fromJson(url, CallItem[].class);
Integer setCount = 1;
for(int i = 0; i < callItems.length; i++) {
if( i > 0) {
Thread.sleep(bridgeSettings.getButtonsleep());
}
try {
if(callItems[i].getItem().contains("udp://") || callItems[i].getItem().contains("tcp://")) {
String intermediate = callItems[i].getItem().substring(callItems[i].getItem().indexOf("://") + 3);
String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
String theUrlBody = intermediate.substring(intermediate.indexOf('/')+1);
String hostAddr = null;
String port = null;
if(hostPortion.contains(":")) {
hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
port = hostPortion.substring(intermediate.indexOf(':') + 1);
if(callItems[i].getCount() != null && callItems[i].getCount() > 0)
setCount = callItems[i].getCount();
else
setCount = 1;
for(int x = 0; x < setCount; x++) {
if( x > 0) {
Thread.sleep(theDelay);
}
if(callItems[i].getDelay() != null && callItems[i].getDelay() > 0)
theDelay = callItems[i].getDelay();
try {
if(callItems[i].getItem().contains("udp://") || callItems[i].getItem().contains("tcp://")) {
String intermediate = callItems[i].getItem().substring(callItems[i].getItem().indexOf("://") + 3);
String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
String theUrlBody = intermediate.substring(intermediate.indexOf('/')+1);
String hostAddr = null;
String port = null;
if(hostPortion.contains(":")) {
hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
port = hostPortion.substring(intermediate.indexOf(':') + 1);
}
else
hostAddr = hostPortion;
InetAddress IPAddress = InetAddress.getByName(hostAddr);;
if(theUrlBody.startsWith("0x")) {
theUrlBody = replaceIntensityValue(theUrlBody, calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), true);
sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2));
}
else {
theUrlBody = replaceIntensityValue(theUrlBody, calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
sendData = theUrlBody.getBytes();
}
if(callItems[i].getItem().contains("udp://")) {
log.debug("executing HUE api request to UDP: " + callItems[i].getItem());
theUDPDatagramSender.sendUDPResponse(new String(sendData), IPAddress, Integer.parseInt(port));
}
else if(callItems[i].getItem().contains("tcp://"))
{
log.debug("executing HUE api request to TCP: " + callItems[i].getItem());
Socket dataSendSocket = new Socket(IPAddress, Integer.parseInt(port));
DataOutputStream outToClient = new DataOutputStream(dataSendSocket.getOutputStream());
outToClient.write(sendData);
outToClient.flush();
dataSendSocket.close();
}
}
else
hostAddr = hostPortion;
InetAddress IPAddress = InetAddress.getByName(hostAddr);;
if(theUrlBody.startsWith("0x")) {
theUrlBody = replaceIntensityValue(theUrlBody, calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), true);
sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2));
else if(callItems[i].getItem().contains("exec://")) {
String intermediate = callItems[i].getItem().substring(callItems[i].getItem().indexOf("://") + 3);
String anError = doExecRequest(intermediate, calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), lightId);
if(anError != null) {
responseString = anError;
i = callItems.length+1;
}
}
else {
theUrlBody = replaceIntensityValue(theUrlBody, calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
sendData = theUrlBody.getBytes();
}
if(callItems[i].getItem().contains("udp://")) {
log.debug("executing HUE api request to UDP: " + callItems[i].getItem());
theUDPDatagramSender.sendUDPResponse(new String(sendData), IPAddress, Integer.parseInt(port));
}
else if(callItems[i].getItem().contains("tcp://"))
{
log.debug("executing HUE api request to TCP: " + callItems[i].getItem());
Socket dataSendSocket = new Socket(IPAddress, Integer.parseInt(port));
DataOutputStream outToClient = new DataOutputStream(dataSendSocket.getOutputStream());
outToClient.write(sendData);
outToClient.flush();
dataSendSocket.close();
}
}
else if(callItems[i].getItem().contains("exec://")) {
String intermediate = callItems[i].getItem().substring(callItems[i].getItem().indexOf("://") + 3);
String anError = doExecRequest(intermediate, calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), lightId);
if(anError != null) {
responseString = anError;
i = callItems.length+1;
}
}
else {
log.debug("executing HUE api request to Http " + (device.getHttpVerb() == null?"GET":device.getHttpVerb()) + ": " + callItems[i].getItem());
log.debug("executing HUE api request to Http " + (device.getHttpVerb() == null?"GET":device.getHttpVerb()) + ": " + callItems[i].getItem());
String anUrl = replaceIntensityValue(callItems[i].getItem(), calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
String body;
if(stateHasBri || stateHasBriInc)
body = replaceIntensityValue(device.getContentBodyDim(), calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
else if (state.isOn())
body = replaceIntensityValue(device.getContentBody(), calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
else
body = replaceIntensityValue(device.getContentBodyOff(), calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
// make call
if (doHttpRequest(anUrl, device.getHttpVerb(), device.getContentType(), body, theHeaders) == null) {
log.warn("Error on calling url to change device state: " + anUrl);
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Error on calling url to change device state\", \"parameter\": \"/lights/" + lightId + "state\"}}]";
i = callItems.length+1;
}
}
} catch (Exception e) {
log.warn("Change device state, Could not send data for network request: " + callItems[i].getItem() + " with Message: " + e.getMessage());
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/" + lightId + "state\"}}]";
i = callItems.length+1;
}
String anUrl = replaceIntensityValue(callItems[i].getItem(), calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
String body;
if(stateHasBri || stateHasBriInc)
body = replaceIntensityValue(device.getContentBodyDim(), calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
else if (state.isOn())
body = replaceIntensityValue(device.getContentBody(), calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
else
body = replaceIntensityValue(device.getContentBodyOff(), calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
// make call
if (doHttpRequest(anUrl, device.getHttpVerb(), device.getContentType(), body, theHeaders) == null) {
log.warn("Error on calling url to change device state: " + anUrl);
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Error on calling url to change device state\", \"parameter\": \"/lights/" + lightId + "state\"}}]";
i = callItems.length+1;
}
}
} catch (Exception e) {
log.warn("Change device state, Could not send data for network request: " + callItems[i].getItem() + " with Message: " + e.getMessage());
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/" + lightId + "state\"}}]";
i = callItems.length+1;
}
}
}
}

View File

@@ -3,6 +3,8 @@ package com.bwssystems.harmony;
public class ButtonPress {
private String device;
private String button;
private Integer delay;
private Integer count;
public String getDevice() {
return device;
}
@@ -15,6 +17,18 @@ public class ButtonPress {
public void setButton(String button) {
this.button = button;
}
public Integer getDelay() {
return delay;
}
public void setDelay(Integer delay) {
this.delay = delay;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public Boolean isValid() {
if (device != null && !device.isEmpty()){
if (button != null && !button.isEmpty())

View File

@@ -145,6 +145,7 @@ app.service('bridgeService', function ($http, $window, ngToast) {
self.state.device.contentBody = null;
self.state.device.contentBodyDim = null;
self.state.device.contentBodyOff = null;
self.state.device.requesterAddress = null;
self.state.olddevicename = "";
};

View File

@@ -39,6 +39,7 @@
<th sortable-header col="name">Name</th>
<th sortable-header col="deviceType">Type</th>
<th sortable-header col="targetDevice">Target</th>
<th sortable-header col="requesterAddress">Requester Address</th>
<th>Actions</th>
</tr>
</thead>
@@ -48,6 +49,7 @@
<td>{{device.name}}</td>
<td>{{device.deviceType}}</td>
<td>{{device.targetDevice}}</td>
<td>{{device.requesterAddress}}</td>
<td>
<p>
<button class="btn btn-info" type="submit"

View File

@@ -115,6 +115,14 @@
ng-model="device.uniqueid" placeholder="AA:BB:CC:DD:EE:FF-XX" readonly>
</div>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-2 control-label" for="device-requester-addr">Requester Address (comma separated list) </label>
<div class="col-xs-8 col-sm-7">
<input type="text" class="form-control" id="evice-requester-addr"
ng-model="device.requesterAddress" placeholder="Only use if you want to restrict this device to a specific caller(s)">
</div>
</div>
<div ng-if="device.mapType" class="form-group">
<label class="col-xs-12 col-sm-2 control-label" for="device-map-id">Map
ID </label>

View File

@@ -129,6 +129,16 @@
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<label class="col-xs-12 col-sm-2 control-label" for="device-requester-addr">Requester Address (comma separated list) </label>
<div class="col-xs-8 col-sm-7">
<input type="text" class="form-control" id="evice-requester-addr"
ng-model="device.requesterAddress" placeholder="Only use if you want to restrict this device to a specific caller(s)">
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On