From 2f567cd604f0fe9bec3661dbee9a231b0836a936 Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Tue, 23 Apr 2019 09:56:49 -0500 Subject: [PATCH] remove JAXB dependency and update harmony disconnect detection --- pom.xml | 8 +-- .../HABridge/dao/DeviceRepository.java | 12 +--- .../plugins/broadlink/BroadlinkHome.java | 9 ++- .../plugins/broadlink/TestBLDevice.java | 4 +- .../plugins/broadlink/TestMP1Device.java | 4 +- .../plugins/broadlink/TestRM2Device.java | 4 +- .../plugins/broadlink/TestSP1Device.java | 4 +- .../plugins/broadlink/TestSP2Device.java | 4 +- .../plugins/harmony/HarmonyHandler.java | 2 +- .../HABridge/plugins/harmony/HarmonyHome.java | 26 +++++-- .../HABridge/plugins/tcp/TCPHome.java | 4 +- .../HABridge/plugins/udp/UDPHome.java | 4 +- .../bwssystems/HABridge/util/HexLibrary.java | 72 +++++++++++++++++++ .../test/BroadlinkDataConstructor.java | 6 +- 14 files changed, 123 insertions(+), 40 deletions(-) create mode 100644 src/main/java/com/bwssystems/HABridge/util/HexLibrary.java diff --git a/pom.xml b/pom.xml index 9141efc..8423d8e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,16 +5,16 @@ com.bwssystems.HABridge ha-bridge - 5.2.2RC3 + 5.2.2RC4 jar HA Bridge Emulates a Philips Hue bridge to allow the Amazon Echo to hook up to other HA systems, i.e. Vera or Harmony Hub or Nest, using lightweight frameworks - 1.8 - 1.8 - 1.8 + 1.11 + 1.11 + 1.11 UTF-8 diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java index 990e011..b8b5651 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java @@ -2,7 +2,6 @@ package com.bwssystems.HABridge.dao; import java.io.IOException; -import java.math.BigInteger; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -13,8 +12,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import javax.xml.bind.DatatypeConverter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,6 +22,7 @@ import com.bwssystems.HABridge.dao.DeviceDescriptor; import com.bwssystems.HABridge.plugins.hue.HueHome; import com.bwssystems.HABridge.util.BackupHandler; import com.bwssystems.HABridge.util.JsonTransformer; +import com.bwssystems.HABridge.util.HexLibrary; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonSyntaxException; @@ -180,9 +178,7 @@ public class DeviceRepository extends BackupHandler { descriptors[i].setId(String.valueOf(nextId)); } if(descriptors[i].getUniqueid() == null || descriptors[i].getUniqueid().length() == 0) { - BigInteger bigInt = BigInteger.valueOf(Integer.decode(descriptors[i].getId())); - byte[] theBytes = bigInt.toByteArray(); - String hexValue = DatatypeConverter.printHexBinary(theBytes); + String hexValue = HexLibrary.encodeUsingBigIntegerToString(descriptors[i].getId()); descriptors[i].setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue); } @@ -204,9 +200,7 @@ public class DeviceRepository extends BackupHandler { nextId++; DeviceDescriptor theDevice = deviceIterator.next(); theDevice.setId(String.valueOf(nextId)); - BigInteger bigInt = BigInteger.valueOf(nextId); - byte[] theBytes = bigInt.toByteArray(); - String hexValue = DatatypeConverter.printHexBinary(theBytes); + String hexValue = HexLibrary.encodeUsingBigIntegerToString(nextId.toString()); theDevice.setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue); newdevices.put(theDevice.getId(), theDevice); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java index 8ef6fc3..7c03df1 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java @@ -11,8 +11,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import javax.xml.bind.DatatypeConverter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,6 +26,7 @@ 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.util.HexLibrary; import com.github.mob41.blapi.BLDevice; import com.github.mob41.blapi.MP1Device; import com.github.mob41.blapi.SP1Device; @@ -118,7 +117,7 @@ public class BroadlinkHome implements Home { if (theDevice == null) { if(broadlinkCommand.hasIpAndMac()) { - byte[] intBytes = DatatypeConverter.parseHexBinary(broadlinkCommand.getType()); + byte[] intBytes = HexLibrary.decodeHexString(broadlinkCommand.getType()); BigInteger theBig = new BigInteger(intBytes); int theType = theBig.intValue(); try { @@ -218,13 +217,13 @@ public class BroadlinkHome implements Home { } theStringData = DeviceDataDecode.replaceDeviceData(theStringData, device); theStringData = TimeDecode.replaceTimeValue(theStringData); - byte[] theData = DatatypeConverter.parseHexBinary(theStringData); + byte[] theData = HexLibrary.decodeHexString(theStringData); SendDataCmdPayload thePayload = new SendDataCmdPayload(theData); DatagramPacket thePacket = theDevice.sendCmdPkt(Configuration.BROADLINK_DISCONVER_TIMEOUT, thePayload); String returnData = null; if(thePacket != null) - returnData = DatatypeConverter.printHexBinary(thePacket.getData()); + returnData = HexLibrary.encodeHexString(thePacket.getData()); else returnData = "No Data - null"; log.debug("RM2 Device data return: <<<" + returnData + ">>>"); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestBLDevice.java b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestBLDevice.java index adbf47d..4dfe9f0 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestBLDevice.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestBLDevice.java @@ -4,7 +4,7 @@ import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; -import javax.xml.bind.DatatypeConverter; +import com.bwssystems.HABridge.util.HexLibrary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +33,7 @@ public class TestBLDevice extends BLDevice { } public DatagramPacket sendCmdPkt(int timeout, CmdPayload aCmd) { - log.info("sendCmdPkt called with " + DatatypeConverter.printHexBinary(aCmd.getPayload().getData())); + log.info("sendCmdPkt called with " + HexLibrary.encodeHexString(aCmd.getPayload().getData())); return null; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestMP1Device.java b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestMP1Device.java index f4bcc7d..a74e684 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestMP1Device.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestMP1Device.java @@ -2,7 +2,7 @@ package com.bwssystems.HABridge.plugins.broadlink; import java.io.IOException; import java.net.DatagramPacket; -import javax.xml.bind.DatatypeConverter; +import com.bwssystems.HABridge.util.HexLibrary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,7 +23,7 @@ public class TestMP1Device extends MP1Device { } public DatagramPacket sendCmdPkt(int timeout, CmdPayload aCmd) { - log.info("sendCmdPkt called with " + DatatypeConverter.printHexBinary(aCmd.getPayload().getData())); + log.info("sendCmdPkt called with " + HexLibrary.encodeHexString(aCmd.getPayload().getData())); return null; } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestRM2Device.java b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestRM2Device.java index 46d30e0..9373e4b 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestRM2Device.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestRM2Device.java @@ -3,7 +3,7 @@ package com.bwssystems.HABridge.plugins.broadlink; import java.io.IOException; import java.net.DatagramPacket; -import javax.xml.bind.DatatypeConverter; +import com.bwssystems.HABridge.util.HexLibrary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,7 +21,7 @@ public class TestRM2Device extends RM2Device { } public DatagramPacket sendCmdPkt(int timeout, CmdPayload aCmd) { - log.info("sendCmdPkt called with " + DatatypeConverter.printHexBinary(((SendDataCmdPayload)aCmd).getData())); + log.info("sendCmdPkt called with " + HexLibrary.encodeHexString(((SendDataCmdPayload)aCmd).getData())); return null; } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestSP1Device.java b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestSP1Device.java index 6b441e8..70f3244 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestSP1Device.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestSP1Device.java @@ -3,7 +3,7 @@ package com.bwssystems.HABridge.plugins.broadlink; import java.io.IOException; import java.net.DatagramPacket; -import javax.xml.bind.DatatypeConverter; +import com.bwssystems.HABridge.util.HexLibrary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,7 +24,7 @@ public class TestSP1Device extends SP1Device { } public DatagramPacket sendCmdPkt(int timeout, CmdPayload aCmd) { - log.info("sendCmdPkt called with " + DatatypeConverter.printHexBinary(aCmd.getPayload().getData())); + log.info("sendCmdPkt called with " + HexLibrary.encodeHexString(aCmd.getPayload().getData())); return null; } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestSP2Device.java b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestSP2Device.java index daa7831..5d35645 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestSP2Device.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/TestSP2Device.java @@ -3,7 +3,7 @@ package com.bwssystems.HABridge.plugins.broadlink; import java.io.IOException; import java.net.DatagramPacket; -import javax.xml.bind.DatatypeConverter; +import com.bwssystems.HABridge.util.HexLibrary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,7 +24,7 @@ public class TestSP2Device extends SP2Device { } public DatagramPacket sendCmdPkt(int timeout, CmdPayload aCmd) { - log.info("sendCmdPkt called with " + DatatypeConverter.printHexBinary(aCmd.getPayload().getData())); + log.info("sendCmdPkt called with " + HexLibrary.encodeHexString(aCmd.getPayload().getData())); return null; } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHandler.java b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHandler.java index bcb0f1e..a2855b6 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHandler.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHandler.java @@ -163,7 +163,7 @@ public class HarmonyHandler { } boolean handleExceptionError(Exception e) { - if(e.getMessage().equalsIgnoreCase("Failed communicating with Harmony Hub")) { + if(e.getMessage().contains("Failed communicating with Harmony Hub") || e.getMessage().contains("Send heartbeat failed")) { log.warn("Issue in communcicating with Harmony Hub, retrying connect...."); return false; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java index 90cdc87..13bea4f 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java @@ -93,7 +93,13 @@ public class HarmonyHome implements Home { resetHub(hubs.get(key).getMyHarmony()); activities = hubs.get(key).getMyHarmony().getActivities().iterator(); if (activities == null) { - log.error("Could not get communication restored with hub: " + key + ", please restart..."); + if (resetHub(hubs.get(key).getMyHarmony())) { + activities = hubs.get(key).getMyHarmony().getActivities().iterator(); + if (activities == null) { + log.error("Could not get communication restored with hub: " + key + + ", please restart..."); + } + } } } if (activities != null) { @@ -120,7 +126,13 @@ public class HarmonyHome implements Home { resetHub(hubs.get(key).getMyHarmony()); theActivity = hubs.get(key).getMyHarmony().getCurrentActivity(); if (theActivity == null) { - log.error("Could not get communication restored with hub: " + key + ", please restart..."); + if (resetHub(hubs.get(key).getMyHarmony())) { + theActivity = hubs.get(key).getMyHarmony().getCurrentActivity(); + if (theActivity == null) { + log.error("Could not get communication restored with hub: " + key + + ", please restart..."); + } + } } } if (theActivity != null) { @@ -145,7 +157,13 @@ public class HarmonyHome implements Home { resetHub(hubs.get(key).getMyHarmony()); devices = hubs.get(key).getMyHarmony().getDevices().iterator(); if (devices == null) { - log.error("Could not get communication restored with hub: " + key + ", please restart..."); + if (resetHub(hubs.get(key).getMyHarmony())) { + devices = hubs.get(key).getMyHarmony().getDevices().iterator(); + if (devices == null) { + log.error("Could not get communication restored with hub: " + key + + ", please restart..."); + } + } } } if (devices != null) { @@ -239,7 +257,7 @@ public class HarmonyHome implements Home { if (myHarmony == null) log.warn("Button Press - Should not get here, no harmony hub available"); else{ - if (myHarmony.pressButton(deviceButtons[z])) { + if (!myHarmony.pressButton(deviceButtons[z])) { if (resetHub(myHarmony)) { myHarmony = getHarmonyHandler(deviceButtons[z].getHub()); if (!myHarmony.pressButton(deviceButtons[z])) { diff --git a/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java b/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java index f40edf3..21db858 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java @@ -9,7 +9,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import javax.xml.bind.DatatypeConverter; +import com.bwssystems.HABridge.util.HexLibrary; import org.apache.commons.lang3.StringEscapeUtils; import org.slf4j.Logger; @@ -92,7 +92,7 @@ public class TCPHome implements Home { if (colorData != null) { theUrlBody = ColorDecode.replaceColorData(theUrlBody, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), true); } - sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2)); + sendData = HexLibrary.decodeHexString(theUrlBody.substring(2)); } else { theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, false); if (colorData != null) { diff --git a/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java b/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java index 22315fd..666521c 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java @@ -4,7 +4,7 @@ import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; -import javax.xml.bind.DatatypeConverter; +import com.bwssystems.HABridge.util.HexLibrary; import org.apache.commons.lang3.StringEscapeUtils; import org.slf4j.Logger; @@ -68,7 +68,7 @@ public class UDPHome implements Home { if (colorData != null) { theUrlBody = ColorDecode.replaceColorData(theUrlBody, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), true); } - sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2)); + sendData = HexLibrary.decodeHexString(theUrlBody.substring(2)); } else { theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, false); diff --git a/src/main/java/com/bwssystems/HABridge/util/HexLibrary.java b/src/main/java/com/bwssystems/HABridge/util/HexLibrary.java new file mode 100644 index 0000000..e3c3de3 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/util/HexLibrary.java @@ -0,0 +1,72 @@ +package com.bwssystems.HABridge.util; + +import java.math.BigInteger; + +public class HexLibrary { + + public static String byteToHex(byte num) { + char[] hexDigits = new char[2]; + hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16); + hexDigits[1] = Character.forDigit((num & 0xF), 16); + return new String(hexDigits); + } + + public static byte hexToByte(String hexString) { + int firstDigit = toDigit(hexString.charAt(0)); + int secondDigit = toDigit(hexString.charAt(1)); + return (byte) ((firstDigit << 4) + secondDigit); + } + + private static int toDigit(char hexChar) { + int digit = Character.digit(hexChar, 16); + if (digit == -1) { + throw new IllegalArgumentException("Invalid Hexadecimal Character: " + hexChar); + } + return digit; + } + + public static String encodeHexString(byte[] byteArray) { + StringBuffer hexStringBuffer = new StringBuffer(); + for (int i = 0; i < byteArray.length; i++) { + hexStringBuffer.append(byteToHex(byteArray[i])); + } + return hexStringBuffer.toString(); + } + + public static byte[] decodeHexString(String hexString) { + if (hexString.length() % 2 == 1) { + throw new IllegalArgumentException("Invalid hexadecimal String supplied."); + } + + byte[] bytes = new byte[hexString.length() / 2]; + for (int i = 0; i < hexString.length(); i += 2) { + bytes[i / 2] = hexToByte(hexString.substring(i, i + 2)); + } + return bytes; + } + + public static String encodeUsingBigIntegerStringFormat(byte[] bytes) { + BigInteger bigInteger = new BigInteger(1, bytes); + return String.format("%0" + (bytes.length << 1) + "x", bigInteger); + } + + public static String encodeUsingBigIntegerToString(String intValue) { + BigInteger bigInteger = BigInteger.valueOf(Integer.decode(intValue)); + return bigInteger.toString(16); + } + + public static String encodeUsingBigIntegerToString(byte[] bytes) { + BigInteger bigInteger = new BigInteger(1, bytes); + return bigInteger.toString(16); + } + + public static byte[] decodeUsingBigInteger(String hexString) { + byte[] byteArray = new BigInteger(hexString, 16).toByteArray(); + if (byteArray[0] == 0) { + byte[] output = new byte[byteArray.length - 1]; + System.arraycopy(byteArray, 1, output, 0, output.length); + return output; + } + return byteArray; + } +} diff --git a/src/test/java/com/bwssystems/broadlink/test/BroadlinkDataConstructor.java b/src/test/java/com/bwssystems/broadlink/test/BroadlinkDataConstructor.java index e2c80e6..b5a258d 100644 --- a/src/test/java/com/bwssystems/broadlink/test/BroadlinkDataConstructor.java +++ b/src/test/java/com/bwssystems/broadlink/test/BroadlinkDataConstructor.java @@ -1,6 +1,6 @@ package com.bwssystems.broadlink.test; -import javax.xml.bind.DatatypeConverter; +import com.bwssystems.HABridge.util.HexLibrary; public class BroadlinkDataConstructor { public final static byte[] testData1 = { 84, 104, 105, 115, 73, 115, 65, 84, 101, 115, 116, 83, 116, 114, 105, 110, 103, 49 }; @@ -18,8 +18,8 @@ public class BroadlinkDataConstructor { System.out.println("----------------------------------"); System.out.println("This is the test hex string: <<<" + theHexString + ">>>"); try { - theData = DatatypeConverter.parseHexBinary(theHexString); - System.out.println("This is the test hex string from data bytes: <<<" + DatatypeConverter.printHexBinary(theData) + ">>>"); + theData = HexLibrary.decodeHexString(theHexString); + System.out.println("This is the test hex string from data bytes: <<<" + HexLibrary.encodeHexString(theData) + ">>>"); } catch(Exception e) { System.out.println("Error parsing he string: " + e.getMessage()); return false;