Comitinue refactor of huemulator

This commit is contained in:
Admin
2016-12-21 17:06:30 -06:00
parent 2579949a23
commit b5a3bea803
8 changed files with 799 additions and 592 deletions

View File

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

View File

@@ -15,7 +15,7 @@ public class DeviceMapTypes {
public final static String[] HAL_HOME = { "halHome", "HAL Home Status"};
public final static String[] HAL_THERMO_SET = { "halThermoSet", "HAL Thermostat"};
public final static String[] MQTT_MESSAGE = { "mqttMessage", "MQTT Message"};
public final static String[] EXEC_DEVICE = { "execDevice", "Execute Script/Program"};
public final static String[] EXEC_DEVICE = { "exec", "Execute Script/Program"};
public final static String[] HASS_DEVICE = { "hassDevice", "HomeAssistant Device"};
public final static int typeIndex = 0;

View File

@@ -0,0 +1,7 @@
package com.bwssystems.HABridge;
import com.bwssystems.HABridge.hue.HueMulatorHandler;
public interface Home extends HueMulatorHandler {
public Home createHome(BridgeSettingsDescriptor bridgeSettings);
}

View File

@@ -0,0 +1,103 @@
package com.bwssystems.HABridge.hue;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.DatatypeConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.bwssystems.HABridge.api.hue.DeviceState;
import com.bwssystems.HABridge.api.hue.StateChangeBody;
import net.java.dev.eval.Expression;
public class BrightnessDecode {
private static final Logger log = LoggerFactory.getLogger(BrightnessDecode.class);
private static final String INTENSITY_PERCENT = "${intensity.percent}";
private static final String INTENSITY_BYTE = "${intensity.byte}";
private static final String INTENSITY_MATH = "${intensity.math(";
private static final String INTENSITY_MATH_VALUE = "X";
private static final String INTENSITY_MATH_CLOSE = ")}";
public static int calculateIntensity(DeviceState state, StateChangeBody theChanges, boolean hasBri, boolean hasBriInc) {
int setIntensity = state.getBri();
if (hasBri) {
setIntensity = theChanges.getBri();
} else if (hasBriInc) {
if ((setIntensity + theChanges.getBri_inc()) <= 0)
setIntensity = theChanges.getBri_inc();
else if ((setIntensity + theChanges.getBri_inc()) > 255)
setIntensity = theChanges.getBri_inc();
else
setIntensity = setIntensity + theChanges.getBri_inc();
}
return setIntensity;
}
/*
* 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: 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
*/
public static String replaceIntensityValue(String request, int intensity, boolean isHex) {
if (request == null) {
return null;
}
if (request.contains(INTENSITY_BYTE)) {
if (isHex) {
BigInteger bigInt = BigInteger.valueOf(intensity);
byte[] theBytes = bigInt.toByteArray();
String hexValue = DatatypeConverter.printHexBinary(theBytes);
request = request.replace(INTENSITY_BYTE, hexValue);
} else {
String intensityByte = String.valueOf(intensity);
request = request.replace(INTENSITY_BYTE, intensityByte);
}
} else if (request.contains(INTENSITY_PERCENT)) {
int percentBrightness = (int) Math.round(intensity / 255.0 * 100);
if (isHex) {
BigInteger bigInt = BigInteger.valueOf(percentBrightness);
byte[] theBytes = bigInt.toByteArray();
String hexValue = DatatypeConverter.printHexBinary(theBytes);
request = request.replace(INTENSITY_PERCENT, hexValue);
} else {
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));
variables.put(INTENSITY_MATH_VALUE, new BigDecimal(intensity));
try {
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 = Math.round(result.floatValue());
if (isHex) {
BigInteger bigInt = BigInteger.valueOf(endResult);
byte[] theBytes = bigInt.toByteArray();
String hexValue = DatatypeConverter.printHexBinary(theBytes);
request = request.replace(INTENSITY_MATH + mathDescriptor + INTENSITY_MATH_CLOSE, hexValue);
} else {
request = request.replace(INTENSITY_MATH + mathDescriptor + INTENSITY_MATH_CLOSE,
endResult.toString());
}
} catch (Exception e) {
log.warn("Could not execute Math: " + mathDescriptor, e);
}
}
return request;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
package com.bwssystems.HABridge.hue;
import com.bwssystems.HABridge.api.CallItem;
import com.bwssystems.HABridge.api.hue.DeviceState;
import com.bwssystems.HABridge.api.hue.StateChangeBody;
public interface HueMulatorHandler {
public String deviceHandler(CallItem anItem, MultiCommandUtil multiComand, String lightId, int iterationCount, DeviceState state, StateChangeBody theStateChanges, boolean stateHasBri, boolean stateHasBriInc);
}

View File

@@ -0,0 +1,22 @@
package com.bwssystems.HABridge.hue;
public class MultiCommandUtil {
private Integer setCount;
private Integer theDelay;
public Integer getSetCount() {
return setCount;
}
public void setSetCount(Integer setCount) {
this.setCount = setCount;
}
public Integer getTheDelay() {
return theDelay;
}
public void setTheDelay(Integer theDelay) {
this.theDelay = theDelay;
}
}

View File

@@ -10,21 +10,34 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
import com.bwssystems.HABridge.Home;
import com.bwssystems.HABridge.NamedIP;
import com.bwssystems.HABridge.api.CallItem;
import com.bwssystems.HABridge.api.hue.DeviceState;
import com.bwssystems.HABridge.api.hue.StateChangeBody;
import com.bwssystems.HABridge.hue.BrightnessDecode;
import com.bwssystems.HABridge.hue.HueMulatorHandler;
import com.bwssystems.HABridge.hue.MultiCommandUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class HassHome {
public class HassHome implements Home {
private static final Logger log = LoggerFactory.getLogger(HassHome.class);
private Map<String, HomeAssistant> hassMap;
private Boolean validHass;
private Gson aGsonHandler;
public HassHome(BridgeSettingsDescriptor bridgeSettings) {
super();
createHome(bridgeSettings);
}
@Override
public Home createHome(BridgeSettingsDescriptor bridgeSettings) {
validHass = bridgeSettings.isValidHass();
if(!validHass)
return;
return null;
hassMap = new HashMap<String,HomeAssistant>();
if(!bridgeSettings.isValidHass())
return;
Iterator<NamedIP> theList = bridgeSettings.getHassaddress().getDevices().iterator();
while(theList.hasNext()) {
NamedIP aHass = theList.next();
@@ -32,9 +45,13 @@ public class HassHome {
hassMap.put(aHass.getName(), new HomeAssistant(aHass));
} catch (Exception e) {
log.error("Cannot get hass (" + aHass.getName() + ") setup, Exiting with message: " + e.getMessage(), e);
return;
return null;
}
}
aGsonHandler =
new GsonBuilder()
.create();
return this;
}
public HomeAssistant getHomeAssistant(String aName) {
@@ -86,4 +103,40 @@ public class HassHome {
}
return true;
}
@Override
public String deviceHandler(CallItem anItem, MultiCommandUtil multiComand, String lightId, int iterationCount, DeviceState state,
StateChangeBody theStateChanges, boolean stateHasBri, boolean stateHasBriInc) {
String theReturn = null;
log.debug("executing HUE api request to send message to HomeAssistant: " + anItem.getItem().toString());
HassCommand hassCommand = aGsonHandler.fromJson(anItem.getItem(), HassCommand.class);
hassCommand.setBri(BrightnessDecode.replaceIntensityValue(hassCommand.getBri(),
BrightnessDecode.calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false));
HomeAssistant homeAssistant = getHomeAssistant(hassCommand.getHassName());
if (homeAssistant == null) {
log.warn("Should not get here, no HomeAssistants available");
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Should not get here, no HiomeAssistant clients available\", \"parameter\": \"/lights/"
+ lightId + "state\"}}]";
} else {
for (int x = 0; x < multiComand.getSetCount(); x++) {
if (x > 0 || iterationCount > 0) {
try {
Thread.sleep(multiComand.getTheDelay());
} catch (InterruptedException e) {
// ignore
}
}
if (anItem.getDelay() != null && anItem.getDelay() > 0)
multiComand.setTheDelay(anItem.getDelay());
// else
// this.setTheDelay(bridgeSettings.getButtonsleep());
log.debug("calling HomeAssistant: " + hassCommand.getHassName() + " - "
+ hassCommand.getEntityId() + " - " + hassCommand.getState() + " - " + hassCommand.getBri()
+ " - iteration: " + String.valueOf(iterationCount) + " - count: " + String.valueOf(x));
homeAssistant.callCommand(hassCommand);
}
}
return theReturn;
}
}