Skip to content

Commit 3e89072

Browse files
committed
Fixed handling of dim and brigthen requests as they were not setting the
state appropriately for other systems. Fixed handling of data return from an http call if the entity was empty. Fixes #102 Fixes #107
1 parent 62d1c64 commit 3e89072

File tree

3 files changed

+65
-48
lines changed

3 files changed

+65
-48
lines changed

README.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Then locate the jar and start the server with:
2121
ATTENTION: This requires JDK 1.8 to run
2222

2323
```
24-
java -jar ha-bridge-W.X.Y.jar
24+
java -jar ha-bridge-2.0.5.jar
2525
```
2626
### Automation on Linux systems
2727
To have this conigured and running automatically ther eare 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
@@ -35,7 +35,7 @@ After=network.target
3535
3636
[Service]
3737
Type=simple
38-
ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/amazon-echo/data/habridge.config /home/pi/amazon-echo/ha-bridge-2.0.4.jar
38+
ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/amazon-echo/data/habridge.config /home/pi/amazon-echo/ha-bridge-2.0.5.jar
3939
4040
[Install]
4141
WantedBy=multi-user.target
@@ -109,7 +109,7 @@ This screen displays the last 512 or number of rows defined in the config screen
109109

110110
The bottom part of the Logs Screen has configuration to change the logging levels as it is running. The ROOT is the basic setting and will turn on only top level logging. To set logging at a lower level, select the `Show All Loggers` checkbox and then you can set the explicit level on each of the processes components. The most helpful logger would be setting DEBUG for com.bwssystems.HABridge.hue.HueMulator component. Changing this and then selecting the `Update Log Levels` button applies the new log settings.
111111
### Bridge Device Additions
112-
You must configure devices before you will have any thing for the Echo or other contoller that is connected to the ha-bridge to receive.
112+
You must configure devices before you will have any thing for the Echo or other controller that is connected to the ha-bridge to receive.
113113
#### Helpers
114114
The easy way to get devices configured is with the use of the helpers for the Vera or Harmony, Nest and Hue to create devices that the bridge will present.
115115

@@ -217,13 +217,15 @@ OFF Commands |
217217
DIM Commands |
218218
| Alexa, brighten `<Device Name>` to `<Position>`
219219
| Alexa, dim `<Device Name> to <Position>`
220+
| Alexa, brighten `<Device Name>`
221+
| Alexa, dim `<Device Name>`
220222
| Alexa, raise `<Device Name>` to `<Position>`
221223
| Alexa, lower `<Device Name>` to `<Position>`
222224
| Alexa, set `<Device Name>` to `<Position>`
223225
| Alexa, turn up `<Device Name>` to `<Position>`
224226
| Alexa, turn down `<Device Name>` to `<Position>`
225227

226-
To see what Alexa thinks you said, you can check in the home page for your alexa.
228+
To see what Alexa thinks you said, you can check in the home page for your Alexa.
227229

