Updated math variable execution to use net.java.dev.eval package. Safer

and more robust than using JavaScript Engine Eval. Also, added checks if
a default vera address is uses , "1.1.1.1", that we ignore the vera
helpers to not throw errors.
This commit is contained in:
Admin
2015-10-12 16:34:21 -05:00
parent aebde7ee48
commit c5fbd5d1f0
14 changed files with 70 additions and 34 deletions

View File

@@ -61,4 +61,9 @@ public class BridgeSettings {
this.vtwocompatibility = vtwocompatibility;
}
public Boolean isValidVera() {
if(this.veraaddress.contains(Configuration.DEFAULT_VERA_ADDRESS))
return false;
return true;
}
}

View File

@@ -0,0 +1,8 @@
package com.bwssystems.HABridge;
public class Configuration {
public final static String DEVICE_DB_DIRECTORY = "data/device.db";
public final static String UPNP_RESPONSE_PORT = "50000";
public final static String DEFAULT_VERA_ADDRESS = "1.1.1.1";
public final static String DFAULT_WEB_PORT = "8080";
}

View File

@@ -51,17 +51,17 @@ public class HABridge {
bridgeSettings = new BridgeSettings();
bridgeSettings.setUpnpConfigAddress(System.getProperty("upnp.config.address", addressString));
bridgeSettings.setUpnpDeviceDb(System.getProperty("upnp.device.db", "data/device.db"));
bridgeSettings.setUpnpResponsePort(System.getProperty("upnp.response.port", "50000"));
bridgeSettings.setVeraAddress(System.getProperty("vera.address", "192.168.1.100"));
bridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("upnp.strict", "false")));
bridgeSettings.setUpnpDeviceDb(System.getProperty("upnp.device.db", Configuration.DEVICE_DB_DIRECTORY));
bridgeSettings.setUpnpResponsePort(System.getProperty("upnp.response.port", Configuration.UPNP_RESPONSE_PORT));
bridgeSettings.setVeraAddress(System.getProperty("vera.address", Configuration.DEFAULT_VERA_ADDRESS));
bridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("upnp.strict", "true")));
bridgeSettings.setTraceupnp(Boolean.parseBoolean(System.getProperty("trace.upnp", "false")));
bridgeSettings.setVtwocompatibility(Boolean.parseBoolean(System.getProperty("vtwo.compatibility", "true")));
bridgeSettings.setVtwocompatibility(Boolean.parseBoolean(System.getProperty("vtwo.compatibility", "false")));
// sparkjava config directive to set ip address for the web server to listen on
// ipAddress("0.0.0.0"); // not used
// sparkjava config directive to set port for the web server to listen on
bridgeSettings.setServerPort(System.getProperty("server.port", "8080"));
bridgeSettings.setServerPort(System.getProperty("server.port", Configuration.DFAULT_WEB_PORT));
port(Integer.valueOf(bridgeSettings.getServerPort()));
// sparkjava config directive to set html static file location for Jetty
staticFileLocation("/public");

View File

@@ -3,7 +3,6 @@ package com.bwssystems.HABridge.dao;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;

View File

@@ -36,7 +36,7 @@ public class DeviceResource {
public DeviceResource(BridgeSettings theSettings) {
super();
deviceRepository = new DeviceRepository(theSettings.getUpnpDeviceDb());
veraInfo = new VeraInfo(theSettings.getVeraAddress());
veraInfo = new VeraInfo(theSettings.getVeraAddress(), theSettings.isValidVera());
setupEndpoints();
}

View File

@@ -9,9 +9,9 @@ import com.bwssystems.HABridge.dao.*;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.ScriptEngine;
import net.java.dev.eval.Expression;
import static spark.Spark.get;
import static spark.Spark.post;
import static spark.Spark.put;
@@ -32,6 +32,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -47,7 +48,6 @@ public class HueMulator {
private static final String INTENSITY_MATH = "${intensity.math(";
private static final String INTENSITY_MATH_VALUE = "X";
private static final String INTENSITY_MATH_CLOSE = ")}";
private static final String ENGINE_JAVASCRIPT = "JavaScript";
private static final String HUE_CONTEXT = "/api";
private DeviceRepository repository;
@@ -232,9 +232,10 @@ public class HueMulator {
/* light weight templating here, was going to use free marker but it was a bit too
* heavy for what we were trying to do.
*
* currently provides only two variables:
* currently provides:
* intensity.byte : 0-255 brightness. this is raw from the echo
* intensity.percent : 0-100, adjusted for the vera
* intensity.math(X*1) : where X is the value from the interface call and can use net.java.dev.eval math
*/
protected String replaceIntensityValue(String request, int intensity){
if(request == null){
@@ -248,16 +249,18 @@ public class HueMulator {
String intensityPercent = String.valueOf(percentBrightness);
request = request.replace(INTENSITY_PERCENT, intensityPercent);
} else if(request.contains(INTENSITY_MATH)){
Map<String, BigDecimal> variables = new HashMap<String, BigDecimal>();
String mathDescriptor = request.substring(request.indexOf(INTENSITY_MATH) + INTENSITY_MATH.length(),request.indexOf(INTENSITY_MATH_CLOSE));
String updatedMath = mathDescriptor.replace(INTENSITY_MATH_VALUE, String.valueOf(intensity));
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName(ENGINE_JAVASCRIPT);
variables.put(INTENSITY_MATH_VALUE, new BigDecimal(intensity));
try {
log.debug("Math eval is: " + updatedMath);
Integer endResult = (Integer) engine.eval(updatedMath);
log.debug("Math eval is: " + mathDescriptor + ", Where " + INTENSITY_MATH_VALUE + " is: " + String.valueOf(intensity));
Expression exp = new Expression(mathDescriptor);
BigDecimal result = exp.eval(variables);
Integer endResult = result.intValue();
request = request.replace(INTENSITY_MATH + mathDescriptor + INTENSITY_MATH_CLOSE, endResult.toString());
} catch (ScriptException e) {
log.error("Could not execute Math: " + updatedMath, e);
} catch (Exception e) {
log.error("Could not execute Math: " + mathDescriptor, e);
} }
return request;
}

View File

@@ -26,14 +26,19 @@ public class VeraInfo {
private HttpClient httpClient;
private static final String SDATA_REQUEST = ":3480/data_request?id=sdata&output_format=json";
private String veraAddressString;
private Boolean validVera;
public VeraInfo(String addressString) {
public VeraInfo(String addressString, Boolean isValidVera) {
super();
httpClient = HttpClients.createMinimal();
veraAddressString = addressString;
validVera = isValidVera;
}
public Sdata getSdata() {
if(!validVera)
return new Sdata();
String theUrl = "http://" + veraAddressString + SDATA_REQUEST;
String theData;