From 58e1679529d36bdd5e930fdb1508c6c5ab5f38c0 Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Mon, 23 Jan 2017 19:05:29 -0600 Subject: [PATCH 1/7] updated jar version --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a4dd638..8c21726 100644 --- a/README.md +++ b/README.md @@ -31,16 +31,16 @@ ATTENTION: This requires JDK 1.8 to run ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below. ``` -java -jar ha-bridge-4.0.0.jar +java -jar ha-bridge-4.0.1.jar ``` ### Automation on Linux systems To have this configured and running automatically there are a few resources to use. One is using Docker and a docker container has been built for this and can be gotten here: https://github.com/aptalca/docker-ha-bridge -Create the directory and make sure that ha-bridge-4.0.0.jar is in your /home/pi/habridge directory. +Create the directory and make sure that ha-bridge-4.0.1.jar is in your /home/pi/habridge directory. ``` pi@raspberrypi:~ $ mkdir habridge pi@raspberrypi:~ $ cd habridge -pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.0.0/ha-bridge-4.0.0.jar +pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.0.1/ha-bridge-4.0.1.jar ``` #### System Control Setup on a pi (preferred) For next gen Linux systems (this includes the Raspberry Pi), here is a systemctl unit file that you can install. Here is a link on how to do this: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units @@ -59,7 +59,7 @@ After=network.target [Service] Type=simple -ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.0.jar +ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.1.jar [Install] WantedBy=multi-user.target @@ -94,7 +94,7 @@ Then cut and past this, modify any locations that are not correct ``` cd /home/pi/habridge rm /home/pi/habridge/habridge-log.txt -nohup java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.0.jar > /home/pi/habridge/habridge-log.txt 2>&1 & +nohup java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.1.jar > /home/pi/habridge/habridge-log.txt 2>&1 & chmod 777 /home/pi/habridge/habridge-log.txt ``` Exit and save the file with ctrl-X and follow the prompts and then execute on the command line: From fd486588f5999a0c7b418fd9766b2fe5ed46c500 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 24 Jan 2017 09:31:48 -0600 Subject: [PATCH 2/7] Fixed more immediate issues Fixes #272 Fixes #384 Fixes #387 Fixes #389 --- pom.xml | 2 +- .../HABridge/hue/BrightnessDecode.java | 4 +- .../bwssystems/HABridge/hue/HueMulator.java | 6 +- .../HABridge/plugins/NestBridge/NestHome.java | 80 ++++++++++--------- .../HABridge/plugins/exec/CommandHome.java | 2 +- .../HABridge/plugins/hass/HassHome.java | 8 +- .../HABridge/plugins/hue/HueHome.java | 6 +- .../HABridge/plugins/mqtt/MQTTHome.java | 7 +- 8 files changed, 68 insertions(+), 47 deletions(-) diff --git a/pom.xml b/pom.xml index c8d90b4..59ffd55 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.0.1 + 4.0.2 jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/hue/BrightnessDecode.java b/src/main/java/com/bwssystems/HABridge/hue/BrightnessDecode.java index 0c26dfd..55da9dd 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/BrightnessDecode.java +++ b/src/main/java/com/bwssystems/HABridge/hue/BrightnessDecode.java @@ -26,7 +26,7 @@ public class BrightnessDecode { } else if (targetBriInc != null) { if ((setIntensity + targetBriInc) <= 0) setIntensity = targetBriInc; - else if ((setIntensity + targetBriInc) > 255) + else if ((setIntensity + targetBriInc) > 254) setIntensity = targetBriInc; else setIntensity = setIntensity + targetBriInc; @@ -38,7 +38,7 @@ public class BrightnessDecode { * 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 + * currently provides: intensity.byte : 0-254 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 diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 87829fc..4618abb 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -276,7 +276,7 @@ public class HueMulator { } if (deviceState != null) { deviceState.setOn(stateChanges.isOn()); - if(!deviceState.isOn() && deviceState.getBri() == 255) + if(!deviceState.isOn() && deviceState.getBri() == 254) deviceState.setBri(0); } notFirstChange = true; @@ -416,7 +416,7 @@ public class HueMulator { } if(deviceState.isOn() && deviceState.getBri() <= 0) - deviceState.setBri(255); + deviceState.setBri(254); if(!deviceState.isOn() && (targetBri != null || targetBriInc != null)) deviceState.setOn(true); @@ -734,7 +734,7 @@ public class HueMulator { if(url == null) url = device.getOnUrl(); } - if (url != null) { + if (url != null && !url.equals("")) { if (!url.startsWith("[")) { if (url.startsWith("{\"item")) url = "[" + url + "]"; diff --git a/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java b/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java index 8af25a3..3e4bc9d 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java @@ -111,46 +111,54 @@ public class NestHome implements com.bwssystems.HABridge.Home { + "\",\"description\": \"Should not get here, no Nest available\", \"parameter\": \"/lights/" + lightId + "state\"}}]"; } else if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.NEST_HOMEAWAY[DeviceMapTypes.typeIndex])) { - NestInstruction homeAway = aGsonHandler.fromJson(anItem.getItem().toString(), NestInstruction.class); + NestInstruction homeAway = null; + if(anItem.getItem().isJsonObject()) + homeAway = aGsonHandler.fromJson(anItem.getItem(), NestInstruction.class); + else + homeAway = aGsonHandler.fromJson(anItem.getItem().getAsString(), NestInstruction.class); theNest.getHome(homeAway.getName()).setAway(homeAway.getAway()); } else if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.NEST_THERMO_SET[DeviceMapTypes.typeIndex])) { - NestInstruction thermoSetting = aGsonHandler.fromJson(anItem.getItem().toString(), NestInstruction.class); - if (thermoSetting.getControl().equalsIgnoreCase("temp")) { - if (targetBri != null) { - if (isFarenheit) - thermoSetting - .setTemp( - String.valueOf((Double - .parseDouble(BrightnessDecode.calculateReplaceIntensityValue(thermoSetting.getTemp(), - intensity, targetBri, targetBriInc, false)) - 32.0) / 1.8)); - else - thermoSetting - .setTemp( - String.valueOf(Double.parseDouble(BrightnessDecode.calculateReplaceIntensityValue(thermoSetting.getTemp(), - intensity, targetBri, targetBriInc, false)))); - log.debug("Setting thermostat: " + thermoSetting.getName() + " to " - + thermoSetting.getTemp() + "C"); - theNest.getThermostat(thermoSetting.getName()) - .setTargetTemperature(Float.parseFloat(thermoSetting.getTemp())); - } - } else if (thermoSetting.getControl().contains("range") - || thermoSetting.getControl().contains("heat") - || thermoSetting.getControl().contains("cool") - || thermoSetting.getControl().contains("off")) { - log.debug("Setting thermostat target type: " + thermoSetting.getName() + " to " - + thermoSetting.getControl()); - theNest.getThermostat(thermoSetting.getName()).setTargetType(thermoSetting.getControl()); - } else if (thermoSetting.getControl().contains("fan")) { - log.debug("Setting thermostat fan mode: " + thermoSetting.getName() + " to " - + thermoSetting.getControl().substring(4)); + NestInstruction thermoSetting = null; + if(anItem.getItem().isJsonObject()) + thermoSetting = aGsonHandler.fromJson(anItem.getItem(), NestInstruction.class); + else + thermoSetting = aGsonHandler.fromJson(anItem.getItem().getAsString(), NestInstruction.class); + if (thermoSetting.getControl().equalsIgnoreCase("temp")) { + if (targetBri != null) { + if (isFarenheit) + thermoSetting + .setTemp( + String.valueOf((Double + .parseDouble(BrightnessDecode.calculateReplaceIntensityValue(thermoSetting.getTemp(), + intensity, targetBri, targetBriInc, false)) - 32.0) / 1.8)); + else + thermoSetting + .setTemp( + String.valueOf(Double.parseDouble(BrightnessDecode.calculateReplaceIntensityValue(thermoSetting.getTemp(), + intensity, targetBri, targetBriInc, false)))); + log.debug("Setting thermostat: " + thermoSetting.getName() + " to " + + thermoSetting.getTemp() + "C"); theNest.getThermostat(thermoSetting.getName()) - .setFanMode(thermoSetting.getControl().substring(4)); - } else { - log.warn("no valid Nest control info: " + thermoSetting.getControl()); - responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId - + "\",\"description\": \"no valid Nest control info\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + .setTargetTemperature(Float.parseFloat(thermoSetting.getTemp())); } + } else if (thermoSetting.getControl().contains("range") + || thermoSetting.getControl().contains("heat") + || thermoSetting.getControl().contains("cool") + || thermoSetting.getControl().contains("off")) { + log.debug("Setting thermostat target type: " + thermoSetting.getName() + " to " + + thermoSetting.getControl()); + theNest.getThermostat(thermoSetting.getName()).setTargetType(thermoSetting.getControl()); + } else if (thermoSetting.getControl().contains("fan")) { + log.debug("Setting thermostat fan mode: " + thermoSetting.getName() + " to " + + thermoSetting.getControl().substring(4)); + theNest.getThermostat(thermoSetting.getName()) + .setFanMode(thermoSetting.getControl().substring(4)); + } else { + log.warn("no valid Nest control info: " + thermoSetting.getControl()); + responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + + "\",\"description\": \"no valid Nest control info\", \"parameter\": \"/lights/" + + lightId + "state\"}}]"; + } } return responseString; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java b/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java index 71ef5f0..f87c48b 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java @@ -26,7 +26,7 @@ public class CommandHome implements Home { String responseString = null; String intermediate; if (anItem.getItem().toString().contains("exec://")) - intermediate = anItem.getItem().getAsString().substring(anItem.getItem().toString().indexOf("://") + 3); + intermediate = anItem.getItem().getAsString().substring(anItem.getItem().getAsString().indexOf("://") + 3); else intermediate = anItem.getItem().getAsString(); String anError = doExecRequest(intermediate, diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java b/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java index fd8df64..fd73f33 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java @@ -125,9 +125,13 @@ public class HassHome implements Home { + lightId + "state\"}}]"; } else { - HassCommand hassCommand = aGsonHandler.fromJson(anItem.getItem(), HassCommand.class); + HassCommand hassCommand = null; + if(anItem.getItem().isJsonObject()) + hassCommand = aGsonHandler.fromJson(anItem.getItem(), HassCommand.class); + else + hassCommand = aGsonHandler.fromJson(anItem.getItem().getAsString(), HassCommand.class); hassCommand.setBri(BrightnessDecode.replaceIntensityValue(hassCommand.getBri(), - BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false)); + BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false)); HomeAssistant homeAssistant = getHomeAssistant(hassCommand.getHassName()); if (homeAssistant == null) { log.warn("Should not get here, no HomeAssistants available"); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hue/HueHome.java b/src/main/java/com/bwssystems/HABridge/plugins/hue/HueHome.java index 3bfcf5c..e0c5b76 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hue/HueHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hue/HueHome.java @@ -80,7 +80,11 @@ public class HueHome implements Home { if(!validHue) return null; String responseString = null; - HueDeviceIdentifier deviceId = aGsonHandler.fromJson(anItem.getItem(), HueDeviceIdentifier.class); + HueDeviceIdentifier deviceId = null; + if(anItem.getItem().isJsonObject()) + deviceId = aGsonHandler.fromJson(anItem.getItem(), HueDeviceIdentifier.class); + else + deviceId = aGsonHandler.fromJson(anItem.getItem().getAsString(), HueDeviceIdentifier.class); if(deviceId.getHueName() == null || deviceId.getHueName().isEmpty()) deviceId.setHueName(device.getTargetDevice()); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java b/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java index c544762..4716199 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java @@ -79,8 +79,13 @@ public class MQTTHome implements Home { String responseString = null; log.debug("executing HUE api request to send message to MQTT broker: " + anItem.getItem().toString()); if (validMqtt) { - String mqttObject = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().toString(), + String mqttObject = null; + if(anItem.getItem().isJsonObject()) + mqttObject = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(), intensity, targetBri, targetBriInc, false); + else + mqttObject = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().toString(), + intensity, targetBri, targetBriInc, false); if (mqttObject.substring(0, 1).equalsIgnoreCase("{")) mqttObject = "[" + mqttObject + "]"; MQTTMessage[] mqttMessages = aGsonHandler.fromJson(mqttObject, MQTTMessage[].class); From f148c2b9fcb4b2750b4665085fb2d2799e3727b6 Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Tue, 24 Jan 2017 10:28:14 -0600 Subject: [PATCH 3/7] updated jar version --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8c21726..8a5f371 100644 --- a/README.md +++ b/README.md @@ -31,16 +31,16 @@ ATTENTION: This requires JDK 1.8 to run ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below. ``` -java -jar ha-bridge-4.0.1.jar +java -jar ha-bridge-4.0.2.jar ``` ### Automation on Linux systems To have this configured and running automatically there are a few resources to use. One is using Docker and a docker container has been built for this and can be gotten here: https://github.com/aptalca/docker-ha-bridge -Create the directory and make sure that ha-bridge-4.0.1.jar is in your /home/pi/habridge directory. +Create the directory and make sure that ha-bridge-4.0.2.jar is in your /home/pi/habridge directory. ``` pi@raspberrypi:~ $ mkdir habridge pi@raspberrypi:~ $ cd habridge -pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.0.1/ha-bridge-4.0.1.jar +pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.0.2/ha-bridge-4.0.2.jar ``` #### System Control Setup on a pi (preferred) For next gen Linux systems (this includes the Raspberry Pi), here is a systemctl unit file that you can install. Here is a link on how to do this: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units @@ -59,7 +59,7 @@ After=network.target [Service] Type=simple -ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.1.jar +ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.2.jar [Install] WantedBy=multi-user.target @@ -94,7 +94,7 @@ Then cut and past this, modify any locations that are not correct ``` cd /home/pi/habridge rm /home/pi/habridge/habridge-log.txt -nohup java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.1.jar > /home/pi/habridge/habridge-log.txt 2>&1 & +nohup java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.2.jar > /home/pi/habridge/habridge-log.txt 2>&1 & chmod 777 /home/pi/habridge/habridge-log.txt ``` Exit and save the file with ctrl-X and follow the prompts and then execute on the command line: From 881f739c0b60e1d3a4d8a90419edbd58290e3074 Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Tue, 24 Jan 2017 12:47:36 -0600 Subject: [PATCH 4/7] Added proxy instructions --- README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/README.md b/README.md index 8a5f371..e110671 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,54 @@ You should now be running the bridge. Check for errors: ``` pi@raspberrypi:~/habridge $ tail -f habridge-log.txt ``` +## Run ha-bridge alongside web server already on port 80 +These examples will help you proxy your current webserver requests to the ha-bridge running on a different port, such as 8080. +### Apache Example +Reverse proxy with Apache on Ubuntu linux: + +a2enmod proxy +a2enmod proxy_http +a2enmod headers + +Added the following lines to my Apache config file “000-default” + +``` + + ProxyPass /api http://localhost:8080/api nocanon + ProxyPassReverse /api http://localhost:8080/api + ProxyRequests Off + AllowEncodedSlashes NoDecode + + # Local reverse proxy authorization override + # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu) + + Order deny,allow + Allow from all + + +….. (the rest of the VirtualHost config section) ….. + +``` + +service apache2 restart +### lighthttpd Example +``` +server.modules += ( "mod_proxy" ) +proxy.server = ( + "/api" => + ( + ( "host" => "127.0.0.1", + "port" => "8080" + ) + ) +) +``` +### nginx Example +``` +location /api/ { + proxy_pass http://127.0.0.1:8080/api; +} +``` ## Available Arguments Arguments are now deprecated. The ha-bridge will use the old -D arguments and populate the configuration screen, Brisge Control Tab, which can now be saved to a file and will not be needed. There is only one optional argument that overrides and that is the location of the configuration file. The default is the relative path "data/habridge.config". ### -Dconfig.file=`` From 5a3a02cb341ca2a70f797f5b28f6d9ea910afa09 Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Wed, 25 Jan 2017 12:14:59 -0600 Subject: [PATCH 5/7] Added security note. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e110671..3c4c115 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # ha-bridge Emulates Philips Hue api to other home automation gateways such as an Amazon Echo or Google Home. The Bridge handles basic commands such as "On", "Off" and "brightness" commands of the hue protocol. This bridge can control most devices that have a distinct API. +**SECURITY RISK: If you are unsure on how this software operates and what it exposes to your netowrk, please make sure you understand that it can allow root access to your sytem. It is best practice to not open this to the itnernet through your router as there are no security protocols in place to protect the system. The Licenese agreement states specifically that you use this at your own risk.** + **ATTENTION: This requires a physical Amazon Echo, Dot or Tap and does not work with prototype devices built using the Alexa Voice Service e.g. Amazon's Alexa AVS Sample App and Sam Machin's AlexaPi. The AVS version does not have any capability for Hue Bridge discovery!** **NOTE: This software does require the user to have knwoledge on how processes run on Linux or Windows with java. Also, an understanding of networking basics will help as well. This system reveives upnp udp multicast packets from devices to be found, so that is some thing to understand. Please make sure you have all your devices use static IP addresses from your router. Most all questions have been answered already. PLEASE USE GOOGLE TO FIND YOUR ANSWERS!** From c9d55e26aca23ef5b2160bd2c8ac0890b8251585 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 25 Jan 2017 15:19:46 -0600 Subject: [PATCH 6/7] Fix immediate issues for JSON decoding Fixes #391 Fixes #392 Fixes #398 --- README.md | 12 +++++++----- pom.xml | 2 +- src/main/java/com/bwssystems/HABridge/NamedIP.java | 7 +++++++ .../java/com/bwssystems/HABridge/hue/HueMulator.java | 11 ++++++----- .../HABridge/plugins/exec/CommandHome.java | 2 +- .../com/bwssystems/HABridge/plugins/hal/HalHome.java | 7 ++++--- .../HABridge/plugins/harmony/HarmonyHome.java | 7 ++++++- .../bwssystems/HABridge/plugins/http/HTTPHome.java | 7 ++++--- .../bwssystems/HABridge/plugins/mqtt/MQTTHome.java | 10 ++++++---- 9 files changed, 42 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index e110671..e16bcf9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # ha-bridge Emulates Philips Hue api to other home automation gateways such as an Amazon Echo or Google Home. The Bridge handles basic commands such as "On", "Off" and "brightness" commands of the hue protocol. This bridge can control most devices that have a distinct API. +**SECURITY RISK: If you are unsure on how this software operates and what it exposes to your netowrk, please make sure you understand that it can allow root access to your sytem. It is best practice to not open this to the itnernet through your router as there are no security protocols in place to protect the system. The Licenese agreement states specifically that you use this at your own risk.** + **ATTENTION: This requires a physical Amazon Echo, Dot or Tap and does not work with prototype devices built using the Alexa Voice Service e.g. Amazon's Alexa AVS Sample App and Sam Machin's AlexaPi. The AVS version does not have any capability for Hue Bridge discovery!** **NOTE: This software does require the user to have knwoledge on how processes run on Linux or Windows with java. Also, an understanding of networking basics will help as well. This system reveives upnp udp multicast packets from devices to be found, so that is some thing to understand. Please make sure you have all your devices use static IP addresses from your router. Most all questions have been answered already. PLEASE USE GOOGLE TO FIND YOUR ANSWERS!** @@ -31,16 +33,16 @@ ATTENTION: This requires JDK 1.8 to run ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below. ``` -java -jar ha-bridge-4.0.2.jar +java -jar ha-bridge-4.0.3.jar ``` ### Automation on Linux systems To have this configured and running automatically there are a few resources to use. One is using Docker and a docker container has been built for this and can be gotten here: https://github.com/aptalca/docker-ha-bridge -Create the directory and make sure that ha-bridge-4.0.2.jar is in your /home/pi/habridge directory. +Create the directory and make sure that ha-bridge-4.0.3.jar is in your /home/pi/habridge directory. ``` pi@raspberrypi:~ $ mkdir habridge pi@raspberrypi:~ $ cd habridge -pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.0.2/ha-bridge-4.0.2.jar +pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.0.3/ha-bridge-4.0.3.jar ``` #### System Control Setup on a pi (preferred) For next gen Linux systems (this includes the Raspberry Pi), here is a systemctl unit file that you can install. Here is a link on how to do this: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units @@ -59,7 +61,7 @@ After=network.target [Service] Type=simple -ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.2.jar +ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.3.jar [Install] WantedBy=multi-user.target @@ -94,7 +96,7 @@ Then cut and past this, modify any locations that are not correct ``` cd /home/pi/habridge rm /home/pi/habridge/habridge-log.txt -nohup java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.2.jar > /home/pi/habridge/habridge-log.txt 2>&1 & +nohup java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.3.jar > /home/pi/habridge/habridge-log.txt 2>&1 & chmod 777 /home/pi/habridge/habridge-log.txt ``` Exit and save the file with ctrl-X and follow the prompts and then execute on the command line: diff --git a/pom.xml b/pom.xml index 59ffd55..2def510 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.0.2 + 4.0.3 jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/NamedIP.java b/src/main/java/com/bwssystems/HABridge/NamedIP.java index 38a6d7f..145f798 100644 --- a/src/main/java/com/bwssystems/HABridge/NamedIP.java +++ b/src/main/java/com/bwssystems/HABridge/NamedIP.java @@ -6,6 +6,7 @@ public class NamedIP { private String port; private String username; private String password; + private Boolean secure; public String getName() { return name; @@ -37,4 +38,10 @@ public class NamedIP { public void setPassword(String password) { this.password = password; } + public Boolean getSecure() { + return secure; + } + public void setSecure(Boolean secure) { + this.secure = secure; + } } diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 4618abb..ae483aa 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -524,10 +524,11 @@ public class HueMulator { deviceResponseMap = new HashMap(); for (DeviceDescriptor device : deviceList) { DeviceResponse deviceResponse = null; - if ((device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex]))) { - HueDeviceIdentifier deviceId = aGsonHandler.fromJson(device.getOnUrl(), HueDeviceIdentifier.class); - deviceResponse = myHueHome.getHueDeviceInfo(deviceId, device); - } + // In the multi command context, this is not valid anymore +// if ((device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex]))) { +// HueDeviceIdentifier deviceId = aGsonHandler.fromJson(device.getOnUrl(), HueDeviceIdentifier.class); +// deviceResponse = myHueHome.getHueDeviceInfo(deviceId, device); +// } if (deviceResponse == null) deviceResponse = DeviceResponse.createResponse(device); @@ -730,7 +731,7 @@ public class HueMulator { } // code for backwards compatibility - if(!(device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex]))) { + if(device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) { if(url == null) url = device.getOnUrl(); } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java b/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java index f87c48b..2e60e9e 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java @@ -25,7 +25,7 @@ public class CommandHome implements Home { log.debug("Exec Request called with url: " + anItem.getItem().getAsString()); String responseString = null; String intermediate; - if (anItem.getItem().toString().contains("exec://")) + if (anItem.getItem().getAsString().contains("exec://")) intermediate = anItem.getItem().getAsString().substring(anItem.getItem().getAsString().indexOf("://") + 3); else intermediate = anItem.getItem().getAsString(); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java b/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java index a153bf7..f57e44f 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java @@ -125,9 +125,10 @@ public class HalHome implements Home { String anUrl = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(), intensity, targetBri, targetBriInc, false); - String aBody; - aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(), - intensity, targetBri, targetBriInc, false); + String aBody = null; + if(anItem.getHttpBody()!= null && !anItem.getHttpBody().isEmpty()) + aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(), + intensity, targetBri, targetBriInc, false); // make call if (anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody, new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class)) == null) { 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 8038a66..592cabb 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java @@ -152,7 +152,12 @@ public class HarmonyHome implements Home { myHarmony.startActivity(anActivity); } } else if(anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.HARMONY_BUTTON[DeviceMapTypes.typeIndex])) { - String url = anItem.getItem().toString(); + String url = null; + if(anItem.getItem().isJsonObject()) { + url = aGsonHandler.toJson(anItem.getItem()); + } else + url = anItem.getItem().getAsString(); + if (url.substring(0, 1).equalsIgnoreCase("{")) { url = "[" + url + "]"; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java index ff561bb..bbc2db9 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java @@ -46,9 +46,10 @@ public class HTTPHome implements Home { String anUrl = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(), intensity, targetBri, targetBriInc, false); - String aBody; - aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(), - intensity, targetBri, targetBriInc, false); + String aBody = null; + if(anItem.getHttpBody()!= null && !anItem.getHttpBody().isEmpty()) + aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(), + intensity, targetBri, targetBriInc, false); // make call if (anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody, new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class)) == null) { diff --git a/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java b/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java index 4716199..0831407 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java @@ -80,11 +80,13 @@ public class MQTTHome implements Home { log.debug("executing HUE api request to send message to MQTT broker: " + anItem.getItem().toString()); if (validMqtt) { String mqttObject = null; - if(anItem.getItem().isJsonObject()) - mqttObject = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(), - intensity, targetBri, targetBriInc, false); + if(anItem.getItem().isJsonObject() || anItem.getItem().isJsonArray()) { + String theItem = aGsonHandler.toJson(anItem.getItem()); + mqttObject = BrightnessDecode.calculateReplaceIntensityValue(theItem, + intensity, targetBri, targetBriInc, false); + } else - mqttObject = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().toString(), + mqttObject = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(), intensity, targetBri, targetBriInc, false); if (mqttObject.substring(0, 1).equalsIgnoreCase("{")) mqttObject = "[" + mqttObject + "]"; From b08a285bd01926504686ab0f93d83b8d62493279 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 25 Jan 2017 15:23:48 -0600 Subject: [PATCH 7/7] One more update for JsonArray detection. --- .../com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 592cabb..5857f08 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java @@ -153,7 +153,7 @@ public class HarmonyHome implements Home { } } else if(anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.HARMONY_BUTTON[DeviceMapTypes.typeIndex])) { String url = null; - if(anItem.getItem().isJsonObject()) { + if(anItem.getItem().isJsonObject() || anItem.getItem().isJsonArray()) { url = aGsonHandler.toJson(anItem.getItem()); } else url = anItem.getItem().getAsString();