diff --git a/bundles/org.openhab.binding.amazonechocontrol/README.md b/bundles/org.openhab.binding.amazonechocontrol/README.md index 6d1979d13..a2428e620 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/README.md +++ b/bundles/org.openhab.binding.amazonechocontrol/README.md @@ -27,6 +27,7 @@ It provides features to control and view the current state of echo devices: - change the equalizer settings - get information about the next alarm, reminder and timer - send a message to the echo devices +- control alexa smart thermostat It also provides features to control devices connected to your echo: @@ -58,6 +59,7 @@ Some ideas what you can do in your home by using rules and other openHAB control - Change the equalizer settings depending on the bluetooth connection - Turn on a light on your alexa alarm time - Activate or deactivate the Alexa Guard with presence detection +- Adjust thermostat setpoint and mode With the possibility to control your lights you could do: @@ -438,20 +440,25 @@ The only possibility to find out the id is by using the discover function in the The channels of the smarthome devices will be generated at runtime. Check in the UI thing configurations, which channels are created. | Channel Type ID | Item Type | Access Mode | Thing Type | Description -|--------------------------|-----------|-------------|-------------------------------|------------------------------------------------------------------------------------------ -| powerState | Switch | R/W | smartHomeDevice, smartHomeDeviceGroup | Shows and changes the state (ON/OFF) of your device -| brightness | Dimmer | R/W | smartHomeDevice, smartHomeDeviceGroup | Shows and changes the brightness of your lamp -| color | Color | R | smartHomeDevice, smartHomeDeviceGroup | Shows the color of your light -| colorName | String | R/W | smartHomeDevice, smartHomeDeviceGroup | Shows and changes the color name of your light (groups are not able to show their color) -| colorTemperatureName | String | R/W | smartHomeDevice, smartHomeDeviceGroup | White temperatures name of your lights (groups are not able to show their color) -| armState | String | R/W | smartHomeDevice, smartHomeDeviceGroup | State of your alarm guard. Options: ARMED_AWAY, ARMED_STAY, ARMED_NIGHT, DISARMED (groups are not able to show their state) -| burglaryAlarm | Contact | R | smartHomeDevice | Burglary alarm -| carbonMonoxideAlarm | Contact | R | smartHomeDevice | Carbon monoxide detection alarm -| fireAlarm | Contact | R | smartHomeDevice | Fire alarm -| waterAlarm | Contact | R | smartHomeDevice | Water alarm -| glassBreakDetectionState | Contact | R | smartHomeDevice | Glass break detection alarm -| smokeAlarmDetectionState | Contact | R | smartHomeDevice | Smoke detection alarm -| temperature | Number | R | smartHomeDevice | Temperature +|--------------------------|----------------------|-------------|-------------------------------|------------------------------------------------------------------------------------------ +| powerState | Switch | R/W | smartHomeDevice, smartHomeDeviceGroup | Shows and changes the state (ON/OFF) of your device +| brightness | Dimmer | R/W | smartHomeDevice, smartHomeDeviceGroup | Shows and changes the brightness of your lamp +| color | Color | R | smartHomeDevice, smartHomeDeviceGroup | Shows the color of your light +| colorName | String | R/W | smartHomeDevice, smartHomeDeviceGroup | Shows and changes the color name of your light (groups are not able to show their color) +| colorTemperatureName | String | R/W | smartHomeDevice, smartHomeDeviceGroup | White temperatures name of your lights (groups are not able to show their color) +| armState | String | R/W | smartHomeDevice, smartHomeDeviceGroup | State of your alarm guard. Options: ARMED_AWAY, ARMED_STAY, ARMED_NIGHT, DISARMED (groups are not able to show their state) +| burglaryAlarm | Contact | R | smartHomeDevice | Burglary alarm +| carbonMonoxideAlarm | Contact | R | smartHomeDevice | Carbon monoxide detection alarm +| fireAlarm | Contact | R | smartHomeDevice | Fire alarm +| waterAlarm | Contact | R | smartHomeDevice | Water alarm +| glassBreakDetectionState | Contact | R | smartHomeDevice | Glass break detection alarm +| smokeAlarmDetectionState | Contact | R | smartHomeDevice | Smoke detection alarm +| temperature | Number:Temperature | R | smartHomeDevice | Temperature +| targetSetpoint | Number:Temperature | R/W | smartHomeDevice | Thermostat target setpoint +| upperSetpoint | Number:Temperature | R/W | smartHomeDevice | Thermostat upper setpoint (AUTO) +| lowerSetpoint | Number:Temperature | R/W | smartHomeDevice | Thermostat lower setpoint (AUTO) +| relativeHumidity | Number:Dimensionless | R | smartHomeDevice | Thermostat humidity +| thermostatMode | String | R/W | smartHomeDevice | Thermostat operation mode ### Example diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java index ce006aea1..cc2974ca0 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java @@ -145,7 +145,7 @@ public class AccountServlet extends HttpServlet { } Connection connection = this.account.findConnection(); - if (connection != null && uri.equals("/changedomain")) { + if (connection != null && "/changedomain".equals(uri)) { Map map = req.getParameterMap(); String[] domainArray = map.get("domain"); if (domainArray == null) { @@ -199,7 +199,7 @@ public class AccountServlet extends HttpServlet { postDataBuilder.append(name); postDataBuilder.append('='); String value = ""; - if (name.equals("failedSignInCount")) { + if ("failedSignInCount".equals(name)) { value = "ape:AA=="; } else { String[] strings = map.get(name); @@ -277,29 +277,29 @@ public class AccountServlet extends HttpServlet { if (connection != null && connection.verifyLogin()) { // handle commands - if (baseUrl.equals("/logout") || baseUrl.equals("/logout/")) { + if ("/logout".equals(baseUrl) || "/logout/".equals(baseUrl)) { this.connectionToInitialize = reCreateConnection(); this.account.setConnection(null); resp.sendRedirect(this.servletUrl); return; } // handle commands - if (baseUrl.equals("/newdevice") || baseUrl.equals("/newdevice/")) { + if ("/newdevice".equals(baseUrl) || "/newdevice/".equals(baseUrl)) { this.connectionToInitialize = new Connection(null, this.gson); this.account.setConnection(null); resp.sendRedirect(this.servletUrl); return; } - if (baseUrl.equals("/devices") || baseUrl.equals("/devices/")) { + if ("/devices".equals(baseUrl) || "/devices/".equals(baseUrl)) { handleDevices(resp, connection); return; } - if (baseUrl.equals("/changeDomain") || baseUrl.equals("/changeDomain/")) { + if ("/changeDomain".equals(baseUrl) || "/changeDomain/".equals(baseUrl)) { handleChangeDomain(resp, connection); return; } - if (baseUrl.equals("/ids") || baseUrl.equals("/ids/")) { + if ("/ids".equals(baseUrl) || "/ids/".equals(baseUrl)) { String serialNumber = getQueryMap(queryString).get("serialNumber"); Device device = account.findDeviceJson(serialNumber); if (device != null) { @@ -318,7 +318,7 @@ public class AccountServlet extends HttpServlet { this.connectionToInitialize = connection; } - if (!uri.equals("/")) { + if (!"/".equals(uri)) { String newUri = req.getServletPath() + "/"; resp.sendRedirect(newUri); return; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java index 69a671d47..6ec223e70 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java @@ -97,7 +97,7 @@ public class BindingServlet extends HttpServlet { } logger.debug("doGet {}", uri); - if (!uri.equals("/")) { + if (!"/".equals(uri)) { String newUri = req.getServletPath() + "/"; resp.sendRedirect(newUri); return; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index b950df370..e868e24cb 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -12,6 +12,8 @@ */ package org.openhab.binding.amazonechocontrol.internal; +import static org.openhab.binding.amazonechocontrol.internal.smarthome.Constants.*; + import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; @@ -32,10 +34,12 @@ import java.util.Base64; import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.Random; import java.util.Scanner; @@ -109,6 +113,7 @@ import org.openhab.binding.amazonechocontrol.internal.jsons.JsonWebSiteCookie; import org.openhab.binding.amazonechocontrol.internal.jsons.SmartHomeBaseDevice; import org.openhab.core.common.ThreadPoolManager; import org.openhab.core.library.types.QuantityType; +import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.SIUnits; import org.openhab.core.util.HexUtils; import org.slf4j.Logger; @@ -118,6 +123,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; +import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonSyntaxException; @@ -644,7 +650,7 @@ public class Connection { for (Map.Entry<@Nullable String, List> header : headerFields.entrySet()) { String key = header.getKey(); if (key != null && !key.isEmpty()) { - if (key.equalsIgnoreCase("Set-Cookie")) { + if ("Set-Cookie".equalsIgnoreCase(key)) { // store cookie for (String cookieHeader : header.getValue()) { if (!cookieHeader.isEmpty()) { @@ -655,7 +661,7 @@ public class Connection { } } } - if (key.equalsIgnoreCase("Location")) { + if ("Location".equalsIgnoreCase(key)) { // get redirect location location = header.getValue().get(0); if (!location.isEmpty()) { @@ -1074,7 +1080,7 @@ public class Connection { requestObject.add("stateRequests", stateRequests); String requestBody = requestObject.toString(); String json = makeRequestAndReturnString("POST", alexaServer + "/api/phoenix/state", requestBody, true, null); - logger.trace("Requested {} and received {}", requestBody, json); + logger.debug("Requested {} and received {}", requestBody, json); JsonObject responseObject = Objects.requireNonNull(gson.fromJson(json, JsonObject.class)); JsonArray deviceStates = (JsonArray) responseObject.get("deviceStates"); @@ -1164,6 +1170,8 @@ public class Connection { public void smartHomeCommand(String entityId, String action, @Nullable String property, @Nullable Object value) throws IOException, InterruptedException { String url = alexaServer + "/api/phoenix/state"; + Float lowerSetpoint = null; + Float upperSetpoint = null; JsonObject json = new JsonObject(); JsonArray controlRequests = new JsonArray(); @@ -1173,20 +1181,95 @@ public class Connection { JsonObject parameters = new JsonObject(); parameters.addProperty("action", action); if (property != null) { - if (value instanceof QuantityType) { - parameters.addProperty(property + ".value", ((QuantityType) value).floatValue()); - parameters.addProperty(property + ".scale", - ((QuantityType) value).getUnit().equals(SIUnits.CELSIUS) ? "celsius" : "fahrenheit"); - } else if (value instanceof Boolean) { - parameters.addProperty(property, (boolean) value); - } else if (value instanceof String) { - parameters.addProperty(property, (String) value); - } else if (value instanceof Number) { - parameters.addProperty(property, (Number) value); - } else if (value instanceof Character) { - parameters.addProperty(property, (Character) value); - } else if (value instanceof JsonElement) { - parameters.add(property, (JsonElement) value); + if ("setThermostatMode".equals(action)) { + if (value instanceof StringType) { + parameters.addProperty(property + ".value", value.toString()); + } + } else if ("setTargetTemperature".equals(action)) { + if ("targetTemperature".equals(property)) { + if (value instanceof QuantityType) { + parameters.addProperty(property + ".value", ((QuantityType) value).floatValue()); + parameters.addProperty(property + ".scale", + ((QuantityType) value).getUnit().equals(SIUnits.CELSIUS) ? "celsius" : "fahrenheit"); + } + } else { + // Get current upper and lower setpoints to build command syntax + Map devices = null; + try { + List deviceList = getSmarthomeDeviceList().stream() + .filter(device -> entityId.equals(device.findEntityId())).collect(Collectors.toList()); + devices = getSmartHomeDeviceStatesJson(new HashSet<>(deviceList)); + } catch (URISyntaxException e) { + logger.debug("{}", e.toString()); + } + Entry entry = devices.entrySet().iterator().next(); + JsonArray states = entry.getValue(); + for (JsonElement stateElement : states) { + JsonObject stateValue = new JsonObject(); + String stateJson = stateElement.getAsString(); + if (stateJson.startsWith("{") && stateJson.endsWith("}")) { + JsonObject state = Objects.requireNonNull(gson.fromJson(stateJson, JsonObject.class)); + String interfaceName = Objects.requireNonNullElse(state.get("namespace"), JsonNull.INSTANCE) + .getAsString(); + String name = Objects.requireNonNullElse(state.get("name"), JsonNull.INSTANCE) + .getAsString(); + if ("Alexa.ThermostatController".equals(interfaceName)) { + if ("upperSetpoint".equals(name)) { + stateValue = Objects.requireNonNullElse(state.get("value"), JsonNull.INSTANCE) + .getAsJsonObject(); + upperSetpoint = Objects + .requireNonNullElse(stateValue.get("value"), JsonNull.INSTANCE) + .getAsFloat(); + } else if ("lowerSetpoint".equals(name)) { + stateValue = Objects.requireNonNullElse(state.get("value"), JsonNull.INSTANCE) + .getAsJsonObject(); + lowerSetpoint = Objects + .requireNonNullElse(stateValue.get("value"), JsonNull.INSTANCE) + .getAsFloat(); + } + } + } + } + if ("lowerSetTemperature".equals(property)) { + if (value instanceof QuantityType) { + parameters.addProperty("upperSetTemperature.value", upperSetpoint); + parameters.addProperty("upperSetTemperature.scale", + ((QuantityType) value).getUnit().equals(SIUnits.CELSIUS) ? "celsius" + : "fahrenheit"); + parameters.addProperty(property + ".value", ((QuantityType) value).floatValue()); + parameters.addProperty(property + ".scale", + ((QuantityType) value).getUnit().equals(SIUnits.CELSIUS) ? "celsius" + : "fahrenheit"); + } + } else if ("upperSetTemperature".equals(property)) { + if (value instanceof QuantityType) { + parameters.addProperty(property + ".value", ((QuantityType) value).floatValue()); + parameters.addProperty(property + ".scale", + ((QuantityType) value).getUnit().equals(SIUnits.CELSIUS) ? "celsius" + : "fahrenheit"); + parameters.addProperty("lowerSetTemperature.value", lowerSetpoint); + parameters.addProperty("lowerSetTemperature.scale", + ((QuantityType) value).getUnit().equals(SIUnits.CELSIUS) ? "celsius" + : "fahrenheit"); + } + } + } + } else { + if (value instanceof QuantityType) { + parameters.addProperty(property + ".value", ((QuantityType) value).floatValue()); + parameters.addProperty(property + ".scale", + ((QuantityType) value).getUnit().equals(SIUnits.CELSIUS) ? "celsius" : "fahrenheit"); + } else if (value instanceof Boolean) { + parameters.addProperty(property, (boolean) value); + } else if (value instanceof String) { + parameters.addProperty(property, (String) value); + } else if (value instanceof Number) { + parameters.addProperty(property, (Number) value); + } else if (value instanceof Character) { + parameters.addProperty(property, (Character) value); + } else if (value instanceof JsonElement) { + parameters.add(property, (JsonElement) value); + } } } controlRequest.add("parameters", parameters); diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/WebSocketConnection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/WebSocketConnection.java index 399ea52a0..872dc40fd 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/WebSocketConnection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/WebSocketConnection.java @@ -30,6 +30,7 @@ import java.util.concurrent.ThreadLocalRandom; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; @@ -73,10 +74,11 @@ public class WebSocketConnection { IWebSocketCommandHandler webSocketCommandHandler) throws IOException { this.webSocketCommandHandler = webSocketCommandHandler; amazonEchoControlWebSocket = new AmazonEchoControlWebSocket(); - webSocketClient = new WebSocketClient(new SslContextFactory.Client()); + HttpClient httpClient = new HttpClient(new SslContextFactory.Client()); + webSocketClient = new WebSocketClient(httpClient); try { String host; - if (amazonSite.equalsIgnoreCase("amazon.com")) { + if ("amazon.com".equalsIgnoreCase(amazonSite)) { host = "dp-gw-na-js." + amazonSite; } else { host = "dp-gw-na." + amazonSite; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java index 13a2bcecc..073a1061f 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java @@ -139,13 +139,13 @@ public class AmazonEchoDiscovery extends AbstractDiscoveryService { String deviceFamily = device.deviceFamily; if (deviceFamily != null) { ThingTypeUID thingTypeId; - if (deviceFamily.equals("ECHO")) { + if ("ECHO".equals(deviceFamily)) { thingTypeId = THING_TYPE_ECHO; - } else if (deviceFamily.equals("ROOK")) { + } else if ("ROOK".equals(deviceFamily)) { thingTypeId = THING_TYPE_ECHO_SPOT; - } else if (deviceFamily.equals("KNIGHT")) { + } else if ("KNIGHT".equals(deviceFamily)) { thingTypeId = THING_TYPE_ECHO_SHOW; - } else if (deviceFamily.equals("WHA")) { + } else if ("WHA".equals(deviceFamily)) { thingTypeId = THING_TYPE_ECHO_WHA; } else { logger.debug("Unknown thing type '{}'", deviceFamily); diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/SmartHomeDevicesDiscovery.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/SmartHomeDevicesDiscovery.java index 2ac945bc7..2f7c8ef24 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/SmartHomeDevicesDiscovery.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/SmartHomeDevicesDiscovery.java @@ -49,7 +49,7 @@ import org.slf4j.LoggerFactory; @NonNullByDefault public class SmartHomeDevicesDiscovery extends AbstractDiscoveryService { private AccountHandler accountHandler; - private final Logger logger = LoggerFactory.getLogger(SmartHomeDevicesDiscovery.class); + private Logger logger = LoggerFactory.getLogger(SmartHomeDevicesDiscovery.class); private @Nullable ScheduledFuture startScanStateJob; private @Nullable Long activateTimeStamp; @@ -189,6 +189,8 @@ public class SmartHomeDevicesDiscovery extends AbstractDiscoveryService { deviceName = "Alexa Color Controller on " + shd.friendlyName; } else if (interfaces.contains("Alexa.PowerController")) { deviceName = "Alexa Plug on " + shd.friendlyName; + } else if (interfaces.contains("Alexa.ThermostatController")) { + deviceName = "Alexa Smart " + shd.friendlyName; } else { deviceName = "Unknown Device on " + shd.friendlyName; } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java index 110a5b2cc..59952ace8 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java @@ -783,11 +783,11 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler { if (currentNotification != null) { String type = currentNotification.type; if (type != null) { - if (type.equals("Reminder")) { + if ("Reminder".equals(type)) { updateState(CHANNEL_REMIND, StringType.EMPTY); updateRemind = false; } - if (type.equals("Alarm")) { + if ("Alarm".equals(type)) { updateState(CHANNEL_PLAY_ALARM_SOUND, StringType.EMPTY); updateAlarm = false; } @@ -864,10 +864,10 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler { if (musicProviderId != null) { musicProviderId = musicProviderId.toUpperCase(); - if (musicProviderId.equals("AMAZON MUSIC")) { + if ("AMAZON MUSIC".equals(musicProviderId)) { musicProviderId = "AMAZON_MUSIC"; } - if (musicProviderId.equals("CLOUD_PLAYER")) { + if ("CLOUD_PLAYER".equals(musicProviderId)) { musicProviderId = "AMAZON_MUSIC"; } if (musicProviderId.startsWith("TUNEIN")) { @@ -876,7 +876,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler { if (musicProviderId.startsWith("IHEARTRADIO")) { musicProviderId = "I_HEART_RADIO"; } - if (musicProviderId.equals("APPLE") && musicProviderId.contains("MUSIC")) { + if ("APPLE".equals(musicProviderId) && musicProviderId.contains("MUSIC")) { musicProviderId = "APPLE_MUSIC"; } } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/SmartHomeDeviceHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/SmartHomeDeviceHandler.java index 5cfda45db..6eb054499 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/SmartHomeDeviceHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/SmartHomeDeviceHandler.java @@ -347,7 +347,6 @@ public class SmartHomeDeviceHandler extends BaseThingHandler { if (shd.getCapabilities().stream().map(capability -> capability.interfaceName) .anyMatch(SUPPORTED_INTERFACES::contains)) { result.add(shd); - } } else { SmartHomeGroup shg = (SmartHomeGroup) baseDevice; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonSmartHomeDevices.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonSmartHomeDevices.java index fcc53623d..a02ef015c 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonSmartHomeDevices.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonSmartHomeDevices.java @@ -55,6 +55,11 @@ public class JsonSmartHomeDevices { return applianceId; } + @Override + public @Nullable String findEntityId() { + return entityId; + } + @Override public boolean isGroup() { return false; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonSmartHomeGroups.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonSmartHomeGroups.java index 4fa6dbea9..6ed6eada8 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonSmartHomeGroups.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonSmartHomeGroups.java @@ -39,6 +39,19 @@ public class JsonSmartHomeGroups { return value; } + @Override + public @Nullable String findEntityId() { + SmartHomeGroupIdentifier applianceGroupIdentifier = this.applianceGroupIdentifier; + if (applianceGroupIdentifier == null) { + return null; + } + String value = applianceGroupIdentifier.value; + if (value == null) { + return null; + } + return value; + } + @Override public boolean isGroup() { return true; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/SmartHomeBaseDevice.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/SmartHomeBaseDevice.java index 1533a06d6..4a6ed46f8 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/SmartHomeBaseDevice.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/SmartHomeBaseDevice.java @@ -25,5 +25,8 @@ public interface SmartHomeBaseDevice { @Nullable String findId(); + @Nullable + String findEntityId(); + boolean isGroup(); } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/Constants.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/Constants.java index 874495bf2..dacec9f87 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/Constants.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/Constants.java @@ -26,23 +26,38 @@ import org.openhab.core.thing.type.ChannelTypeUID; */ @NonNullByDefault public class Constants { - public static final Map> HANDLER_FACTORY = Map.of( - HandlerPowerController.INTERFACE, HandlerPowerController::new, HandlerBrightnessController.INTERFACE, - HandlerBrightnessController::new, HandlerColorController.INTERFACE, HandlerColorController::new, - HandlerColorTemperatureController.INTERFACE, HandlerColorTemperatureController::new, - HandlerSecurityPanelController.INTERFACE, HandlerSecurityPanelController::new, - HandlerAcousticEventSensor.INTERFACE, HandlerAcousticEventSensor::new, HandlerTemperatureSensor.INTERFACE, - HandlerTemperatureSensor::new, HandlerThermostatController.INTERFACE, HandlerThermostatController::new, - HandlerPercentageController.INTERFACE, HandlerPercentageController::new, - HandlerPowerLevelController.INTERFACE, HandlerPowerLevelController::new); + public static final Map> HANDLER_FACTORY = Map.ofEntries( + Map.entry(HandlerPowerController.INTERFACE, HandlerPowerController::new), + Map.entry(HandlerBrightnessController.INTERFACE, HandlerBrightnessController::new), + Map.entry(HandlerColorController.INTERFACE, HandlerColorController::new), + Map.entry(HandlerColorTemperatureController.INTERFACE, HandlerColorTemperatureController::new), + Map.entry(HandlerSecurityPanelController.INTERFACE, HandlerSecurityPanelController::new), + Map.entry(HandlerAcousticEventSensor.INTERFACE, HandlerAcousticEventSensor::new), + Map.entry(HandlerTemperatureSensor.INTERFACE, HandlerTemperatureSensor::new), + Map.entry(HandlerThermostatController.INTERFACE, HandlerThermostatController::new), + Map.entry(HandlerPercentageController.INTERFACE, HandlerPercentageController::new), + Map.entry(HandlerPowerLevelController.INTERFACE, HandlerPowerLevelController::new), + Map.entry(HandlerHumiditySensor.INTERFACE, HandlerHumiditySensor::new)); public static final Set SUPPORTED_INTERFACES = HANDLER_FACTORY.keySet(); // channel types public static final ChannelTypeUID CHANNEL_TYPE_TEMPERATURE = new ChannelTypeUID( AmazonEchoControlBindingConstants.BINDING_ID, "temperature"); + public static final ChannelTypeUID CHANNEL_TYPE_HUMIDITY = new ChannelTypeUID( + AmazonEchoControlBindingConstants.BINDING_ID, "relativeHumidity"); public static final ChannelTypeUID CHANNEL_TYPE_TARGETSETPOINT = new ChannelTypeUID( AmazonEchoControlBindingConstants.BINDING_ID, "targetSetpoint"); + public static final ChannelTypeUID CHANNEL_TYPE_LOWERSETPOINT = new ChannelTypeUID( + AmazonEchoControlBindingConstants.BINDING_ID, "lowerSetpoint"); + public static final ChannelTypeUID CHANNEL_TYPE_UPPERSETPOINT = new ChannelTypeUID( + AmazonEchoControlBindingConstants.BINDING_ID, "upperSetpoint"); + public static final ChannelTypeUID CHANNEL_TYPE_THERMOSTATMODE = new ChannelTypeUID( + AmazonEchoControlBindingConstants.BINDING_ID, "thermostatMode"); + public static final ChannelTypeUID CHANNEL_TYPE_FAN_OPERATION = new ChannelTypeUID( + AmazonEchoControlBindingConstants.BINDING_ID, "fanOperation"); + public static final ChannelTypeUID CHANNEL_TYPE_COOLER_OPERATION = new ChannelTypeUID( + AmazonEchoControlBindingConstants.BINDING_ID, "coolerOperation"); // List of Item types public static final String ITEM_TYPE_SWITCH = "Switch"; @@ -50,6 +65,7 @@ public class Constants { public static final String ITEM_TYPE_STRING = "String"; public static final String ITEM_TYPE_NUMBER = "Number"; public static final String ITEM_TYPE_NUMBER_TEMPERATURE = "Number:Temperature"; + public static final String ITEM_TYPE_HUMIDITY = "Number:Dimensionless"; public static final String ITEM_TYPE_CONTACT = "Contact"; public static final String ITEM_TYPE_COLOR = "Color"; } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerBase.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerBase.java index e95b0a469..ddbc2b212 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerBase.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerBase.java @@ -33,6 +33,8 @@ import org.openhab.core.thing.type.ChannelTypeUID; import org.openhab.core.types.Command; import org.openhab.core.types.State; import org.openhab.core.types.StateDescription; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.gson.JsonObject; @@ -41,6 +43,9 @@ import com.google.gson.JsonObject; */ @NonNullByDefault public abstract class HandlerBase { + // Logger + private final Logger logger = LoggerFactory.getLogger(HandlerBase.class); + protected SmartHomeDeviceHandler smartHomeDeviceHandler; protected Map channels = new HashMap<>(); @@ -76,6 +81,7 @@ public abstract class HandlerBase { if (properties != null) { List supported = Objects.requireNonNullElse(properties.supported, List.of()); + logger.trace("{} | {}", capability.toString(), supported.toString()); for (Property property : supported) { String name = property.name; if (name != null) { diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerHumiditySensor.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerHumiditySensor.java new file mode 100644 index 000000000..6576b550f --- /dev/null +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerHumiditySensor.java @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2010-2022 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.amazonechocontrol.internal.smarthome; + +import static org.openhab.binding.amazonechocontrol.internal.smarthome.Constants.*; +import static org.openhab.core.library.unit.Units.*; + +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +import javax.measure.Unit; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.amazonechocontrol.internal.Connection; +import org.openhab.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; +import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeCapabilities.SmartHomeCapability; +import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.SmartHomeDevice; +import org.openhab.core.library.types.QuantityType; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; +import org.openhab.core.types.StateDescription; +import org.openhab.core.types.UnDefType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonObject; + +/** + * The {@link HandlerHumiditySensor} is responsible for the Alexa.HumiditySensorInterface + * + * @author Daniel Campbell - Initial contribution + */ +@NonNullByDefault +public class HandlerHumiditySensor extends HandlerBase { + // Logger + private final Logger logger = LoggerFactory.getLogger(HandlerHumiditySensor.class); + // Interface + public static final String INTERFACE = "Alexa.HumiditySensor"; + // Channel definitions + private static final ChannelInfo HUMIDITY = new ChannelInfo("relativeHumidity" /* propertyName */ , + "relativeHumidity" /* ChannelId */, CHANNEL_TYPE_HUMIDITY /* Channel Type */ , + ITEM_TYPE_HUMIDITY /* Item Type */); + + public HandlerHumiditySensor(SmartHomeDeviceHandler smartHomeDeviceHandler) { + super(smartHomeDeviceHandler); + } + + @Override + public String[] getSupportedInterface() { + return new String[] { INTERFACE }; + } + + @Override + protected ChannelInfo @Nullable [] findChannelInfos(SmartHomeCapability capability, String property) { + if (HUMIDITY.propertyName.equals(property)) { + return new ChannelInfo[] { HUMIDITY }; + } + return null; + } + + @Override + public void updateChannels(String interfaceName, List stateList, UpdateChannelResult result) { + for (JsonObject state : stateList) { + State humidityValue = null; + logger.debug("Updating {} with state: {}", interfaceName, state.toString()); + if (HUMIDITY.propertyName.equals(state.get("name").getAsString())) { + // For groups take the first + humidityValue = getQuantityTypeState(state.get("value").getAsInt(), PERCENT); + updateState(HUMIDITY.channelId, humidityValue == null ? UnDefType.UNDEF : humidityValue); + } + } + } + + protected State getQuantityTypeState(@Nullable Number value, Unit unit) { + return (value == null) ? UnDefType.UNDEF : new QuantityType<>(value, unit); + } + + @Override + public boolean handleCommand(Connection connection, SmartHomeDevice shd, String entityId, + List capabilities, String channelId, Command command) throws IOException { + return false; + } + + @Override + public @Nullable StateDescription findStateDescription(String channelId, StateDescription originalStateDescription, + @Nullable Locale locale) { + return null; + } +} diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerTemperatureSensor.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerTemperatureSensor.java index 3f8707190..a24c7115d 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerTemperatureSensor.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerTemperatureSensor.java @@ -32,17 +32,21 @@ import org.openhab.core.library.unit.SIUnits; import org.openhab.core.types.Command; import org.openhab.core.types.StateDescription; import org.openhab.core.types.UnDefType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.gson.JsonObject; /** - * The {@link HandlerTemperatureSensor} is responsible for the Alexa.PowerControllerInterface + * The {@link HandlerTemperatureSensor} is responsible for the Alexa.TemperatureSensorInterface * * @author Lukas Knoeller - Initial contribution * @author Michael Geramb - Initial contribution */ @NonNullByDefault public class HandlerTemperatureSensor extends HandlerBase { + // Logger + private final Logger logger = LoggerFactory.getLogger(HandlerTemperatureSensor.class); // Interface public static final String INTERFACE = "Alexa.TemperatureSensor"; // Channel definitions @@ -71,6 +75,7 @@ public class HandlerTemperatureSensor extends HandlerBase { public void updateChannels(String interfaceName, List stateList, UpdateChannelResult result) { QuantityType temperatureValue = null; for (JsonObject state : stateList) { + logger.debug("Updating {} with state: {}", interfaceName, state.toString()); if (TEMPERATURE.propertyName.equals(state.get("name").getAsString())) { JsonObject value = state.get("value").getAsJsonObject(); // For groups take the first diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerThermostatController.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerThermostatController.java index 44fba494b..033d7c07a 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerThermostatController.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerThermostatController.java @@ -27,11 +27,14 @@ import org.openhab.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHan import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeCapabilities.SmartHomeCapability; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.SmartHomeDevice; import org.openhab.core.library.types.QuantityType; +import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.ImperialUnits; import org.openhab.core.library.unit.SIUnits; import org.openhab.core.types.Command; import org.openhab.core.types.StateDescription; import org.openhab.core.types.UnDefType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.gson.JsonObject; @@ -42,12 +45,23 @@ import com.google.gson.JsonObject; */ @NonNullByDefault public class HandlerThermostatController extends HandlerBase { + // Logger + private final Logger logger = LoggerFactory.getLogger(HandlerThermostatController.class); // Interface public static final String INTERFACE = "Alexa.ThermostatController"; // Channel definitions private static final ChannelInfo TARGET_SETPOINT = new ChannelInfo("targetSetpoint" /* propertyName */ , "targetSetpoint" /* ChannelId */, CHANNEL_TYPE_TARGETSETPOINT /* Channel Type */ , ITEM_TYPE_NUMBER_TEMPERATURE /* Item Type */); + private static final ChannelInfo LOWER_SETPOINT = new ChannelInfo("lowerSetpoint" /* propertyName */ , + "lowerSetpoint" /* ChannelId */, CHANNEL_TYPE_LOWERSETPOINT /* Channel Type */ , + ITEM_TYPE_NUMBER_TEMPERATURE /* Item Type */); + private static final ChannelInfo UPPER_SETPOINT = new ChannelInfo("upperSetpoint" /* propertyName */ , + "upperSetpoint" /* ChannelId */, CHANNEL_TYPE_UPPERSETPOINT /* Channel Type */ , + ITEM_TYPE_NUMBER_TEMPERATURE /* Item Type */); + private static final ChannelInfo THERMOSTAT_MODE = new ChannelInfo("thermostatMode" /* propertyName */ , + "thermostatMode" /* ChannelId */, CHANNEL_TYPE_THERMOSTATMODE /* Channel Type */ , + ITEM_TYPE_STRING /* Item Type */); public HandlerThermostatController(SmartHomeDeviceHandler smartHomeDeviceHandler) { super(smartHomeDeviceHandler); @@ -63,17 +77,27 @@ public class HandlerThermostatController extends HandlerBase { if (TARGET_SETPOINT.propertyName.equals(property)) { return new ChannelInfo[] { TARGET_SETPOINT }; } + if (LOWER_SETPOINT.propertyName.equals(property)) { + return new ChannelInfo[] { LOWER_SETPOINT }; + } + if (UPPER_SETPOINT.propertyName.equals(property)) { + return new ChannelInfo[] { UPPER_SETPOINT }; + } + if (THERMOSTAT_MODE.propertyName.equals(property)) { + return new ChannelInfo[] { THERMOSTAT_MODE }; + } return null; } @Override public void updateChannels(String interfaceName, List stateList, UpdateChannelResult result) { - QuantityType temperatureValue = null; for (JsonObject state : stateList) { + QuantityType temperatureValue = null; + logger.debug("Updating {} with state: {}", interfaceName, state.toString()); if (TARGET_SETPOINT.propertyName.equals(state.get("name").getAsString())) { - JsonObject value = state.get("value").getAsJsonObject(); // For groups take the first if (temperatureValue == null) { + JsonObject value = state.get("value").getAsJsonObject(); float temperature = value.get("value").getAsFloat(); String scale = value.get("scale").getAsString().toUpperCase(); if ("CELSIUS".equals(scale)) { @@ -82,9 +106,43 @@ public class HandlerThermostatController extends HandlerBase { temperatureValue = new QuantityType(temperature, ImperialUnits.FAHRENHEIT); } } + updateState(TARGET_SETPOINT.channelId, temperatureValue == null ? UnDefType.UNDEF : temperatureValue); + } + if (THERMOSTAT_MODE.propertyName.equals(state.get("name").getAsString())) { + // For groups take the first + String operation = state.get("value").getAsString().toUpperCase(); + StringType operationValue = new StringType(operation); + updateState(THERMOSTAT_MODE.channelId, operationValue); + } + if (UPPER_SETPOINT.propertyName.equals(state.get("name").getAsString())) { + // For groups take the first + if (temperatureValue == null) { + JsonObject value = state.get("value").getAsJsonObject(); + float temperature = value.get("value").getAsFloat(); + String scale = value.get("scale").getAsString().toUpperCase(); + if ("CELSIUS".equals(scale)) { + temperatureValue = new QuantityType(temperature, SIUnits.CELSIUS); + } else { + temperatureValue = new QuantityType(temperature, ImperialUnits.FAHRENHEIT); + } + } + updateState(UPPER_SETPOINT.channelId, temperatureValue == null ? UnDefType.UNDEF : temperatureValue); + } + if (LOWER_SETPOINT.propertyName.equals(state.get("name").getAsString())) { + // For groups take the first + if (temperatureValue == null) { + JsonObject value = state.get("value").getAsJsonObject(); + float temperature = value.get("value").getAsFloat(); + String scale = value.get("scale").getAsString().toUpperCase(); + if ("CELSIUS".equals(scale)) { + temperatureValue = new QuantityType(temperature, SIUnits.CELSIUS); + } else { + temperatureValue = new QuantityType(temperature, ImperialUnits.FAHRENHEIT); + } + } + updateState(LOWER_SETPOINT.channelId, temperatureValue == null ? UnDefType.UNDEF : temperatureValue); } } - updateState(TARGET_SETPOINT.channelId, temperatureValue == null ? UnDefType.UNDEF : temperatureValue); } @Override @@ -99,6 +157,30 @@ public class HandlerThermostatController extends HandlerBase { } } } + if (channelId.equals(LOWER_SETPOINT.channelId)) { + if (containsCapabilityProperty(capabilities, LOWER_SETPOINT.propertyName)) { + if (command instanceof QuantityType) { + connection.smartHomeCommand(entityId, "setTargetTemperature", "lowerSetTemperature", command); + return true; + } + } + } + if (channelId.equals(UPPER_SETPOINT.channelId)) { + if (containsCapabilityProperty(capabilities, UPPER_SETPOINT.propertyName)) { + if (command instanceof QuantityType) { + connection.smartHomeCommand(entityId, "setTargetTemperature", "upperSetTemperature", command); + return true; + } + } + } + if (channelId.equals(THERMOSTAT_MODE.channelId)) { + if (containsCapabilityProperty(capabilities, THERMOSTAT_MODE.propertyName)) { + if (command instanceof StringType) { + connection.smartHomeCommand(entityId, "setThermostatMode", "thermostatMode", command); + return true; + } + } + } return false; } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/OH-INF/i18n/amazonechocontrol.properties b/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/OH-INF/i18n/amazonechocontrol.properties index 1875688d7..dba47615f 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/OH-INF/i18n/amazonechocontrol.properties +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/OH-INF/i18n/amazonechocontrol.properties @@ -101,6 +101,8 @@ channel-type.amazonechocontrol.lastVoiceCommand.label = Last Voice Command channel-type.amazonechocontrol.lastVoiceCommand.description = Last voice command spoken to the device. Writing to the channel starts voice output. channel-type.amazonechocontrol.loop.label = Loop channel-type.amazonechocontrol.loop.description = Loop +channel-type.amazonechocontrol.lowerSetpoint.label = Lower Setpoint +channel-type.amazonechocontrol.lowerSetpoint.description = Lower Setpoint channel-type.amazonechocontrol.mediaLength.label = Media Length channel-type.amazonechocontrol.mediaLength.description = Media length channel-type.amazonechocontrol.mediaProgress.label = Media Progress @@ -139,6 +141,8 @@ channel-type.amazonechocontrol.radio.label = TuneIn Radio channel-type.amazonechocontrol.radio.description = Radio turned on channel-type.amazonechocontrol.radioStationId.label = TuneIn Radio Station Id channel-type.amazonechocontrol.radioStationId.description = Id of the radio station +channel-type.amazonechocontrol.relativeHumidity.label = Humidity +channel-type.amazonechocontrol.relativeHumidity.description = Relative humidity measured by the thermostat. channel-type.amazonechocontrol.remind.label = Remind channel-type.amazonechocontrol.remind.description = Speak the reminder and send a notification to the Alexa app channel-type.amazonechocontrol.save.label = Save @@ -173,8 +177,12 @@ channel-type.amazonechocontrol.textToSpeech.label = Speak channel-type.amazonechocontrol.textToSpeech.description = Speak the text (Write only). It is possible to use plain text or SSML: I want to tell you a secret.I am not a real human..Can you believe it? channel-type.amazonechocontrol.textToSpeechVolume.label = Speak Volume channel-type.amazonechocontrol.textToSpeechVolume.description = Volume of the Speak channel. If 0, the current volume will be used. +channel-type.amazonechocontrol.thermostatMode.label = Thermostat Mode +channel-type.amazonechocontrol.thermostatMode.description = Thermostat Mode channel-type.amazonechocontrol.title.label = Title channel-type.amazonechocontrol.title.description = Title +channel-type.amazonechocontrol.upperSetpoint.label = Upper Setpoint +channel-type.amazonechocontrol.upperSetpoint.description = Upper Setpoint channel-type.amazonechocontrol.volume.label = Volume channel-type.amazonechocontrol.volume.description = Volume of the sound channel-type.amazonechocontrol.waterAlarm.label = Water Alarm diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/OH-INF/thing/thing-types.xml index 20601205a..8e3a374ca 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/OH-INF/thing/thing-types.xml @@ -634,6 +634,18 @@ Temperature + + + Number:Dimensionless + + Relative humidity measured by the thermostat. + Humidity + + Measurement + Temperature + + + Number:Temperature @@ -641,4 +653,32 @@ Target Setpoint + + Number:Temperature + + Upper Setpoint + Temperature + + Setpoint + Temperature + + + + + Number:Temperature + + Lower Setpoint + Temperature + + Setpoint + Temperature + + + + + String + + Thermostat Mode + +