package com.bwssystems.HABridge.plugins.hue; import java.io.IOException; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.bwssystems.HABridge.NamedIP; import com.bwssystems.HABridge.api.SuccessUserResponse; import com.bwssystems.HABridge.api.UserCreateRequest; import com.bwssystems.HABridge.api.hue.DeviceResponse; import com.bwssystems.HABridge.api.hue.HueApiResponse; import com.bwssystems.HABridge.dao.DeviceDescriptor; import com.bwssystems.HABridge.plugins.http.HTTPHandler; import com.google.gson.Gson; public class HueInfo { private static final Logger log = LoggerFactory.getLogger(HueInfo.class); private HTTPHandler httpClient; private NamedIP hueAddress; public static final String HUE_REQUEST = "/api"; public HueInfo(NamedIP addressName) { super(); httpClient = new HTTPHandler(); hueAddress = addressName; } public HueApiResponse getHueApiResponse() { log.debug("Get hue info to hue " + hueAddress.getName()); HueApiResponse theHueApiResponse = null; if(hueAddress.getUsername() == null) { registerWithHue(); if(hueAddress.getUsername() == null) { log.warn("Could not register with hue: " + hueAddress.getName()); } } String theUrl = "http://" + hueAddress.getIp() + HUE_REQUEST + "/" + hueAddress.getUsername(); String theData; boolean loopControl = true; int retryCount = 0; while(loopControl) { if(retryCount > 3) { log.warn("Max Retry reached to get Hue data from " + hueAddress.getName()); loopControl = false; break; } else if (retryCount > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { // ignore } } theUrl = "http://" + hueAddress.getIp() + HueUtil.HUE_REQUEST + "/" + hueAddress.getUsername(); theData = httpClient.doHttpRequest(theUrl, null, null, null, null); if(theData != null) { log.debug("GET HueApiResponse - data: " + theData); if(theData.contains("[{\"error\":")) { if(theData.contains("unauthorized user")) { registerWithHue(); if(hueAddress.getUsername() == null) { log.warn("Retry Register to Hue for " + hueAddress.getName() + " returned error: " + theData); } retryCount++; } else { log.warn("GET HueApiResponse for " + hueAddress.getName() + " - returned error: " + theData); return null; } } else { theHueApiResponse = new Gson().fromJson(theData, HueApiResponse.class); log.debug("GET HueApiResponse for " + hueAddress.getName() + " - Gson parse - name: " + theHueApiResponse.getConfig().getName() + ", mac addr: " + theHueApiResponse.getConfig().getMac()); loopControl = false; } } else { log.warn("GET HueApiResponse for " + hueAddress.getName() + " - returned null, no data."); loopControl = false; } } return theHueApiResponse; } public String registerWithHue() { UserCreateRequest theLogin = new UserCreateRequest(); theLogin.setDevicetype("HABridge#MyMachine"); HttpPost postRequest = new HttpPost("http://" + hueAddress.getIp() + HUE_REQUEST); ContentType parsedContentType = ContentType.parse("application/json"); StringEntity requestBody = new StringEntity(new Gson().toJson(theLogin), parsedContentType); HttpResponse response = null; postRequest.setEntity(requestBody); HttpClient anHttpClient = httpClient.getHttpClient(); try { response = anHttpClient.execute(postRequest); log.debug("registerWithHue - POST execute on " + hueAddress.getName() + "URL responded: " + response.getStatusLine().getStatusCode()); if(response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300){ String theBody = EntityUtils.toString(response.getEntity()); log.debug("registerWithHue response data: " + theBody); if(theBody.contains("[{\"error\":")) { if(theBody.contains("link button not")) { log.warn("registerWithHue needs link button pressed on HUE bridge: " + hueAddress.getName()); } else log.warn("registerWithHue returned an unexpected error: " + theBody); } else { SuccessUserResponse[] theResponses = new Gson().fromJson(theBody, SuccessUserResponse[].class); //read content for data, SuccessUserResponse[].class); hueAddress.setUsername(theResponses[0].getSuccess().getUsername()); } } EntityUtils.consume(response.getEntity()); //close out inputstream ignore content } catch (IOException e) { log.warn("Error logging into HUE: IOException in log", e); } return hueAddress.getUsername(); } public DeviceResponse getHueDeviceInfo(String hueDeviceId, DeviceDescriptor device) { log.debug("Get hue device info to "+ hueAddress.getName() + " passthru id " + hueDeviceId); String responseString = null; DeviceResponse deviceResponse = null; if(hueAddress.getUsername() == null) registerWithHue(); if (hueAddress.getUsername() != null) { // make call responseString = httpClient.doHttpRequest( "http://" + hueAddress.getIp() + "/api/" + hueAddress.getUsername() + "/lights/" + hueDeviceId, HttpGet.METHOD_NAME, "application/json", null, null); if (responseString == null) { log.warn("Error on calling hue device to get state: " + device.getName()); deviceResponse = DeviceResponse.createResponse(device); } else if (responseString.contains("[{\"error\":") && responseString.contains("unauthorized user")) { log.warn("Error on calling hue device to get state: " + device.getName() + " with errors: " + responseString); deviceResponse = DeviceResponse.createResponse(device); } else { deviceResponse = new Gson().fromJson(responseString, DeviceResponse.class); if (deviceResponse != null) deviceResponse.setName(device.getName()); } } else { log.warn("Error on calling hue device to get state: " + device.getName() + " Could not register with hue: " + hueAddress.getName()); deviceResponse = DeviceResponse.createResponse(device); } return deviceResponse; } public String changeState(HueDeviceIdentifier deviceId, String lightId, String body) { log.debug("Changing state for ha-bridge id " + lightId + " to " + deviceId.getHueName() + " passthru id " + deviceId.getDeviceId() + " with state " + body ); String responseString = null; if(hueAddress.getUsername() == null) registerWithHue(); if (hueAddress.getUsername() != null) { responseString = httpClient.doHttpRequest( "http://" + deviceId.getIpAddress() + "/api/" + hueAddress.getUsername() + "/lights/" + deviceId.getDeviceId() + "/state", HttpPut.METHOD_NAME, "application/json", body, null); if (responseString == null) { log.warn("Error on calling Hue passthru to change device state: " + deviceId.getHueName()); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Error on calling HUE to change device state\", \"parameter\": \"/lights/" + lightId + "state\"}}]"; } else if (responseString.contains("[{\"error\":")) { if(responseString.contains("unauthorized user")) { } log.warn("Error occurred when calling Hue Passthru: " + responseString); } } else { log.warn("Error on calling hue device to change state: " + deviceId.getHueName() + " Could not register with hue: " + hueAddress.getName()); } return responseString; } public void closeHue() { httpClient.closeHandler(); httpClient = null; } public NamedIP getHueAddress() { return hueAddress; } public void setHueAddress(NamedIP hueAddress) { this.hueAddress = hueAddress; } }