228230
To view or remove devices that Alexa knows about, you can use the mobile app `Menu / Settings / Connected Home` or go to http://echo.amazon.com/#cards.
229231
## Configuration REST API Usage
@@ -264,7 +266,7 @@ contentBodyOff | string | This is the content body that you would like to send w
264266
}
265267
```
266268
#### Dimming Control Example
267-
Dimming is also supported by using the expressions ${intensity.percent} for 0-100 or ${intensity.byte} for 0-255 for straight pass trhough of the value.
269+
Dimming is also supported by using the expressions ${intensity.percent} for 0-100 or ${intensity.byte} for 0-255 for straight pass through of the value.
268270
e.g.
269271
```
270272
{
@@ -872,7 +874,7 @@ rules | object | A collection of all rules and their attributes. This is not giv
872874
## UPNP Emulation of HUE
873875
This section will discuss the UPNP implementation of this bridge based as much as can be for the HUE.
874876
### UPNP listening
875-
The HA Bridge default UPNP listner is started on port 1900 on the upnp multicast address of 239.255.255.250. All ethernet interfaces that are active are bound to and the repsonse port is set to the one given on the command line above or the default of 50000.
877+
The HA Bridge default UPNP listener is started on port 1900 on the upnp multicast address of 239.255.255.250. All ethernet interfaces that are active are bound to and the response port is set to the one given on the command line above or the default of 50000.
876878

877879
The listener will respond to the following body packet that contain the following minimal information:
878880

@@ -898,7 +900,7 @@ ST: urn:schemas-upnp-org:device:basic:1\r\n
898900
"USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1\r\n\r\n
899901
```
900902
### UPNP description service
901-
The bridge provides the description service which is used by the calling app to interogate access details after it has decided the upnp multicast repsonse is the correct device.
903+
The bridge provides the description service which is used by the calling app to interogate access details after it has decided the upnp multicast response is the correct device.
902904
#### Get Description
903905
```
904906
GET http://host:8080/description.xml

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>com.bwssystems.HABridge</groupId>
77
<artifactId>ha-bridge</artifactId>
8-
<version>2.0.4</version>
8+
<version>2.0.5</version>
99
<packaging>jar</packaging>
1010

1111
<name>HA Bridge</name>

src/main/java/com/bwssystems/HABridge/hue/HueMulator.java

+55-40
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,15 @@ public void setupServer() {
317317
String lightId = request.params(":id");
318318
String responseString = null;
319319
DeviceState state = null;
320+
boolean stateHasOn = false;
320321
log.debug("Update state requested: " + userId + " from " + request.ip() + " body: " + request.body());
321322
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
322323
response.type("application/json; charset=utf-8");
323324
response.status(HttpStatus.SC_OK);
324325
try {
325326
state = mapper.readValue(request.body(), DeviceState.class);
327+
if(request.body().contains("\"on\""))
328+
stateHasOn = true;
326329
} catch (IOException e) {
327330
log.warn("Object mapper barfed on input of body.", e);
328331
responseString = "[{\"error\":{\"type\": 2, \"address\": \"/lights/" + lightId + "\",\"description\": \"Object mapper barfed on input of body.\"}}]";
@@ -335,7 +338,7 @@ public void setupServer() {
335338
return responseString;
336339
}
337340

338-
responseString = this.formatSuccessHueResponse(state, request.body(), lightId);
341+
responseString = this.formatSuccessHueResponse(state, request.body(), stateHasOn, lightId);
339342
device.setDeviceState(state);
340343

341344
return responseString;
@@ -362,13 +365,19 @@ public void setupServer() {
362365
String url = null;
363366
NameValue[] theHeaders = null;
364367
DeviceState state = null;
368+
boolean stateHasBri = false;
369+
boolean stateHasOn = false;
365370
log.debug("hue state change requested: " + userId + " from " + request.ip() + " body: " + request.body());
366371
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
367372
response.type("application/json; charset=utf-8");
368373
response.status(HttpStatus.SC_OK);
369374

370375
try {
371376
state = mapper.readValue(request.body(), DeviceState.class);
377+
if(request.body().contains("\"bri\""))
378+
stateHasBri = true;
379+
if(request.body().contains("\"on\""))
380+
stateHasOn = true;
372381
} catch (IOException e) {
373382
log.warn("Object mapper barfed on input of body.", e);
374383
responseString = "[{\"error\":{\"type\": 2, \"address\": \"/lights/" + lightId + "\",\"description\": \"Object mapper barfed on input of body.\"}}]";
@@ -384,7 +393,7 @@ public void setupServer() {
384393
state.fillIn();
385394

386395
theHeaders = new Gson().fromJson(device.getHeaders(), NameValue[].class);
387-
responseString = this.formatSuccessHueResponse(state, request.body(), lightId);
396+
responseString = this.formatSuccessHueResponse(state, request.body(), stateHasOn, lightId);
388397

389398
if(device.getDeviceType().toLowerCase().contains("hue") || (device.getMapType() != null && device.getMapType().equalsIgnoreCase("hueDevice")))
390399
{
@@ -422,8 +431,11 @@ else if(!responseString.contains("[{\"error\":"))
422431
return responseString;
423432
}
424433

425-
if(request.body().contains("bri"))
434+
if(stateHasBri)
426435
{
436+
if(state.getBri() > 0 && !state.isOn())
437+
state.setOn(true);
438+
427439
url = device.getDimUrl();
428440

429441
if(url == null || url.length() == 0)
@@ -433,8 +445,9 @@ else if(!responseString.contains("[{\"error\":"))
433445
{
434446
if (state.isOn()) {
435447
url = device.getOnUrl();
436-
state.setBri(255);
437-
} else if (request.body().contains("false")) {
448+
if(state.getBri() <= 0)
449+
state.setBri(255);
450+
} else {
438451
url = device.getOffUrl();
439452
state.setBri(0);
440453
}
@@ -759,83 +772,85 @@ protected String doHttpRequest(String url, String httpVerb, String contentType,
759772
} catch(Exception e) {
760773
log.debug("Error ocurred in handling response entity after successful call, still responding success. "+ e.getMessage(), e);
761774
}
762-
if(theContent == null)
763-
theContent = "";
764775
}
776+
if(theContent == null)
777+
theContent = "";
765778
}
766779
} catch (IOException e) {
767780
log.warn("Error calling out to HA gateway: IOException in log", e);
768781
}
769782
return theContent;
770783
}
771784

772-
private String formatSuccessHueResponse(DeviceState state, String body, String lightId) {
785+
private String formatSuccessHueResponse(DeviceState state, String body, boolean stateHasOn, String lightId) {
773786

774-
String responseString = "[{\"success\":{\"/lights/" + lightId + "/state/on\":";
775-
boolean justState = true;
787+
String responseString = "[";
788+
boolean justState = false;
789+
if(stateHasOn)
790+
{
791+
responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/on\":";
792+
if (state.isOn()) {
793+
responseString = responseString + "true}}";
794+
if(state.getBri() <= 0)
795+
state.setBri(255);
796+
} else {
797+
responseString = responseString + "false}}";
798+
state.setBri(0);
799+
}
800+
justState = true;
801+
}
802+
776803
if(body.contains("bri"))
777804
{
778805
if(justState)
779-
responseString = responseString + "true}}";
780-
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/bri\":" + state.getBri() + "}}";
781-
justState = false;
806+
responseString = responseString + ",";
807+
responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/bri\":" + state.getBri() + "}}";
808+
justState = true;
782809
}
783810

784811
if(body.contains("ct"))
785812
{
786813
if(justState)
787-
responseString = responseString + "true}}";
788-
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/ct\":" + state.getCt() + "}}";
789-
justState = false;
814+
responseString = responseString + ",";
815+
responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/ct\":" + state.getCt() + "}}";
816+
justState = true;
790817
}
791818

792819
if(body.contains("xy"))
793820
{
794821
if(justState)
795-
responseString = responseString + "true}}";
796-
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/xy\":" + state.getXy() + "}}";
797-
justState = false;
822+
responseString = responseString + ",";
823+
responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/xy\":" + state.getXy() + "}}";
824+
justState = true;
798825
}
799826

800827
if(body.contains("hue"))
801828
{
802829
if(justState)
803-
responseString = responseString + "true}}";
804-
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/hue\":" + state.getHue() + "}}";
805-
justState = false;
830+
responseString = responseString + ",";
831+
responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/hue\":" + state.getHue() + "}}";
832+
justState = true;
806833
}
807834

808835
if(body.contains("sat"))
809836
{
810837
if(justState)
811-
responseString = responseString + "true}}";
812-
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/sat\":" + state.getSat() + "}}";
813-
justState = false;
838+
responseString = responseString + ",";
839+
responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/sat\":" + state.getSat() + "}}";
840+
justState = true;
814841
}
815842

816843
if(body.contains("colormode"))
817844
{
818845
if(justState)
819-
responseString = responseString + "true}}";
820-
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/colormode\":" + state.getColormode() + "}}";
821-
justState = false;
822-
}
823-
824-
if(justState)
825-
{
826-
if (state.isOn()) {
827-
responseString = responseString + "true}}";
828-
state.setBri(255);
829-
} else if (body.contains("false")) {
830-
responseString = responseString + "false}}";
831-
state.setBri(0);
832-
}
846+
responseString = responseString + ",";
847+
responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/colormode\":" + state.getColormode() + "}}";
848+
justState = true;
833849
}
834850

835851
responseString = responseString + "]";
836852

837853
return responseString;
838-
839854
}
840855

841856
@Override

0 commit comments

Comments
 (0)