diff --git a/pom.xml b/pom.xml index 93768fa..b756c66 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 3.5.1e + 3.5.1f jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index f48a446..184d248 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -783,10 +783,10 @@ public class HueMulator implements HueErrorStringSet { else setCount = 1; // code for backwards compatibility - if((callItems[i].getType() == null || callItems[i].getType().trim().length() == 0) && (device.getMapType() != null && device.getMapType().trim().length() > 0)) { - if(device.getMapType() != null || device.getMapType().length() > 0) + if((callItems[i].getType() == null || callItems[i].getType().trim().length() == 0)) { + if(device.getMapType() != null && device.getMapType().length() > 0) callItems[i].setType(device.getMapType()); - else if(device.getDeviceType() != null || device.getDeviceType().length() > 0) + else if(device.getDeviceType() != null && device.getDeviceType().length() > 0) callItems[i].setType(device.getDeviceType()); else callItems[i].setType(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex]); diff --git a/src/main/java/com/bwssystems/hass/Attributes.java b/src/main/java/com/bwssystems/hass/Attributes.java new file mode 100644 index 0000000..3848854 --- /dev/null +++ b/src/main/java/com/bwssystems/hass/Attributes.java @@ -0,0 +1,303 @@ +package com.bwssystems.hass; +import java.util.List; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Attributes { + +@SerializedName("Vera Device Id") +@Expose +private Integer veraDeviceId; +@SerializedName("friendly_name") +@Expose +private String friendlyName; +@SerializedName("supported_features") +@Expose +private Integer supportedFeatures; +@SerializedName("attribution") +@Expose +private String attribution; +@SerializedName("entity_picture") +@Expose +private String entityPicture; +@SerializedName("azimuth") +@Expose +private Double azimuth; +@SerializedName("elevation") +@Expose +private Double elevation; +@SerializedName("next_rising") +@Expose +private String nextRising; +@SerializedName("next_setting") +@Expose +private String nextSetting; +@SerializedName("current_power_mwh") +@Expose +private Integer currentPowerMwh; +@SerializedName("auto") +@Expose +private Boolean auto; +@SerializedName("entity_id") +@Expose +private List entityId = null; +@SerializedName("hidden") +@Expose +private Boolean hidden; +@SerializedName("order") +@Expose +private Integer order; + +/** +* +* @return +* The veraDeviceId +*/ +public Integer getVeraDeviceId() { +return veraDeviceId; +} + +/** +* +* @param veraDeviceId +* The Vera Device Id +*/ +public void setVeraDeviceId(Integer veraDeviceId) { +this.veraDeviceId = veraDeviceId; +} + +/** +* +* @return +* The friendlyName +*/ +public String getFriendlyName() { +return friendlyName; +} + +/** +* +* @param friendlyName +* The friendly_name +*/ +public void setFriendlyName(String friendlyName) { +this.friendlyName = friendlyName; +} + +/** +* +* @return +* The supportedFeatures +*/ +public Integer getSupportedFeatures() { +return supportedFeatures; +} + +/** +* +* @param supportedFeatures +* The supported_features +*/ +public void setSupportedFeatures(Integer supportedFeatures) { +this.supportedFeatures = supportedFeatures; +} + +/** +* +* @return +* The attribution +*/ +public String getAttribution() { +return attribution; +} + +/** +* +* @param attribution +* The attribution +*/ +public void setAttribution(String attribution) { +this.attribution = attribution; +} + +/** +* +* @return +* The entityPicture +*/ +public String getEntityPicture() { +return entityPicture; +} + +/** +* +* @param entityPicture +* The entity_picture +*/ +public void setEntityPicture(String entityPicture) { +this.entityPicture = entityPicture; +} + +/** +* +* @return +* The azimuth +*/ +public Double getAzimuth() { +return azimuth; +} + +/** +* +* @param azimuth +* The azimuth +*/ +public void setAzimuth(Double azimuth) { +this.azimuth = azimuth; +} + +/** +* +* @return +* The elevation +*/ +public Double getElevation() { +return elevation; +} + +/** +* +* @param elevation +* The elevation +*/ +public void setElevation(Double elevation) { +this.elevation = elevation; +} + +/** +* +* @return +* The nextRising +*/ +public String getNextRising() { +return nextRising; +} + +/** +* +* @param nextRising +* The next_rising +*/ +public void setNextRising(String nextRising) { +this.nextRising = nextRising; +} + +/** +* +* @return +* The nextSetting +*/ +public String getNextSetting() { +return nextSetting; +} + +/** +* +* @param nextSetting +* The next_setting +*/ +public void setNextSetting(String nextSetting) { +this.nextSetting = nextSetting; +} + +/** +* +* @return +* The currentPowerMwh +*/ +public Integer getCurrentPowerMwh() { +return currentPowerMwh; +} + +/** +* +* @param currentPowerMwh +* The current_power_mwh +*/ +public void setCurrentPowerMwh(Integer currentPowerMwh) { +this.currentPowerMwh = currentPowerMwh; +} + +/** +* +* @return +* The auto +*/ +public Boolean getAuto() { +return auto; +} + +/** +* +* @param auto +* The auto +*/ +public void setAuto(Boolean auto) { +this.auto = auto; +} + +/** +* +* @return +* The entityId +*/ +public List getEntityId() { +return entityId; +} + +/** +* +* @param entityId +* The entity_id +*/ +public void setEntityId(List entityId) { +this.entityId = entityId; +} + +/** +* +* @return +* The hidden +*/ +public Boolean getHidden() { +return hidden; +} + +/** +* +* @param hidden +* The hidden +*/ +public void setHidden(Boolean hidden) { +this.hidden = hidden; +} + +/** +* +* @return +* The order +*/ +public Integer getOrder() { +return order; +} + +/** +* +* @param order +* The order +*/ +public void setOrder(Integer order) { +this.order = order; +} + +} diff --git a/src/main/java/com/bwssystems/hass/Field.java b/src/main/java/com/bwssystems/hass/Field.java new file mode 100644 index 0000000..c39bd3e --- /dev/null +++ b/src/main/java/com/bwssystems/hass/Field.java @@ -0,0 +1,29 @@ + +package com.bwssystems.hass; + +import java.util.Map; + +import com.google.gson.JsonElement; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Field { + + @SerializedName("fields") + @Expose + private Map fields; + + public Field(Map fields) { + super(); + this.fields = fields; + } + + public Map getFields() { + return fields; + } + + public void setFields(Map fields) { + this.fields = fields; + } + +} diff --git a/src/main/java/com/bwssystems/hass/FieldDeserializer.java b/src/main/java/com/bwssystems/hass/FieldDeserializer.java new file mode 100644 index 0000000..b3defe3 --- /dev/null +++ b/src/main/java/com/bwssystems/hass/FieldDeserializer.java @@ -0,0 +1,31 @@ +package com.bwssystems.hass; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +public class FieldDeserializer implements JsonDeserializer { + private Map fields; + @Override + public Field deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) + { + JsonObject obj = json.getAsJsonObject(); + String theKey; + + fields = new HashMap(); + for(Entry entry:obj.entrySet()){ + theKey = entry.getKey(); + JsonElement theRawDetail = obj.get(theKey); + fields.put(theKey, theRawDetail); + } + + return new Field(fields); + } + +} diff --git a/src/main/java/com/bwssystems/hass/FieldElement.java b/src/main/java/com/bwssystems/hass/FieldElement.java new file mode 100644 index 0000000..0d94615 --- /dev/null +++ b/src/main/java/com/bwssystems/hass/FieldElement.java @@ -0,0 +1,52 @@ + +package com.bwssystems.hass; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class FieldElement { + + @SerializedName("description") + @Expose + private String description; + @SerializedName("example") + @Expose + private String example; + + /** + * + * @return + * The description + */ + public String getDescription() { + return description; + } + + /** + * + * @param description + * The description + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * + * @return + * The example + */ + public String getExample() { + return example; + } + + /** + * + * @param example + * The example + */ + public void setExample(String example) { + this.example = example; + } + +} diff --git a/src/main/java/com/bwssystems/hass/Service.java b/src/main/java/com/bwssystems/hass/Service.java new file mode 100644 index 0000000..d8be7d3 --- /dev/null +++ b/src/main/java/com/bwssystems/hass/Service.java @@ -0,0 +1,60 @@ + +package com.bwssystems.hass; + +import java.util.Map; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Service { + + @SerializedName("domain") + @Expose + private String domain; + @SerializedName("services") + @Expose + private Map services; + + public Service(String domain, Map services) { + super(); + this.domain = domain; + this.services = services; + } + + /** + * + * @return + * The domain + */ + public String getDomain() { + return domain; + } + + /** + * + * @param domain + * The domain + */ + public void setDomain(String domain) { + this.domain = domain; + } + + /** + * + * @return + * The services + */ + public Map getServices() { + return services; + } + + /** + * + * @param domain + * The services + */ + public void setServices(Map services) { + this.services = services; + } + +} diff --git a/src/main/java/com/bwssystems/hass/ServiceDeserializer.java b/src/main/java/com/bwssystems/hass/ServiceDeserializer.java new file mode 100644 index 0000000..54613fe --- /dev/null +++ b/src/main/java/com/bwssystems/hass/ServiceDeserializer.java @@ -0,0 +1,36 @@ +package com.bwssystems.hass; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +public class ServiceDeserializer implements JsonDeserializer { + private Map services; + private String domain; + @Override + public Service deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) + { + JsonObject objServices = json.getAsJsonObject(); + String theKey; + domain = objServices.get("domain").getAsString(); + JsonObject obj = objServices.get("services").getAsJsonObject(); + services = new HashMap(); + for(Entry entry:obj.entrySet()){ + ServiceElement theServiceElement = new ServiceElement(); + theKey = entry.getKey(); + JsonObject theRawDetail = obj.getAsJsonObject(theKey); + + theServiceElement.setDescription(theRawDetail.get("description").getAsString()); + theServiceElement.setField(ctx.deserialize(theRawDetail.get("fields"), Field.class)); + services.put(theKey, theServiceElement); + } + return new Service(domain, services); + } + +} diff --git a/src/main/java/com/bwssystems/hass/ServiceElement.java b/src/main/java/com/bwssystems/hass/ServiceElement.java new file mode 100644 index 0000000..a701792 --- /dev/null +++ b/src/main/java/com/bwssystems/hass/ServiceElement.java @@ -0,0 +1,52 @@ + +package com.bwssystems.hass; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class ServiceElement { + + @SerializedName("description") + @Expose + private String description; + @SerializedName("fields") + @Expose + private Field fields; + + /** + * + * @return + * The description + */ + public String getDescription() { + return description; + } + + /** + * + * @param description + * The description + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * + * @return + * The fields + */ + public Field getFields() { + return fields; + } + + /** + * + * @param fields + * The fields + */ + public void setField(Field fields) { + this.fields = fields; + } + +} diff --git a/src/main/java/com/bwssystems/hass/State.java b/src/main/java/com/bwssystems/hass/State.java new file mode 100644 index 0000000..7f8544b --- /dev/null +++ b/src/main/java/com/bwssystems/hass/State.java @@ -0,0 +1,114 @@ +package com.bwssystems.hass; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class State { + +@SerializedName("attributes") +@Expose +private Attributes attributes; +@SerializedName("entity_id") +@Expose +private String entityId; +@SerializedName("last_changed") +@Expose +private String lastChanged; +@SerializedName("last_updated") +@Expose +private String lastUpdated; +@SerializedName("state") +@Expose +private String state; + +/** +* +* @return +* The attributes +*/ +public Attributes getAttributes() { +return attributes; +} + +/** +* +* @param attributes +* The attributes +*/ +public void setAttributes(Attributes attributes) { +this.attributes = attributes; +} + +/** +* +* @return +* The entityId +*/ +public String getEntityId() { +return entityId; +} + +/** +* +* @param entityId +* The entity_id +*/ +public void setEntityId(String entityId) { +this.entityId = entityId; +} + +/** +* +* @return +* The lastChanged +*/ +public String getLastChanged() { +return lastChanged; +} + +/** +* +* @param lastChanged +* The last_changed +*/ +public void setLastChanged(String lastChanged) { +this.lastChanged = lastChanged; +} + +/** +* +* @return +* The lastUpdated +*/ +public String getLastUpdated() { +return lastUpdated; +} + +/** +* +* @param lastUpdated +* The last_updated +*/ +public void setLastUpdated(String lastUpdated) { +this.lastUpdated = lastUpdated; +} + +/** +* +* @return +* The state +*/ +public String getState() { +return state; +} + +/** +* +* @param state +* The state +*/ +public void setState(String state) { +this.state = state; +} + +} \ No newline at end of file diff --git a/src/main/java/com/bwssystems/hass/TestService.java b/src/main/java/com/bwssystems/hass/TestService.java new file mode 100644 index 0000000..635f916 --- /dev/null +++ b/src/main/java/com/bwssystems/hass/TestService.java @@ -0,0 +1,32 @@ +package com.bwssystems.hass; + +import java.util.Map; +import java.util.Map.Entry; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; + +public class TestService { + public final static String TestData = "[{\"domain\": \"homeassistant\", \"services\": {\"reload_core_config\": {\"description\": \"\", \"fields\": {}}, \"restart\": {\"description\": \"\", \"fields\": {}}, \"stop\": {\"description\": \"\", \"fields\": {}}, \"toggle\": {\"description\": \"\", \"fields\": {}}, \"turn_off\": {\"description\": \"\", \"fields\": {}}, \"turn_on\": {\"description\": \"\", \"fields\": {}}}}, {\"domain\": \"lock\", \"services\": {\"lock\": {\"description\": \"Lock all or specified locks\", \"fields\": {\"code\": {\"description\": \"An optional code to lock the lock with\", \"example\": 1234}, \"entity_id\": {\"description\": \"Name of lock to lock\", \"example\": \"lock.front_door\"}}}, \"unlock\": {\"description\": \"Unlock all or specified locks\", \"fields\": {\"code\": {\"description\": \"An optional code to unlock the lock with\", \"example\": 1234}, \"entity_id\": {\"description\": \"Name of lock to unlock\", \"example\": \"lock.front_door\"}}}}}, {\"domain\": \"light\", \"services\": {\"toggle\": {\"description\": \"Toggles a light\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of entities to toggle\", \"example\": \"light.kitchen\"}, \"transition\": {\"description\": \"Duration in seconds it takes to get to next state\", \"example\": 60}}}, \"turn_off\": {\"description\": \"Turn a light off\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of entities to turn off\", \"example\": \"light.kitchen\"}, \"flash\": {\"description\": \"If the light should flash\", \"values\": [\"short\", \"long\"]}, \"transition\": {\"description\": \"Duration in seconds it takes to get to next state\", \"example\": 60}}}, \"turn_on\": {\"description\": \"Turn a light on\", \"fields\": {\"brightness\": {\"description\": \"Number between 0..255 indicating brightness\", \"example\": 120}, \"color_name\": {\"description\": \"A human readable color name\", \"example\": \"red\"}, \"color_temp\": {\"description\": \"Color temperature for the light in mireds (154-500)\", \"example\": \"250\"}, \"effect\": {\"description\": \"Light effect\", \"values\": [\"colorloop\", \"random\"]}, \"entity_id\": {\"description\": \"Name(s) of entities to turn on\", \"example\": \"light.kitchen\"}, \"flash\": {\"description\": \"If the light should flash\", \"values\": [\"short\", \"long\"]}, \"profile\": {\"description\": \"Name of a light profile to use\", \"example\": \"relax\"}, \"rgb_color\": {\"description\": \"Color for the light in RGB-format\", \"example\": \"[255, 100, 100]\"}, \"transition\": {\"description\": \"Duration in seconds it takes to get to next state\", \"example\": 60}, \"white_value\": {\"description\": \"Number between 0..255 indicating level of white\", \"example\": \"250\"}, \"xy_color\": {\"description\": \"Color for the light in XY-format\", \"example\": \"[0.52, 0.43]\"}}}}}, {\"domain\": \"switch\", \"services\": {\"toggle\": {\"description\": \"Toggles a switch state\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of entities to toggle\", \"example\": \"switch.living_room\"}}}, \"turn_off\": {\"description\": \"Turn a switch off\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of entities to turn off\", \"example\": \"switch.living_room\"}}}, \"turn_on\": {\"description\": \"Turn a switch on\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of entities to turn on\", \"example\": \"switch.living_room\"}}}}}, {\"domain\": \"conversation\", \"services\": {\"process\": {\"description\": \"\", \"fields\": {}}}}, {\"domain\": \"climate\", \"services\": {\"set_aux_heat\": {\"description\": \"Turn auxillary heater on/off for climate device\", \"fields\": {\"aux_heat\": {\"description\": \"New value of axillary heater\", \"example\": true}, \"entity_id\": {\"description\": \"Name(s) of entities to change\", \"example\": \"climate.kitchen\"}}}, \"set_away_mode\": {\"description\": \"Turn away mode on/off for climate device\", \"fields\": {\"away_mode\": {\"description\": \"New value of away mode\", \"example\": true}, \"entity_id\": {\"description\": \"Name(s) of entities to change\", \"example\": \"climate.kitchen\"}}}, \"set_fan_mode\": {\"description\": \"Set fan operation for climate device\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of entities to change\", \"example\": \"climate.nest\"}, \"fan\": {\"description\": \"New value of fan mode\", \"example\": \"On Low\"}}}, \"set_humidity\": {\"description\": \"Set target humidity of climate device\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of entities to change\", \"example\": \"climate.kitchen\"}, \"humidity\": {\"description\": \"New target humidity for climate device\", \"example\": 60}}}, \"set_operation_mode\": {\"description\": \"Set operation mode for climate device\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of entities to change\", \"example\": \"climet.nest\"}, \"operation_mode\": {\"description\": \"New value of operation mode\", \"example\": \"Heat\"}}}, \"set_swing_mode\": {\"description\": \"Set swing operation for climate device\", \"fields\": {\"description\": \"New value of swing mode\", \"entity_id\": {\"description\": \"Name(s) of entities to change\", \"example\": \".nest\"}, \"example\": 1, \"swing_mode\": null}}, \"set_temperature\": {\"description\": \"Set target temperature of climate device\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of entities to change\", \"example\": \"climate.kitchen\"}, \"operation_mode\": {\"description\": \"Operation mode to set temperature to. This defaults to current_operation mode if not set, or set incorrectly.\", \"example\": \"Heat\"}, \"target_temp_high\": {\"description\": \"New target high tempereature for hvac\", \"example\": 26}, \"target_temp_low\": {\"description\": \"New target low temperature for hvac\", \"example\": 20}, \"temperature\": {\"description\": \"New target temperature for hvac\", \"example\": 25}}}}}, {\"domain\": \"cover\", \"services\": {\"close_cover\": {\"description\": \"Close all or specified cover\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of cover(s) to close\", \"example\": \"cover.living_room\"}}}, \"close_cover_tilt\": {\"description\": \"Close all or specified cover tilt\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of cover(s) to close tilt\", \"example\": \"cover.living_room\"}}}, \"open_cover\": {\"description\": \"Open all or specified cover\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of cover(s) to open\", \"example\": \"cover.living_room\"}}}, \"open_cover_tilt\": {\"description\": \"Open all or specified cover tilt\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of cover(s) tilt to open\", \"example\": \"cover.living_room\"}}}, \"set_cover_position\": {\"description\": \"Move to specific position all or specified cover\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of cover(s) to set cover position\", \"example\": \"cover.living_room\"}, \"position\": {\"description\": \"Position of the cover (0 to 100)\", \"example\": 30}}}, \"set_cover_tilt_position\": {\"description\": \"Move to specific position all or specified cover tilt\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of cover(s) to set cover tilt position\", \"example\": \"cover.living_room\"}, \"position\": {\"description\": \"Position of the cover (0 to 100)\", \"example\": 30}}}, \"stop_cover\": {\"description\": \"Stop all or specified cover\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of cover(s) to stop\", \"example\": \"cover.living_room\"}}}, \"stop_cover_tilt\": {\"description\": \"Stop all or specified cover\", \"fields\": {\"entity_id\": {\"description\": \"Name(s) of cover(s) to stop\", \"example\": \"cover.living_room\"}}}}}, {\"domain\": \"persistent_notification\", \"services\": {\"create\": {\"description\": \"Show a notification in the frontend\", \"fields\": {\"message\": {\"description\": \"Message body of the notification. [Templates accepted]\", \"example\": \"Please check your configuration.yaml.\"}, \"notification_id\": {\"description\": \"Target ID of the notification, will replace a notification with the same Id. [Optional]\", \"example\": 1234}, \"title\": {\"description\": \"Optional title for your notification. [Optional, Templates accepted]\", \"example\": \"Test notification\"}}}}}, {\"domain\": \"logbook\", \"services\": {\"log\": {\"description\": \"\", \"fields\": {}}}}]"; + public static void main(String[] args){ + Gson aGson; + aGson = new GsonBuilder() + .registerTypeAdapter(Service.class, new ServiceDeserializer()) + .registerTypeHierarchyAdapter(Field.class, new FieldDeserializer()) + .create(); + + Service[] aService = aGson.fromJson(TestData, Service[].class); + for(int i = 0; i < aService.length; i++) { + System.out.println(aService[i].getDomain()); + Map services = aService[i].getServices(); + for(Entry theServiceEntry:services.entrySet()) { + System.out.println(" " + theServiceEntry.getKey()); + Field theField = theServiceEntry.getValue().getFields(); + for(Entry theFieldEntry:theField.getFields().entrySet()) + System.out.println(" " + theFieldEntry.getKey()); + } + } + } + +}