diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/pom.xml b/bundles/org.smarthomej.binding.amazonechocontrol/pom.xml index ab2c9bea47..eb739c8010 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/pom.xml +++ b/bundles/org.smarthomej.binding.amazonechocontrol/pom.xml @@ -27,6 +27,12 @@ 1.1.6.RELEASE compile + + org.eclipse.jdt + org.eclipse.jdt.annotation + 2.2.600 + compile + diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AccountServlet.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AccountServlet.java index 1cf58e67e1..7069573f86 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AccountServlet.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AccountServlet.java @@ -13,7 +13,10 @@ */ package org.smarthomej.binding.amazonechocontrol.internal; +import static org.eclipse.jetty.util.StringUtil.isNotBlank; import static org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.*; +import static org.smarthomej.binding.amazonechocontrol.internal.util.Util.findInList; +import static org.unbescape.html.HtmlEscape.escapeHtml4; import java.io.IOException; import java.net.URI; @@ -22,7 +25,6 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -44,17 +46,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonBluetoothStates; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonBluetoothStates.BluetoothState; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonBluetoothStates.PairedDevice; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonMusicProvider; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNotificationSound; +import org.smarthomej.binding.amazonechocontrol.internal.connection.LoginData; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlaylists; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlaylists.PlayList; +import org.smarthomej.binding.amazonechocontrol.internal.dto.NotificationSoundTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.BluetoothStateTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.MusicProviderTO; import org.smarthomej.binding.amazonechocontrol.internal.handler.AccountHandler; import org.smarthomej.binding.amazonechocontrol.internal.util.HttpRequestBuilder; -import org.unbescape.html.HtmlEscape; import com.google.gson.Gson; import com.google.gson.JsonObject; @@ -95,7 +95,7 @@ public AccountServlet(HttpService httpService, String id, AccountHandler account this.gson = gson; try { - servletUrl = "/amazonechocontrol/" + URLEncoder.encode(id, StandardCharsets.UTF_8); + servletUrl = "/" + BINDING_ID + "/" + URLEncoder.encode(id, StandardCharsets.UTF_8); httpService.registerServlet(servletUrl, this, null, httpService.createDefaultHttpContext()); } catch (NamespaceException | ServletException e) { throw new IllegalStateException(e.getMessage()); @@ -107,34 +107,29 @@ public void dispose() { } @Override - protected void doPut(@Nullable HttpServletRequest req, @Nullable HttpServletResponse resp) - throws ServletException, IOException { + protected void doPut(@NonNullByDefault({}) HttpServletRequest req, @NonNullByDefault({}) HttpServletResponse resp) + throws IOException { doVerb("PUT", req, resp); } @Override - protected void doDelete(@Nullable HttpServletRequest req, @Nullable HttpServletResponse resp) - throws ServletException, IOException { + protected void doDelete(@NonNullByDefault({}) HttpServletRequest req, + @NonNullByDefault({}) HttpServletResponse resp) throws IOException { doVerb("DELETE", req, resp); } @Override - protected void doPost(@Nullable HttpServletRequest req, @Nullable HttpServletResponse resp) - throws ServletException, IOException { + protected void doPost(@NonNullByDefault({}) HttpServletRequest req, @NonNullByDefault({}) HttpServletResponse resp) + throws IOException { doVerb("POST", req, resp); } - void doVerb(String verb, @Nullable HttpServletRequest req, @Nullable HttpServletResponse resp) throws IOException { - if (req == null) { - return; - } - if (resp == null) { - return; - } + private void doVerb(String verb, HttpServletRequest req, HttpServletResponse resp) throws IOException { String requestUri = req.getRequestURI(); if (requestUri == null) { return; } + String uri = requestUri.substring(servletUrl.length()); String queryString = req.getQueryString(); if (queryString != null && !queryString.isEmpty()) { @@ -151,7 +146,6 @@ void doVerb(String verb, @Nullable HttpServletRequest req, @Nullable HttpServlet } String domain = domainArray[0]; String loginData = connection.getLoginData().serializeLoginData(); - logger.error("4"); Connection newConnection = accountHandler.createConnection(null, true); if (newConnection.tryRestoreLogin(loginData, domain)) { accountHandler.setConnection(newConnection); @@ -174,7 +168,7 @@ void doVerb(String verb, @Nullable HttpServletRequest req, @Nullable HttpServlet postData = gson.fromJson(req.getReader(), JsonObject.class); } - this.handleProxyRequest(connection, resp, verb, getUrl, null, postData, true, connection.getAmazonSite()); + this.handleProxyRequest(connection, resp, verb, getUrl, null, postData, connection.getAmazonSite()); return; } @@ -185,7 +179,7 @@ void doVerb(String verb, @Nullable HttpServletRequest req, @Nullable HttpServlet return; } - resp.addHeader("content-type", "text/html;charset=UTF-8"); + resp.addHeader(HttpHeader.CONTENT_TYPE.asString(), MimeTypes.Type.TEXT_HTML_UTF_8.asString()); Map map = req.getParameterMap(); StringBuilder postDataBuilder = new StringBuilder(); @@ -201,7 +195,7 @@ void doVerb(String verb, @Nullable HttpServletRequest req, @Nullable HttpServlet value = "ape:AA=="; } else { String[] strings = map.get(name); - if (strings != null && strings.length > 0 && strings[0] != null) { + if (strings != null && strings.length > 0) { value = strings[0]; } } @@ -226,17 +220,12 @@ void doVerb(String verb, @Nullable HttpServletRequest req, @Nullable HttpServlet } String referer = "https://www." + site; String postData = postDataBuilder.toString(); - handleProxyRequest(connection, resp, "POST", postUrl, referer, postData, false, site); + handleProxyRequest(connection, resp, "POST", postUrl, referer, postData, site); } @Override - protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResponse resp) throws IOException { - if (req == null) { - return; - } - if (resp == null) { - return; - } + protected void doGet(@NonNullByDefault({}) HttpServletRequest req, @NonNullByDefault({}) HttpServletResponse resp) + throws IOException { String requestUri = req.getRequestURI(); if (requestUri == null) { return; @@ -254,7 +243,7 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp String getUrl = "https://www." + connection.getAmazonSite() + "/" + uri.substring(FORWARD_URI_PART.length()); - this.handleProxyRequest(connection, resp, "GET", getUrl, null, null, false, connection.getAmazonSite()); + this.handleProxyRequest(connection, resp, "GET", getUrl, null, null, connection.getAmazonSite()); return; } @@ -269,14 +258,13 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp String getUrl = "https://alexa." + connection.getAmazonSite() + "/" + uri.substring(PROXY_URI_PART.length()); - this.handleProxyRequest(connection, resp, "GET", getUrl, null, null, false, connection.getAmazonSite()); + this.handleProxyRequest(connection, resp, "GET", getUrl, null, null, connection.getAmazonSite()); return; } if (connection != null && connection.verifyLogin()) { // handle commands if ("/logout".equals(baseUrl) || "/logout/".equals(baseUrl)) { - logger.error("3"); this.connectionToInitialize = accountHandler.createConnection(connectionToInitialize, false); this.accountHandler.unsetConnection(); resp.sendRedirect(this.servletUrl); @@ -284,7 +272,6 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp } // handle commands if ("/newdevice".equals(baseUrl) || "/newdevice/".equals(baseUrl)) { - logger.error("2"); this.connectionToInitialize = accountHandler.createConnection(null, true); this.accountHandler.unsetConnection(); resp.sendRedirect(this.servletUrl); @@ -295,13 +282,18 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp handleDevices(resp, connection); return; } - if ("/changeDomain".equals(baseUrl) || "/changeDomain/".equals(baseUrl)) { - handleChangeDomain(resp, connection); - return; - } + /* + * This part of the code is disabled because it seems to be unused. It is left in place if it turns out + * to be needed later. + * if ("/changeDomain".equals(baseUrl) || "/changeDomain/".equals(baseUrl)) { + * handleChangeDomain(resp, connection); + * return; + * } + */ + if ("/ids".equals(baseUrl) || "/ids/".equals(baseUrl)) { String serialNumber = getQueryMap(queryString).get("serialNumber"); - Device device = accountHandler.findDeviceJson(serialNumber); + DeviceTO device = accountHandler.findDeviceJson(serialNumber); if (device != null) { Thing thing = accountHandler.findThingBySerialNumber(device.serialNumber); handleIds(resp, connection, device, thing); @@ -314,7 +306,6 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp } connection = this.connectionToInitialize; if (connection == null) { - logger.error("1"); connection = accountHandler.createConnection(null, false); this.connectionToInitialize = connection; } @@ -348,74 +339,72 @@ private Map getQueryMap(@Nullable String query) { return map; } - private void handleChangeDomain(HttpServletResponse resp, Connection connection) { - StringBuilder html = createPageStart("Change Domain"); - html.append("
\nDomain:\n\n
\n\n
"); - - createPageEndAndSent(resp, html); - } + /* + * This part of the code is disabled because it seems to be unused. It is left in place if it turns out to be needed + * later. + * private void handleChangeDomain(HttpServletResponse resp, Connection connection) { + * StringBuilder html = createPageStart("Change Domain"); + * html.append("
\nDomain:\n\n
\n\n
"); + * + * createPageEndAndSent(resp, html); + * } + */ private void handleDefaultPageResult(HttpServletResponse resp, String message, Connection connection) { + LoginData loginData = connection.getLoginData(); StringBuilder html = createPageStart(""); - html.append(HtmlEscape.escapeHtml4(message)); + html.append(escapeHtml4(message)); // logout link - html.append(" ").append(HtmlEscape.escapeHtml4("Logout")); + html.append(" ").append(escapeHtml4("Logout")); html.append(""); // newdevice link html.append(" | ") - .append(HtmlEscape.escapeHtml4("Logout and create new device id")); + .append(escapeHtml4("Logout and create new device id")); html.append(""); // customer id - html.append("
Customer Id: ").append(HtmlEscape.escapeHtml4(connection.getCustomerId())); + html.append("
Customer Id: ").append(escapeHtml4(loginData.getAccountCustomerId())); // customer name - html.append("
Customer Name: ").append(HtmlEscape.escapeHtml4(connection.getCustomerName())); + html.append("
Customer Name: ").append(escapeHtml4(connection.getCustomerName())); // device name - html.append("
App name: ").append(HtmlEscape.escapeHtml4(connection.getDeviceName())); + html.append("
App name: ").append(escapeHtml4(loginData.getDeviceName())); // connection - html.append("
Connected to: ").append(HtmlEscape.escapeHtml4(connection.getAlexaServer())); + html.append("
Connected to: ").append(escapeHtml4(connection.getAlexaServer())); // domain - html.append(" Change"); + // html.append(" Change"); // Main UI link - html.append("
"); - html.append(HtmlEscape.escapeHtml4("Check Thing in Main UI")); - html.append("

"); + .append(URLEncoder.encode(id, StandardCharsets.UTF_8)).append("'>").append("Check Thing in Main UI") + .append("

"); // device list html.append( ""); - for (Device device : this.accountHandler.getLastKnownDevices()) { - - html.append(""); html.append(""); } @@ -425,43 +414,40 @@ private void handleDefaultPageResult(HttpServletResponse resp, String message, C private void handleDevices(HttpServletResponse resp, Connection connection) throws ConnectionException { returnHtml(resp, - "" + HtmlEscape.escapeHtml4(connection.getRequestBuilder() + "" + escapeHtml4(connection.getRequestBuilder() .get(connection.getAlexaServer() + "/api/devices-v2/device?cached=false") .syncSend(String.class)) + "", connection.getAmazonSite()); } private String nullReplacement(@Nullable String text) { - return Objects.requireNonNullElse(text, "")); } private StringBuilder createPageStart(String title) { StringBuilder html = new StringBuilder(); - html.append("") - .append(HtmlEscape.escapeHtml4(BINDING_NAME + " - " + this.accountHandler.getThing().getLabel())); + html.append("<html><head><title>").append(BINDING_NAME).append(" - ") + .append(escapeHtml4(this.accountHandler.getThing().getLabel())); if (!title.isEmpty()) { - html.append(" - "); - html.append(HtmlEscape.escapeHtml4(title)); + html.append(" - ").append(escapeHtml4(title)); } html.append(""); - html.append("

") - .append(HtmlEscape.escapeHtml4(BINDING_NAME + " - " + this.accountHandler.getThing().getLabel())); + html.append("

").append(BINDING_NAME).append(" - ") + .append(escapeHtml4(this.accountHandler.getThing().getLabel())); if (!title.isEmpty()) { - html.append(" - "); - html.append(HtmlEscape.escapeHtml4(title)); + html.append(" - ").append(escapeHtml4(title)); } html.append("

"); + return html; } private void createPageEndAndSent(HttpServletResponse resp, StringBuilder html) { // account overview link - html.append("
"); - html.append(HtmlEscape.escapeHtml4("Account overview")); - html.append("
"); - + html.append("
").append("Account overview").append("
"); html.append(""); - resp.addHeader("content-type", "text/html;charset=UTF-8"); + + resp.addHeader(HttpHeader.CONTENT_TYPE.asString(), MimeTypes.Type.TEXT_HTML_UTF_8.asString()); try { resp.getWriter().write(html.toString()); } catch (IOException e) { @@ -469,7 +455,7 @@ private void createPageEndAndSent(HttpServletResponse resp, StringBuilder html) } } - private void handleIds(HttpServletResponse resp, Connection connection, Device device, @Nullable Thing thing) { + private void handleIds(HttpServletResponse resp, Connection connection, DeviceTO device, @Nullable Thing thing) { StringBuilder html; if (thing != null) { html = createPageStart("Channel Options - " + thing.getLabel()); @@ -484,38 +470,36 @@ private void handleIds(HttpServletResponse resp, Connection connection, Device d createPageEndAndSent(resp, html); } - private void renderCapabilities(Device device, StringBuilder html) { + private void renderCapabilities(DeviceTO device, StringBuilder html) { html.append("

Capabilities

"); html.append("
DeviceSerial NumberStateThingFamilyTypeCustomer Id
"); - html.append(HtmlEscape.escapeHtml4(nullReplacement(device.accountName))); - html.append(""); - html.append(HtmlEscape.escapeHtml4(nullReplacement(device.serialNumber))); + for (DeviceTO device : this.accountHandler.getLastKnownDevices()) { + html.append("
").append(nullReplacement(device.accountName)); + html.append("").append(nullReplacement(device.serialNumber)); + html.append("").append(device.online ? "Online" : "Offline"); html.append(""); - html.append(HtmlEscape.escapeHtml4(device.online ? "Online" : "Offline")); - html.append(""); - Thing accountHandler = this.accountHandler.findThingBySerialNumber(device.serialNumber); - if (accountHandler != null) { + Thing thing = this.accountHandler.findThingBySerialNumber(device.serialNumber); + if (thing != null) { html.append("") - .append(HtmlEscape.escapeHtml4(accountHandler.getLabel())).append(""); + .append(escapeHtml4(thing.getLabel())).append(""); } else { - html.append("") - .append(HtmlEscape.escapeHtml4("Not defined")).append(""); + html.append("not defined"); } html.append(""); - html.append(HtmlEscape.escapeHtml4(nullReplacement(device.deviceFamily))); + html.append(nullReplacement(device.deviceFamily)); html.append(""); String deviceTypeId = nullReplacement(device.deviceType); - html.append(HtmlEscape.escapeHtml4(DEVICE_TYPES.getOrDefault(deviceTypeId, deviceTypeId))); + html.append(DEVICE_TYPES.getOrDefault(deviceTypeId, deviceTypeId)); html.append(""); - html.append(HtmlEscape.escapeHtml4(nullReplacement(device.deviceOwnerCustomerId))); + html.append(nullReplacement(device.deviceOwnerCustomerId)); html.append("
"); - device.getCapabilities().forEach( - capability -> html.append("")); + device.capabilities + .forEach(capability -> html.append("")); html.append("
Name
").append(HtmlEscape.escapeHtml4(capability)).append("
").append(escapeHtml4(capability)).append("
"); } private void renderMusicProviderIdChannel(Connection connection, StringBuilder html) { - html.append("

").append(HtmlEscape.escapeHtml4("Channel " + CHANNEL_MUSIC_PROVIDER_ID)).append("

"); + html.append("

").append(escapeHtml4("Channel " + CHANNEL_MUSIC_PROVIDER_ID)).append("

"); html.append(""); - List musicProviders = connection.getMusicProviders(); - for (JsonMusicProvider musicProvider : musicProviders) { - List properties = musicProvider.supportedProperties; + List musicProviders = connection.getMusicProviders(); + for (MusicProviderTO musicProvider : musicProviders) { + if (!musicProvider.supportedProperties.contains("Alexa.Music.PlaySearchPhrase")) { + continue; + } String providerId = musicProvider.id; String displayName = musicProvider.displayName; - if (properties != null && properties.contains("Alexa.Music.PlaySearchPhrase") && providerId != null - && !providerId.isEmpty() && "AVAILABLE".equals(musicProvider.availability) && displayName != null - && !displayName.isEmpty()) { - html.append(""); + if (isNotBlank(providerId) && isNotBlank(displayName) && "AVAILABLE".equals(musicProvider.availability)) { + html.append(""); } } html.append("
NameValue
"); - html.append(HtmlEscape.escapeHtml4(displayName)); - html.append(""); - html.append(HtmlEscape.escapeHtml4(providerId)); - html.append("
").append(escapeHtml4(displayName)).append("") + .append(escapeHtml4(providerId)).append("
"); } - private void renderPlayAlarmSoundChannel(Connection connection, Device device, StringBuilder html) { - html.append("

").append(HtmlEscape.escapeHtml4("Channel " + CHANNEL_PLAY_ALARM_SOUND)).append("

"); - List notificationSounds = List.of(); + private void renderPlayAlarmSoundChannel(Connection connection, DeviceTO device, StringBuilder html) { + html.append("

").append("Channel ").append(CHANNEL_PLAY_ALARM_SOUND).append("

"); + + List notificationSounds = List.of(); String errorMessage = "No notifications sounds found"; try { notificationSounds = connection.getNotificationSounds(device); @@ -524,27 +508,26 @@ private void renderPlayAlarmSoundChannel(Connection connection, Device device, S } if (!notificationSounds.isEmpty()) { html.append(""); - for (JsonNotificationSound notificationSound : notificationSounds) { + for (NotificationSoundTO notificationSound : notificationSounds) { if (notificationSound.folder == null && notificationSound.providerId != null && notificationSound.id != null && notificationSound.displayName != null) { String providerSoundId = notificationSound.providerId + ":" + notificationSound.id; html.append(""); } } html.append("
NameValue
"); - html.append(HtmlEscape.escapeHtml4(notificationSound.displayName)); + html.append(escapeHtml4(notificationSound.displayName)); html.append(""); - html.append(HtmlEscape.escapeHtml4(providerSoundId)); + html.append(escapeHtml4(providerSoundId)); html.append("
"); } else { - html.append(HtmlEscape.escapeHtml4(errorMessage)); + html.append(escapeHtml4(errorMessage)); } } - private void renderAmazonMusicPlaylistIdChannel(Connection connection, Device device, StringBuilder html) { - html.append("

").append(HtmlEscape.escapeHtml4("Channel " + CHANNEL_AMAZON_MUSIC_PLAY_LIST_ID)) - .append("

"); + private void renderAmazonMusicPlaylistIdChannel(Connection connection, DeviceTO device, StringBuilder html) { + html.append("

").append(escapeHtml4("Channel " + CHANNEL_AMAZON_MUSIC_PLAY_LIST_ID)).append("

"); JsonPlaylists playLists = null; String errorMessage = "No playlists found"; @@ -564,56 +547,38 @@ private void renderAmazonMusicPlaylistIdChannel(Connection connection, Device de if (innerLists != null && innerLists.length > 0) { PlayList playList = innerLists[0]; if (playList.playlistId != null && playList.title != null) { - html.append(""); - html.append(HtmlEscape.escapeHtml4(nullReplacement(playList.title))); - html.append(""); - html.append(HtmlEscape.escapeHtml4(nullReplacement(playList.playlistId))); - html.append(""); + html.append("").append(nullReplacement(playList.title)).append("") + .append(nullReplacement(playList.playlistId)).append(""); } } } } html.append(""); } else { - html.append(HtmlEscape.escapeHtml4(errorMessage)); + html.append(escapeHtml4(errorMessage)); } } } - private void renderBluetoothMacChannel(Connection connection, Device device, StringBuilder html) { - html.append("

").append(HtmlEscape.escapeHtml4("Channel " + CHANNEL_BLUETOOTH_MAC)).append("

"); - JsonBluetoothStates bluetoothStates = connection.getBluetoothConnectionStates(); - BluetoothState[] innerStates = bluetoothStates.bluetoothStates; - if (innerStates == null) { - return; - } - for (BluetoothState state : innerStates) { - if (state == null) { - continue; - } - String stateDeviceSerialNumber = state.deviceSerialNumber; - if ((stateDeviceSerialNumber == null && device.serialNumber == null) - || (stateDeviceSerialNumber != null && stateDeviceSerialNumber.equals(device.serialNumber))) { - List pairedDeviceList = state.getPairedDeviceList(); - if (!pairedDeviceList.isEmpty()) { - html.append(""); - for (PairedDevice pairedDevice : pairedDeviceList) { - html.append(""); - } - html.append("
NameValue
"); - html.append(HtmlEscape.escapeHtml4(nullReplacement(pairedDevice.friendlyName))); - html.append(""); - html.append(HtmlEscape.escapeHtml4(nullReplacement(pairedDevice.address))); - html.append("
"); - } else { - html.append(HtmlEscape.escapeHtml4("No bluetooth devices paired")); - } + private void renderBluetoothMacChannel(Connection connection, DeviceTO device, StringBuilder html) { + html.append("

").append("Channel ").append(CHANNEL_BLUETOOTH_MAC).append("

"); + List states = connection.getBluetoothConnectionStates().bluetoothStates; + findInList(states, k -> k.deviceSerialNumber, device.serialNumber).ifPresent(state -> { + if (!state.pairedDeviceList.isEmpty()) { + html.append(""); + html.append(""); + state.pairedDeviceList.forEach(pairedDevice -> html.append("")); + html.append("
NameValue
") + .append(nullReplacement(pairedDevice.friendlyName)).append("") + .append(nullReplacement(pairedDevice.address)).append("
"); + } else { + html.append("No bluetooth devices paired"); } - } + }); } - void handleProxyRequest(Connection connection, HttpServletResponse resp, String verb, String url, - @Nullable String referer, @Nullable Object postData, boolean json, String site) throws IOException { + private void handleProxyRequest(Connection connection, HttpServletResponse resp, String verb, String url, + @Nullable String referer, @Nullable Object postData, String site) throws IOException { try { Map headers = new HashMap<>(); if (referer != null) { @@ -621,32 +586,27 @@ void handleProxyRequest(Connection connection, HttpServletResponse resp, String } HttpRequestBuilder.HttpResponse response = connection.getRequestBuilder() - .builder(HttpMethod.fromString(verb), url).withContent(postData).withHeaders(headers).retry(false) - .redirect(false).syncSend(); + .builder(HttpMethod.fromString(verb), url).withContent(postData).withJson(true).withHeaders(headers) + .retry(false).redirect(false).syncSend(); if (response.statusCode() == HttpStatus.FOUND_302) { String location = response.headers().get("location"); if (location.contains("/ap/maplanding")) { try { URI oAuthRedirectUri = new URI(location); - - Map queryParameters = new LinkedHashMap<>(); - String query = oAuthRedirectUri.getQuery(); - String[] pairs = query.split("&"); - for (String pair : pairs) { - int idx = pair.indexOf("="); - queryParameters.put(URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8), - URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8)); - } - String accessToken = queryParameters.get("openid.oa2.access_token"); + String accessToken = getQueryMap(oAuthRedirectUri.getQuery()).get("openid.oa2.access_token"); if (accessToken == null) { - throw new ConnectionException("Failed to get access token"); + returnError(resp, "Login to '" + connection.getAmazonSite() + + "' failed: Could not extract accessToken."); + } else if (connection.registerConnectionAsApp(accessToken)) { + accountHandler.setConnection(connection); + handleDefaultPageResult(resp, "Login succeeded", connection); + } else { + returnError(resp, + "Login to '" + connection.getAmazonSite() + "' failed: Could not register as app."); } - connection.registerConnectionAsApp(accessToken); - accountHandler.setConnection(connection); - handleDefaultPageResult(resp, "Login succeeded", connection); this.connectionToInitialize = null; return; - } catch (URISyntaxException | ConnectionException e) { + } catch (URISyntaxException e) { returnError(resp, "Login to '" + connection.getAmazonSite() + "' failed: " + e.getLocalizedMessage()); this.connectionToInitialize = null; @@ -656,7 +616,7 @@ void handleProxyRequest(Connection connection, HttpServletResponse resp, String String startString = "https://www." + connection.getAmazonSite() + "/"; String newLocation = null; - if (location.startsWith(startString) && connection.getIsLoggedIn()) { + if (location.startsWith(startString) && connection.isLoggedIn()) { newLocation = servletUrl + PROXY_URI_PART + location.substring(startString.length()); } else if (location.startsWith(startString)) { newLocation = servletUrl + FORWARD_URI_PART + location.substring(startString.length()); @@ -702,8 +662,8 @@ private void returnHtml(HttpServletResponse resp, String html, String amazonSite void returnError(HttpServletResponse resp, @Nullable String errorMessage) { try { String message = errorMessage != null ? errorMessage : "null"; - resp.getWriter().write("" + HtmlEscape.escapeHtml4(message) + "
Try again"); + resp.getWriter() + .write("" + escapeHtml4(message) + "
Try again"); } catch (IOException e) { logger.info("Returning error message failed", e); } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AmazonEchoControlBindingConstants.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AmazonEchoControlBindingConstants.java index d470fc3513..6c4f454eae 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AmazonEchoControlBindingConstants.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AmazonEchoControlBindingConstants.java @@ -46,10 +46,8 @@ public class AmazonEchoControlBindingConstants { public static final ThingTypeUID THING_TYPE_ECHO_SPOT = new ThingTypeUID(BINDING_ID, "echospot"); public static final ThingTypeUID THING_TYPE_ECHO_SHOW = new ThingTypeUID(BINDING_ID, "echoshow"); public static final ThingTypeUID THING_TYPE_ECHO_WHA = new ThingTypeUID(BINDING_ID, "wha"); - public static final ThingTypeUID THING_TYPE_FLASH_BRIEFING_PROFILE = new ThingTypeUID(BINDING_ID, "flashbriefingprofile"); - public static final ThingTypeUID THING_TYPE_SMART_HOME_DEVICE = new ThingTypeUID(BINDING_ID, "smartHomeDevice"); public static final ThingTypeUID THING_TYPE_SMART_HOME_DEVICE_GROUP = new ThingTypeUID(BINDING_ID, "smartHomeDeviceGroup"); @@ -103,7 +101,6 @@ public class AmazonEchoControlBindingConstants { public static final String CHANNEL_NEXT_ALARM = "nextAlarm"; public static final String CHANNEL_NEXT_MUSIC_ALARM = "nextMusicAlarm"; public static final String CHANNEL_NEXT_TIMER = "nextTimer"; - public static final String CHANNEL_SAVE = "save"; public static final String CHANNEL_ACTIVE = "active"; public static final String CHANNEL_PLAY_ON_DEVICE = "playOnDevice"; @@ -124,86 +121,8 @@ public class AmazonEchoControlBindingConstants { public static final String DI_OS_VERSION = "16.6"; public static final String DI_SDK_VERSION = "6.12.4"; - // DeviceTypeIds to human readable description - // originally found here: https://github.com/Apollon77/ioBroker.alexa2/blob/master/main.js - public static final Map DEVICE_TYPES = Map. ofEntries( // - Map.entry("A10A33FOX2NUBK", "Echo Spot"), // - Map.entry("A10L5JEZTKKCZ8", "Vobot-Clock"), // - Map.entry("A12GXV8XMS007S", "FireTV"), // - Map.entry("A15ERDAKK5HQQG", "Sonos"), // - Map.entry("A17LGWINFBUTZZ", "Anker Roav Viva Alexa"), // - Map.entry("A18O6U1UQFJ0XK", "Echo Plus 2nd Gen"), // - Map.entry("A1C66CX2XD756O", "Fire HD 8"), // - Map.entry("A1DL2DVDQVK3Q", "Apps"), // - Map.entry("A1ETW4IXK2PYBP", "Echo Auto"), // - Map.entry("A1H0CMF1XM0ZP4", "Echo Dot/Bose"), // - Map.entry("A1J16TEDOYCZTN", "Fire Tab"), // - Map.entry("A1JJ0KFC4ZPNJ3", "Echo Input"), // - Map.entry("A1NL4BVLQ4L3N3", "Echo Show"), // - Map.entry("A1P31Q3MOWSHOD", "Anker Zalo Halo Speaker"), // - Map.entry("A1Q7QCGNMXAKYW", "Fire Tab 7"), // - Map.entry("A1QKZ9D0IJY332", "Samsung QLED"), // - Map.entry("A1RABVCI4QCIKC", "Echo Dot 3rd Gen"), // - Map.entry("A1RTAM01W29CUP", "Windows App"), // - Map.entry("A1X7HJX9QL16M5", "Bespoken.io"), // - Map.entry("A1Z88NGR2BK6A2", "Echo Show 8"), // - Map.entry("A1ZB65LA390I4K", "Fire HD 10"), // - Map.entry("A21Z3CGI8UIP0F", "Apps"), // - Map.entry("A265XOI9586NML", "FireTV Stick v3"), // - Map.entry("A2825NDLA7WDZV", "Apps"), // - Map.entry("A2E0SNTXJVT7WK", "FireTV V1"), // - Map.entry("A2GFL5ZMWNE0PX", "FireTV"), // - Map.entry("A2H4LV5GIZ1JFT", "Echo 4 Clock"), // - Map.entry("A2IVLV5VM2W81", "Apps"), // - Map.entry("A2J0R2SD7G9LPA", "Tablet"), // - Map.entry("A2JKHJ0PX4J3L3", "FireTV Cube"), // - Map.entry("A2L8KG0CT86ADW", "RaspPi"), // - Map.entry("A2LWARUGJLBYEW", "FireTV Stick V2"), // - Map.entry("A2M35JJZWCQOMZ", "Echo Plus"), // - Map.entry("A2M4YX06LWP8WI", "Fire Tab"), // - Map.entry("A2OSP3UA4VC85F", "Sonos"), // - Map.entry("A2T0P32DY3F7VB", "echosim.io"), // - Map.entry("A2TF17PFR55MTB", "Apps"), // - Map.entry("A2U21SRK4QGSE1", "Echo Dot 4th Gen"), // - Map.entry("A2Z8O30CD35N8F", "Sonos Arc"), // - Map.entry("A303PJF6ISQ7IC", "Echo Auto"), // - Map.entry("A30YDR2MK8HMRV", "Echo Dot 3rd Gen Clock"), // - Map.entry("A31DTMEEVDDOIV", "FireTV Stick Lite 2020"), // - Map.entry("A32DOYMUN6DTXA", "Echo Dot 3rd Gen"), // - Map.entry("A378ND93PD0NC4", "VR Radio"), // - Map.entry("A37SHHQ3NUL7B5", "Bose Homespeaker"), // - Map.entry("A38BPK7OW001EX", "Raspberry Alexa"), // - Map.entry("A38EHHIB10L47V", "Echo Dot"), // - Map.entry("A39Y3UG1XLEJLZ", "Fitbit Sense"), // - Map.entry("A3C9PE6TNYLTCH", "Multiroom"), // - Map.entry("A3FX4UWTP28V1P", "Echo 3"), // - Map.entry("A3GZUE7F9MEB4U", "FireTV Cube"), // - Map.entry("A3H674413M2EKB", "echosim.io"), // - Map.entry("A3HF4YRA2L7XGC", "FireTV Cube"), // - Map.entry("A3NPD82ABCPIDP", "Sonos Beam"), // - Map.entry("A3R8XIAIU4HJAX", "Echo Show"), // - Map.entry("A3R9S4ZZECZ6YL", "Fire Tab HD 10"), // - Map.entry("A3RBAYBE7VM004", "Echo Studio"), // - Map.entry("A3RMGO6LYLH7YN", "Echo 4 Bridge"), // - Map.entry("A3S5BH2HU6VAYF", "Echo Dot 2nd Gen"), // - Map.entry("A3SSG6GR8UU7SN", "Echo Sub"), // - Map.entry("A3TCJ8RTT3NVI7", "Listens for Alexa"), // - Map.entry("A3V3VA38K169FO", "Fire Tab"), // - Map.entry("A3VRME03NAXFUB", "Echo Flex"), // - Map.entry("A4ZP7ZC4PI6TO", "Echo Show 5th Gen"), // - Map.entry("A7WXQPH584YP", "Echo 2nd Gen"), // - Map.entry("A8DM4FYR6D3HT", "LG WebOS TV"), // - Map.entry("AB72C64C86AW2", "Echo"), // - Map.entry("ADVBD696BHNV5", "FireTV Stick V1"), // - Map.entry("AILBSA2LNTOYL", "reverb App"), // - Map.entry("AINRG27IL8AS0", "Megablast Speaker"), // - Map.entry("AKOAGQTKAS9YB", "Echo Connect"), // - Map.entry("AKPGW064GI9HE", "FireTV Stick 4K"), // - Map.entry("AP1F6KUH00XPV", "Stereo/Subwoofer Pair"), // - Map.entry("AVD3HM0HOJAAL", "Sonos One 2nd Gen"), // - Map.entry("AVE5HX13UR5NO", "Logitech Zero Touch"), // - Map.entry("AVU7CPPF2ZRAS", "Fire HD 8"), // - Map.entry("AWZZ5CVHX2CD", "Echo Show 2nd Gen")); + public static final Map DEVICE_TYPES = ResourceUtil + .readProperties(AmazonEchoControlBindingConstants.class, "device_type.properties"); public static final JsonObject CAPABILITY_REGISTRATION = Objects.requireNonNull( ResourceUtil.getResourceStream(AmazonEchoControlBindingConstants.class, "registration_capabilities.json") diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java index 963ed9b60c..15dbe0f6ff 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java @@ -31,7 +31,6 @@ import org.openhab.core.thing.binding.BaseThingHandlerFactory; import org.openhab.core.thing.binding.ThingHandler; import org.openhab.core.thing.binding.ThingHandlerFactory; -import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; @@ -41,6 +40,7 @@ import org.smarthomej.binding.amazonechocontrol.internal.handler.EchoHandler; import org.smarthomej.binding.amazonechocontrol.internal.handler.FlashBriefingProfileHandler; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; +import org.smarthomej.binding.amazonechocontrol.internal.util.NonNullListTypeAdapterFactory; import org.smarthomej.binding.amazonechocontrol.internal.util.SerializeNullTypeAdapterFactory; import org.smarthomej.commons.SimpleDynamicCommandDescriptionProvider; import org.smarthomej.commons.SimpleDynamicStateDescriptionProvider; @@ -62,7 +62,6 @@ public class AmazonEchoControlHandlerFactory extends BaseThingHandlerFactory { private final HttpService httpService; private final StorageService storageService; - private final BindingServlet bindingServlet; private final Gson gson; private final HttpClient httpClient; private final HTTP2Client http2Client; @@ -77,7 +76,8 @@ public AmazonEchoControlHandlerFactory(@Reference HttpService httpService, @Refe @Reference HttpClientFactory httpClientFactory) throws Exception { this.storageService = storageService; this.httpService = httpService; - this.gson = new GsonBuilder().registerTypeAdapterFactory(new SerializeNullTypeAdapterFactory()).create(); + this.gson = new GsonBuilder().registerTypeAdapterFactory(new NonNullListTypeAdapterFactory()) + .registerTypeAdapterFactory(new SerializeNullTypeAdapterFactory()).create(); this.dynamicCommandDescriptionProvider = dynamicCommandDescriptionProvider; this.dynamicStateDescriptionProvider = dynamicStateDescriptionProvider; @@ -86,8 +86,6 @@ public AmazonEchoControlHandlerFactory(@Reference HttpService httpService, @Refe http2Client.setConnectTimeout(10000); http2Client.setIdleTimeout(-1); - this.bindingServlet = new BindingServlet(httpService); - httpClient.start(); http2Client.start(); } @@ -105,12 +103,6 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { || SUPPORTED_SMART_HOME_THING_TYPES_UIDS.contains(thingTypeUID); } - @Override - protected void deactivate(ComponentContext componentContext) { - bindingServlet.dispose(); - super.deactivate(componentContext); - } - @Override protected @Nullable ThingHandler createHandler(Thing thing) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); @@ -121,7 +113,6 @@ protected void deactivate(ComponentContext componentContext) { AccountHandler bridgeHandler = new AccountHandler((Bridge) thing, httpService, storage, gson, httpClient, http2Client); accountHandlers.add(bridgeHandler); - bindingServlet.addAccountThing(thing); return bridgeHandler; } else if (thingTypeUID.equals(THING_TYPE_FLASH_BRIEFING_PROFILE)) { Storage storage = storageService.getStorage(thing.getUID().toString(), @@ -140,8 +131,6 @@ protected void deactivate(ComponentContext componentContext) { protected synchronized void removeHandler(ThingHandler thingHandler) { if (thingHandler instanceof AccountHandler) { accountHandlers.remove(thingHandler); - BindingServlet bindingServlet = this.bindingServlet; - bindingServlet.removeAccountThing(thingHandler.getThing()); } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/BindingServlet.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/BindingServlet.java index e86deecc4d..0df8491d06 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/BindingServlet.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/BindingServlet.java @@ -13,26 +13,30 @@ */ package org.smarthomej.binding.amazonechocontrol.internal; +import static org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.BINDING_ID; import static org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.BINDING_NAME; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; +import java.util.Collection; -import javax.servlet.ServletException; +import javax.servlet.Servlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.thing.Thing; -import org.osgi.service.http.HttpService; -import org.osgi.service.http.NamespaceException; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.MimeTypes; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardServletName; +import org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardServletPattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.smarthomej.binding.amazonechocontrol.internal.handler.AccountHandler; import org.unbescape.html.HtmlEscape; /** @@ -40,60 +44,34 @@ * * @author Michael Geramb - Initial Contribution */ + +@Component(service = Servlet.class, immediate = true) +@HttpWhiteboardServletName(BindingServlet.SERVLET_PATH) +@HttpWhiteboardServletPattern({ BindingServlet.SERVLET_PATH, BindingServlet.SERVLET_PATH + "/" }) @NonNullByDefault public class BindingServlet extends HttpServlet { + public static final String SERVLET_PATH = "/" + BINDING_ID; private static final long serialVersionUID = -1453738923337413163L; private final Logger logger = LoggerFactory.getLogger(BindingServlet.class); - private final String servletUrl; - private final HttpService httpService; - - private final List accountHandlers = new ArrayList<>(); + private final AmazonEchoControlHandlerFactory handlerFactory; - public BindingServlet(HttpService httpService) { - this.httpService = httpService; - String servletUrlWithoutRoot = "amazonechocontrol"; - servletUrl = "/" + servletUrlWithoutRoot; - try { - httpService.registerServlet(servletUrl, this, null, httpService.createDefaultHttpContext()); - } catch (NamespaceException | ServletException e) { - logger.warn("Register servlet fails", e); - } - } - - public void addAccountThing(Thing accountThing) { - synchronized (accountHandlers) { - accountHandlers.add(accountThing); - } - } - - public void removeAccountThing(Thing accountThing) { - synchronized (accountHandlers) { - accountHandlers.remove(accountThing); - } - } - - public void dispose() { - httpService.unregister(servletUrl); + @Activate + public BindingServlet(@Reference AmazonEchoControlHandlerFactory handlerFactory) { + this.handlerFactory = handlerFactory; } @Override - protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResponse resp) - throws ServletException, IOException { - if (req == null) { - return; - } - if (resp == null) { - return; - } + protected void doGet(@NonNullByDefault({}) HttpServletRequest req, @NonNullByDefault({}) HttpServletResponse resp) + throws IOException { String requestUri = req.getRequestURI(); if (requestUri == null) { return; } - String uri = requestUri.substring(servletUrl.length()); + String uri = requestUri.substring(SERVLET_PATH.length()); String queryString = req.getQueryString(); - if (queryString != null && queryString.length() > 0) { + if (queryString != null && !queryString.isEmpty()) { uri += "?" + queryString; } logger.debug("doGet {}", uri); @@ -105,23 +83,22 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp } StringBuilder html = new StringBuilder(); - html.append("").append(HtmlEscape.escapeHtml4(BINDING_NAME)).append(""); - html.append("

").append(HtmlEscape.escapeHtml4(BINDING_NAME)).append("

"); - - synchronized (accountHandlers) { - if (accountHandlers.isEmpty()) { - html.append("No Account thing created."); - } else { - for (Thing accountHandler : accountHandlers) { - String url = URLEncoder.encode(accountHandler.getUID().getId(), StandardCharsets.UTF_8); - html.append("") - .append(HtmlEscape.escapeHtml4(accountHandler.getLabel())).append("
"); - } + html.append("").append(BINDING_NAME).append(""); + html.append("

").append(BINDING_NAME).append("

"); + + Collection accountHandlers = handlerFactory.getAccountHandlers(); + if (accountHandlers.isEmpty()) { + html.append("No Account thing created."); + } else { + for (AccountHandler accountHandler : accountHandlers) { + String url = URLEncoder.encode(accountHandler.getThing().getUID().getId(), StandardCharsets.UTF_8); + html.append("") + .append(HtmlEscape.escapeHtml4(accountHandler.getThing().getLabel())).append("
"); } } html.append(""); - resp.addHeader("content-type", "text/html;charset=UTF-8"); + resp.addHeader(HttpHeader.CONTENT_TYPE.asString(), MimeTypes.Type.TEXT_HTML_UTF_8.asString()); try { resp.getWriter().write(html.toString()); } catch (IOException e) { diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/ConsoleCommandExtension.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/ConsoleCommandExtension.java index c8f7b5b22f..99e4457c7c 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/ConsoleCommandExtension.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/ConsoleCommandExtension.java @@ -13,6 +13,8 @@ */ package org.smarthomej.binding.amazonechocontrol.internal; +import static org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.BINDING_ID; + import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -41,8 +43,7 @@ public class ConsoleCommandExtension extends AbstractConsoleCommandExtension { @Activate public ConsoleCommandExtension(@Reference AmazonEchoControlHandlerFactory handlerFactory) { - super("amazonechocontrol", "Manage the AmazonEchoControl account"); - + super(BINDING_ID, "Manage the AmazonEchoControl account"); this.handlerFactory = handlerFactory; } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/AmazonHandlerCallback.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/AmazonHandlerCallback.java index c07e5f8138..21b3c9a4ea 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/AmazonHandlerCallback.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/AmazonHandlerCallback.java @@ -19,7 +19,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.core.types.State; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; /** * The {@link AmazonHandlerCallback} is used from ChannelHandlers to communicate @@ -32,6 +32,6 @@ public interface AmazonHandlerCallback { void updateChannelState(String channelId, State state); - void startAnnouncement(Device device, String speak, String bodyText, @Nullable String title, + void startAnnouncement(DeviceTO device, String speak, String bodyText, @Nullable String title, @Nullable Integer volume) throws IOException, URISyntaxException; } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java index 96f7e241a0..6f83265eae 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java @@ -17,7 +17,7 @@ import org.openhab.core.types.Command; import org.smarthomej.binding.amazonechocontrol.internal.ConnectionException; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; /** * The {@link ChannelHandler} is the base class for all channel handlers @@ -27,6 +27,6 @@ @NonNullByDefault public interface ChannelHandler { - boolean tryHandleCommand(Device device, Connection connection, String channelId, Command command) + boolean tryHandleCommand(DeviceTO device, Connection connection, String channelId, Command command) throws ConnectionException; } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java index c54033f9d5..e69d2fd584 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java @@ -23,7 +23,7 @@ import org.openhab.core.types.Command; import org.smarthomej.binding.amazonechocontrol.internal.ConnectionException; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; @@ -47,7 +47,7 @@ public ChannelHandlerAnnouncement(AmazonHandlerCallback callback, Gson gson) { } @Override - public boolean tryHandleCommand(Device device, Connection connection, String channelId, Command command) + public boolean tryHandleCommand(DeviceTO device, Connection connection, String channelId, Command command) throws ConnectionException { try { if (channelId.equals(CHANNEL_NAME)) { diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerSendMessage.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerSendMessage.java index 271c7926e3..b3ffb4bdf6 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerSendMessage.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerSendMessage.java @@ -21,7 +21,7 @@ import org.openhab.core.types.Command; import org.smarthomej.binding.amazonechocontrol.internal.ConnectionException; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; import com.google.gson.Gson; @@ -46,7 +46,7 @@ public ChannelHandlerSendMessage(AmazonHandlerCallback callback, Gson gson) { } @Override - public boolean tryHandleCommand(Device device, Connection connection, String channelId, Command command) + public boolean tryHandleCommand(DeviceTO device, Connection connection, String channelId, Command command) throws ConnectionException { if (channelId.equals(CHANNEL_NAME)) { if (command instanceof StringType) { diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/AnnouncementWrapper.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/AnnouncementWrapper.java index 7a01cc01ae..86185fc71c 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/AnnouncementWrapper.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/AnnouncementWrapper.java @@ -17,7 +17,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.request.AnnouncementTO; /** * The {@link AnnouncementWrapper} is a wrapper for announcement instructions @@ -26,7 +27,7 @@ */ @NonNullByDefault public class AnnouncementWrapper { - private final List devices = new ArrayList<>(); + private final List devices = new ArrayList<>(); private final List<@Nullable Integer> ttsVolumes = new ArrayList<>(); private final List<@Nullable Integer> standardVolumes = new ArrayList<>(); @@ -40,13 +41,13 @@ public AnnouncementWrapper(String speak, String bodyText, @Nullable String title this.title = title; } - public void add(JsonDevices.Device device, @Nullable Integer ttsVolume, @Nullable Integer standardVolume) { + public void add(DeviceTO device, @Nullable Integer ttsVolume, @Nullable Integer standardVolume) { devices.add(device); ttsVolumes.add(ttsVolume); standardVolumes.add(standardVolume); } - public List getDevices() { + public List getDevices() { return devices; } @@ -69,4 +70,14 @@ public String getBodyText() { public List<@Nullable Integer> getStandardVolumes() { return standardVolumes; } + + public AnnouncementTO toAnnouncementTO() { + AnnouncementTO announcement = new AnnouncementTO(); + announcement.display.body = bodyText; + String title = this.title; + announcement.display.title = (title == null || title.isBlank()) ? "openHAB" : title; + announcement.speak.value = speak; + announcement.speak.type = (speak.startsWith("") && speak.endsWith("")) ? "ssml" : "text"; + return announcement; + } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/Connection.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/Connection.java index e4a28f9a62..eba1088160 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/Connection.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/Connection.java @@ -13,7 +13,8 @@ */ package org.smarthomej.binding.amazonechocontrol.internal.connection; -import static org.eclipse.jetty.http.HttpStatus.*; +import static org.eclipse.jetty.http.HttpStatus.NO_CONTENT_204; +import static org.eclipse.jetty.http.HttpStatus.OK_200; import static org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.CAPABILITY_REGISTRATION; import java.io.IOException; @@ -44,7 +45,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -61,55 +61,54 @@ import org.slf4j.LoggerFactory; import org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants; import org.smarthomej.binding.amazonechocontrol.internal.ConnectionException; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonAnnouncementContent; +import org.smarthomej.binding.amazonechocontrol.internal.dto.AscendingAlarmTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceNotificationStateTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DoNotDisturbDeviceStatusTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.EnabledFeedsTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.EqualizerTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.FeedTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonAnnouncementTarget; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonAscendingAlarm; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonAscendingAlarm.AscendingAlarmModel; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonAutomation; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonAutomation.Payload; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonBluetoothStates; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonBootstrapResult; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonBootstrapResult.Authentication; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonCustomerHistoryRecords; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonCustomerHistoryRecords.CustomerHistoryRecord; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDeviceNotificationState; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDeviceNotificationState.DeviceNotificationState; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDoNotDisturb; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDoNotDisturb.DoNotDisturbDeviceStatus; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonEnabledFeeds; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonEqualizer; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonExchangeTokenResponse; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonExchangeTokenResponse.Cookie; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonFeed; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonMediaState; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonMusicProvider; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNetworkDetails; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNotificationRequest; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNotificationResponse; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNotificationSound; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNotificationSounds; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNotificationsResponse; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlaySearchPhraseOperationPayload; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlayValidationResult; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlayerState; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlaylists; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonRegisterAppRequest; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonRegisterAppResponse; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonRegisterAppResponse.MacDms; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonRegisterAppResponse.Tokens; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonRenewTokenResponse; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeGroups.SmartHomeGroup; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonStartRoutineRequest; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonUsersMeResponse; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonWakeWords; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonWakeWords.WakeWord; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonWebSiteCookie; -import org.smarthomej.binding.amazonechocontrol.internal.dto.SmartHomeBaseDevice; -import org.smarthomej.binding.amazonechocontrol.internal.dto.request.ToggleAscendingAlarmTO; -import org.smarthomej.binding.amazonechocontrol.internal.dto.request.ToggleDoNotDisturbTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.NotificationSoundTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.NotificationStateTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.NotificationTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.request.AnnouncementTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.request.RegisterAppRequestTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.request.WebSiteCookieTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.AscendingAlarmModelResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.AuthTokenResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.AuthenticationTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.BluetoothStateResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.BootstrapResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.CustomerHistoryRecordResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.CustomerHistoryRecordTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.DeviceListResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.DeviceNotificationStateResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.DoNotDisturbDeviceStatusResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.EndpointResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.MusicProviderTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.NotificationListResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.NotificationSoundResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.RegisterAppResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.TokensTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.UsersMeResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.WakeWordResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.WakeWordTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeGroups.SmartHomeGroup; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.SmartHomeBaseDevice; import org.smarthomej.binding.amazonechocontrol.internal.util.HttpRequestBuilder; import org.unbescape.json.JsonEscape; import org.unbescape.json.JsonEscapeLevel; @@ -126,8 +125,7 @@ import com.google.gson.JsonSyntaxException; /** - * The {@link Connection} is responsible for the connection to the amazon server - * and handling of the commands + * The {@link Connection} is responsible for the connection to the amazon server and handling of the commands * * @author Michael Geramb - Initial contribution */ @@ -146,12 +144,10 @@ public class Connection { private final LoginData loginData; private final CookieManager cookieManager = new CookieManager(); private final HttpRequestBuilder requestBuilder; - private String alexaServer = "https://alexa.amazon.com"; private @Nullable Date verifyTime; private long connectionExpiryTime = 0; private long accessTokenExpiryTime = 0; private @Nullable String customerName; - private @Nullable MacDms macDms; private @Nullable String accessToken; private final Map announcements = Collections.synchronizedMap(new LinkedHashMap<>()); @@ -177,8 +173,9 @@ public Connection(@Nullable Connection oldConnection, Gson gson, HttpClient http this.gson = gson; this.requestBuilder = new HttpRequestBuilder(httpClient, cookieManager, gson); if (oldConnection != null) { - this.loginData = new LoginData(cookieManager, oldConnection.getDeviceId(), oldConnection.getFrc(), - oldConnection.getSerial()); + LoginData oldLoginData = oldConnection.getLoginData(); + this.loginData = new LoginData(cookieManager, oldLoginData.getDeviceId(), oldLoginData.getFrc(), + oldLoginData.getSerial()); } else { this.loginData = new LoginData(cookieManager); } @@ -187,19 +184,6 @@ public Connection(@Nullable Connection oldConnection, Gson gson, HttpClient http scheduler.scheduleWithFixedDelay(this::handleExecuteSequenceNode, 0, 500, TimeUnit.MILLISECONDS)); } - private void setAmazonSite(@Nullable String amazonSite) { - if (amazonSite != null) { - Matcher matcher = SITE_PATTERN.matcher(amazonSite); - if (matcher.matches()) { - this.loginData.amazonSite = matcher.group("amazonSite"); - this.alexaServer = "https://eu-api-alexa." + matcher.group("amazonSite"); - return; - } - } - this.loginData.amazonSite = "amazon.com"; - this.alexaServer = "https://alexa.amazon.com"; - } - public HttpRequestBuilder getRequestBuilder() { return requestBuilder; } @@ -213,36 +197,12 @@ public LoginData getLoginData() { return verifyTime; } - public String getFrc() { - return loginData.frc; - } - - public String getSerial() { - return loginData.serial; - } - - public String getDeviceId() { - return loginData.deviceId; - } - public String getAmazonSite() { - return loginData.amazonSite; + return loginData.getRetailDomain(); } public String getAlexaServer() { - return alexaServer; - } - - public @Nullable MacDms getMacDms() { - return this.macDms; - } - - public String getDeviceName() { - return this.loginData.deviceName; - } - - public String getCustomerId() { - return Objects.requireNonNullElse(loginData.accountCustomerId, "Unknown"); + return this.loginData.getWebsiteApiUrl(); } public String getCustomerName() { @@ -255,157 +215,133 @@ public boolean isSequenceNodeQueueRunning() { } public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloadedDomain) { - Date loginTime = tryRestoreSessionData(data, overloadedDomain); - if (loginTime != null) { - try { - if (verifyLogin()) { - this.loginData.loginTime = loginTime; - return true; + try { + // verify stored data + if (data != null && !data.isEmpty() && loginData.deserialize(data)) { + if (overloadedDomain != null) { + loginData.setRetailDomain(overloadedDomain); + } + checkRenewSession(); + + // TODO: remove in future versions - check if login-data is correctly set + String retailDomain = loginData.getRetailDomain(); + String retailDomainTLD = retailDomain.substring(retailDomain.lastIndexOf(".")); + if (!loginData.getRetailUrl().endsWith(retailDomainTLD)) { + EndpointResponseTO endpoints = requestBuilder.get("https://alexa.amazon.com/api/endpoints") + .syncSend(EndpointResponseTO.class); + this.loginData.setRetailDomain(endpoints.retailDomain); + this.loginData.setWebsiteApiUrl(endpoints.websiteApiUrl); + this.loginData.setRetailUrl(endpoints.retailUrl); } - } catch (ConnectionException e) { - // no action - } - } - return false; - } - - private @Nullable Date tryRestoreSessionData(@Nullable String data, @Nullable String overloadedDomain) { - // verify stored data - if (data == null || data.isEmpty() || !loginData.deserialize(data)) { - return null; - } - - if (overloadedDomain != null) { - loginData.amazonSite = overloadedDomain; - } - - setAmazonSite(loginData.amazonSite); - try { - checkRenewSession(); - - String accountCustomerId = this.loginData.accountCustomerId; - if (accountCustomerId == null || accountCustomerId.isEmpty()) { - List devices = this.getDeviceList(); - accountCustomerId = devices.stream().filter(device -> loginData.serial.equals(device.serialNumber)) - .findAny().map(device -> device.deviceOwnerCustomerId).orElse(null); - if (accountCustomerId == null || accountCustomerId.isEmpty()) { - accountCustomerId = devices.stream().filter(device -> "This Device".equals(device.accountName)) - .findAny().map(device -> { - loginData.serial = Objects.requireNonNullElse(device.serialNumber, loginData.serial); - return device.deviceOwnerCustomerId; - }).orElse(null); + if (verifyLogin()) { + return true; } - this.loginData.accountCustomerId = accountCustomerId; } } catch (ConnectionException e) { - logger.debug("Getting account customer Id failed", e); + // no action } - return loginData.loginTime; + this.loginData.setLoginTime(null); + return false; } - private @Nullable Authentication tryGetBootstrap() { + private boolean tryGetBootstrap() { try { - HttpRequestBuilder.HttpResponse response = requestBuilder.get(alexaServer + "/api/bootstrap").retry(false) - .redirect(false).syncSend(); - String contentType = response.headers().get(HttpHeader.CONTENT_TYPE); - - if (response.statusCode() == OK_200 && contentType != null - && contentType.toLowerCase().startsWith("application/json")) { - JsonBootstrapResult result = parseJson(response.content(), JsonBootstrapResult.class); - if (result != null) { - Authentication authentication = result.authentication; - if (authentication != null && authentication.authenticated) { - this.customerName = authentication.customerName; - if (this.loginData.accountCustomerId == null) { - this.loginData.accountCustomerId = authentication.customerId; - } - return authentication; - } - } + BootstrapResponseTO result = requestBuilder.get(getAlexaServer() + "/api/bootstrap").retry(false) + .redirect(false).syncSend(BootstrapResponseTO.class); + AuthenticationTO authentication = result.authentication; + if (authentication != null && authentication.authenticated) { + this.customerName = authentication.customerName; + this.loginData.setAccountCustomerId(authentication.customerId); + return authentication.authenticated; } - } catch (JsonSyntaxException | IllegalStateException e) { - logger.info("No valid json received", e); } catch (ConnectionException e) { logger.debug("Bootstrapping failed", e); } - return null; + return false; } - public void registerConnectionAsApp(String accessToken) throws ConnectionException { - List webSiteCookies = new ArrayList<>(); - for (HttpCookie cookie : cookieManager.getCookieStore().get(URI.create("https://www.amazon.com"))) { - webSiteCookies.add(new JsonWebSiteCookie(cookie.getName(), cookie.getValue())); - } - - JsonRegisterAppRequest registerAppRequest = new JsonRegisterAppRequest(loginData.serial, accessToken, - loginData.frc, webSiteCookies); + private WebSiteCookieTO mapWebSiteCookie(HttpCookie cookie) { + WebSiteCookieTO webSiteCookie = new WebSiteCookieTO(); + webSiteCookie.name = cookie.getName(); + webSiteCookie.value = cookie.getValue(); + return webSiteCookie; + } - JsonRegisterAppResponse registerAppResponse = requestBuilder.post("https://api.amazon.com/auth/register") - .withContent(registerAppRequest).withHeaders(Map.of("x-amzn-identity-auth-domain", "api.amazon.com")) - .syncSend(JsonRegisterAppResponse.class); + public boolean registerConnectionAsApp(String accessToken) { + try { + List webSiteCookies = cookieManager.getCookieStore() + .get(URI.create("https://www.amazon.com")).stream().map(this::mapWebSiteCookie).toList(); - if (registerAppResponse == null) { - throw new ConnectionException("Error: No response received from register application"); - } + RegisterAppRequestTO registerAppRequest = new RegisterAppRequestTO(); + registerAppRequest.registrationData.deviceSerial = loginData.getSerial(); + registerAppRequest.authData.accessToken = accessToken; + registerAppRequest.userContextMap = Map.of("frc", loginData.getFrc()); + registerAppRequest.cookies.webSiteCookies = webSiteCookies; - Tokens tokens = registerAppResponse.response.success.tokens; - String refreshToken = tokens.bearer.refreshToken; - this.macDms = tokens.macDms; + RegisterAppResponseTO registerAppResponse = requestBuilder.post("https://api.amazon.com/auth/register") + .withContent(registerAppRequest) + .withHeaders(Map.of("x-amzn-identity-auth-domain", "api.amazon.com")) + .syncSend(RegisterAppResponseTO.class); - this.loginData.refreshToken = refreshToken; + TokensTO tokens = registerAppResponse.response.success.tokens; + String refreshToken = tokens.bearer.refreshToken; - if (refreshToken == null || refreshToken.isEmpty()) { - throw new ConnectionException("Error: No refresh token received"); - } + this.loginData.setRefreshToken(refreshToken); - try { - HttpRequestBuilder.HttpResponse response = requestBuilder - .put("https://api.amazonalexa.com/v1/devices/@self/capabilities") - .withContent(CAPABILITY_REGISTRATION) - .withHeaders(Map.of(HttpHeader.AUTHORIZATION.toString(), "Bearer " + accessToken)).retry(false) - .syncSend(); - if (response.statusCode() != NO_CONTENT_204 && response.statusCode() != OK_200) { - logger.warn("Registering capabilities failed, HTTP/2 stream will not work"); + if (refreshToken == null || refreshToken.isBlank()) { + logger.warn("Could not determine refreshToken while trying to register as app."); + return false; } - } catch (ConnectionException e) { - logger.warn("Registering capabilities failed, HTTP/2 stream will not work: {}", e.getMessage()); - } - try { - exchangeToken(); + exchangeToken(getAmazonSite()); // Check which is the owner domain - JsonUsersMeResponse usersMeResponse = requestBuilder + UsersMeResponseTO usersMeResponse = requestBuilder .get("https://alexa.amazon.com/api/users/me?platform=ios&version=" + AmazonEchoControlBindingConstants.API_VERSION) - .syncSend(JsonUsersMeResponse.class); - if (usersMeResponse == null) { - throw new IllegalStateException(); - } - URI uri = new URI(usersMeResponse.marketPlaceDomainName); - String host = uri.getHost(); + .syncSend(UsersMeResponseTO.class); // Switch to owner domain - setAmazonSite(host); - exchangeToken(); + exchangeToken(usersMeResponse.marketPlaceDomainName); + EndpointResponseTO endpoints = requestBuilder.get("https://alexa.amazon.com/api/endpoints") + .syncSend(EndpointResponseTO.class); + this.loginData.setRetailDomain(endpoints.retailDomain); + this.loginData.setWebsiteApiUrl(endpoints.websiteApiUrl); + this.loginData.setRetailUrl(endpoints.retailUrl); + + try { + HttpRequestBuilder.HttpResponse response = requestBuilder + .put("https://api.amazonalexa.com/v1/devices/@self/capabilities") + .withContent(CAPABILITY_REGISTRATION) + .withHeaders(Map.of(HttpHeader.AUTHORIZATION.toString(), "Bearer " + tokens.bearer.accessToken)) + .retry(false).syncSend(); + if (response.statusCode() != NO_CONTENT_204 && response.statusCode() != OK_200) { + logger.warn("Registering capabilities failed, HTTP/2 stream will not work"); + } + } catch (ConnectionException e) { + logger.warn("Registering capabilities failed, HTTP/2 stream will not work: {}", e.getMessage()); + } + tryGetBootstrap(); + this.loginData.setDeviceName(registerAppResponse.response.success.extensions.deviceInfo.deviceName); + + return true; } catch (Exception e) { + logger.warn("Registering as app failed: {}", e.getMessage()); logout(); - throw new ConnectionException(e.getMessage(), e); + return false; } - - this.loginData.deviceName = registerAppResponse.response.success.extensions.deviceInfo.deviceName; } - private void exchangeToken() throws ConnectionException { + private void exchangeToken(String cookieDomain) throws ConnectionException { this.connectionExpiryTime = 0; - String cookiesJson = "{\"cookies\":{\"." + getAmazonSite() + "\":[]}}"; + String cookiesJson = "{\"cookies\":{\"." + cookieDomain + "\":[]}}"; String cookiesBase64 = Base64.getEncoder().encodeToString(cookiesJson.getBytes()); String exchangePostData = "di.os.name=iOS" // + "&app_version=" + AmazonEchoControlBindingConstants.API_VERSION // + "&domain=." + getAmazonSite() // - + "&source_token=" + URLEncoder.encode(this.loginData.refreshToken, StandardCharsets.UTF_8) // + + "&source_token=" + URLEncoder.encode(this.loginData.getRefreshToken(), StandardCharsets.UTF_8) // + "&requested_token_type=auth_cookies" // + "&source_token_type=refresh_token" // + "&di.hw.version=iPhone" // @@ -457,8 +393,9 @@ public String getAccessToken() throws ConnectionException { /** * Check if tokens need to be renewed *

- * The {@link #accessToken} is renewed when the current time is above {@link #accessTokenExpiryTime}, additionally - * the session tokens/cookies are renewed when the current time is above {@link #connectionExpiryTime} + * The {@link #accessToken} is renewed when the current time is above + * {@link #accessTokenExpiryTime}, additionally the session tokens/cookies are renewed when the current time is + * above {@link #connectionExpiryTime} * * @return true when the session tokens have been renewed, false otherwise * @throws ConnectionException when an error occurred @@ -468,7 +405,7 @@ public boolean checkRenewSession() throws ConnectionException { String renewTokenPostData = "app_name=Amazon%20Alexa" // + "&app_version=" + AmazonEchoControlBindingConstants.API_VERSION // + "&di.sdk.version=" + AmazonEchoControlBindingConstants.DI_SDK_VERSION // - + "&source_token=" + URLEncoder.encode(loginData.refreshToken, StandardCharsets.UTF_8) // + + "&source_token=" + URLEncoder.encode(loginData.getRefreshToken(), StandardCharsets.UTF_8) // + "&package_name=com.amazon.echo" // + "&di.hw.version=iPhone" // + "&platform=iOS" // @@ -478,8 +415,8 @@ public boolean checkRenewSession() throws ConnectionException { + "&di.os.version=" + AmazonEchoControlBindingConstants.DI_OS_VERSION // + "¤t_version=6.12.4"; - JsonRenewTokenResponse tokenResponse = requestBuilder.post("https://api.amazon.com/auth/token") - .withContent(renewTokenPostData).syncSend(JsonRenewTokenResponse.class); + AuthTokenResponseTO tokenResponse = requestBuilder.post("https://api.amazon.com/auth/token") + .withContent(renewTokenPostData).syncSend(AuthTokenResponseTO.class); if (tokenResponse == null) { return false; @@ -494,32 +431,30 @@ public boolean checkRenewSession() throws ConnectionException { // renew at 80% expired accessTokenExpiryTime = System.currentTimeMillis() + (long) ((tokenResponse.expiresIn * 1000.0) / 0.8); - if (this.macDms == null) { - // if macDms is not set, this is a new connection we need to register it as app - registerConnectionAsApp(accessToken); - } else if (System.currentTimeMillis() > this.connectionExpiryTime) { - exchangeToken(); + if (System.currentTimeMillis() > this.connectionExpiryTime) { + exchangeToken(loginData.getRetailDomain()); } return true; } return false; } - public boolean getIsLoggedIn() { - return loginData.loginTime != null; + public boolean isLoggedIn() { + return loginData.getLoginTime() != null; } public String getLoginPage() throws ConnectionException { // clear session data logout(); - logger.debug("Start Login to {}", alexaServer); + logger.debug("Start Login to {}", getAlexaServer()); String mapMdJson = "{\"device_user_dictionary\":[],\"device_registration_data\":{\"software_version\":\"1\"},\"app_identifier\":{\"app_version\":\"2.2.443692\",\"bundle_id\":\"com.amazon.echo\"}}"; String mapMdCookie = Base64.getEncoder().encodeToString(mapMdJson.getBytes()); cookieManager.getCookieStore().add(URI.create("https://www.amazon.com"), new HttpCookie("map-md", mapMdCookie)); - cookieManager.getCookieStore().add(URI.create("https://www.amazon.com"), new HttpCookie("frc", loginData.frc)); + cookieManager.getCookieStore().add(URI.create("https://www.amazon.com"), + new HttpCookie("frc", loginData.getFrc())); String url = "https://www.amazon.com/ap/signin" // + "?openid.return_to=https://www.amazon.com/ap/maplanding" // @@ -530,7 +465,7 @@ public String getLoginPage() throws ConnectionException { + "&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select" // + "&openid.mode=checkid_setup" // + "&openid.ns.oa2=http://www.amazon.com/ap/ext/oauth/2" // - + "&openid.oa2.client_id=device:" + loginData.deviceId// + + "&openid.oa2.client_id=device:" + loginData.getDeviceId() // + "&openid.ns.pape=http://specs.openid.net/extensions/pape/1.0" // + "&openid.oa2.response_type=token" // + "&openid.ns=http://specs.openid.net/auth/2.0&openid.pape.max_auth_age=0" // @@ -543,18 +478,15 @@ public String getLoginPage() throws ConnectionException { } public boolean verifyLogin() throws ConnectionException { - if (this.loginData.refreshToken == null) { + if (this.loginData.getRefreshToken() == null || !tryGetBootstrap()) { + verifyTime = null; return false; } - Authentication authentication = tryGetBootstrap(); - if (authentication != null && authentication.authenticated) { - verifyTime = new Date(); - if (loginData.loginTime == null) { - loginData.loginTime = verifyTime; - } - return true; + verifyTime = new Date(); + if (loginData.getLoginTime() == null) { + loginData.setLoginTime(verifyTime); } - return false; + return true; } // current value in compute can be null @@ -570,8 +502,8 @@ private void replaceTimer(TimerType type, @Nullable ScheduledFuture newTimer) public void logout() { cookieManager.getCookieStore().removeAll(); // reset all members - loginData.refreshToken = null; - loginData.loginTime = null; + loginData.setRefreshToken(null); + loginData.setLoginTime(null); verifyTime = null; replaceTimer(TimerType.ANNOUNCEMENT, null); @@ -605,27 +537,20 @@ public void logout() { } // commands and states - public List getWakeWords() { + public List getWakeWords() { try { - JsonWakeWords wakeWords = requestBuilder.get(alexaServer + "/api/wake-word?cached=true") - .syncSend(JsonWakeWords.class); - if (wakeWords == null) { - return List.of(); - } - return wakeWords.wakeWords; + return requestBuilder.get(getAlexaServer() + "/api/wake-word?cached=true") + .syncSend(WakeWordResponseTO.class).wakeWords; } catch (ConnectionException e) { - logger.info("Getting wakewords failed", e); + logger.info("Getting wake words failed", e); } return List.of(); } public List getSmarthomeDeviceList() throws ConnectionException { try { - JsonNetworkDetails networkDetails = requestBuilder.get(alexaServer + "/api/phoenix") + JsonNetworkDetails networkDetails = requestBuilder.get(getAlexaServer() + "/api/phoenix") .syncSend(JsonNetworkDetails.class); - if (networkDetails == null) { - return List.of(); - } Object jsonObject = gson.fromJson(networkDetails.networkDetail, Object.class); List result = new ArrayList<>(); searchSmartHomeDevicesRecursive(jsonObject, result); @@ -660,15 +585,13 @@ private void searchSmartHomeDevicesRecursive(@Nullable Object jsonNode, List getDeviceList() throws ConnectionException { - JsonDevices devices = requestBuilder.get(alexaServer + "/api/devices-v2/device?cached=false") - .syncSend(JsonDevices.class); - logger.trace("Devices {}", devices.devices); - + public List getDeviceList() throws ConnectionException { + DeviceListResponseTO devices = requestBuilder.get(getAlexaServer() + "/api/devices-v2/device?cached=false") + .syncSend(DeviceListResponseTO.class); // @Nullable because of a limitation of the null-checker, we filter null-serialNumbers before Set<@Nullable String> serialNumbers = ConcurrentHashMap.newKeySet(); return devices.devices.stream().filter(d -> d.serialNumber != null && serialNumbers.add(d.serialNumber)) - .collect(Collectors.toList()); + .toList(); } public Map getSmartHomeDeviceStatesJson(Set devices) @@ -700,7 +623,7 @@ public Map getSmartHomeDeviceStatesJson(Set getSmartHomeDeviceStatesJson(Set r.timestamp)) + .toList(); } catch (ConnectionException e) { logger.info("getting activities failed", e); } return List.of(); } - public JsonBluetoothStates getBluetoothConnectionStates() { + public BluetoothStateResponseTO getBluetoothConnectionStates() { try { - JsonBluetoothStates bluetoothStates = requestBuilder.get(alexaServer + "/api/bluetooth?cached=true") - .syncSend(JsonBluetoothStates.class); - return Objects.requireNonNullElse(bluetoothStates, new JsonBluetoothStates()); + String url = getAlexaServer() + "/api/bluetooth?cached=true"; + return requestBuilder.get(url).syncSend(BluetoothStateResponseTO.class); } catch (ConnectionException e) { - logger.debug("failed to get bluetooth state: {}", e.getMessage()); - return new JsonBluetoothStates(); + logger.debug("Failed to get bluetooth state: {}", e.getMessage()); + return new BluetoothStateResponseTO(); } } - public @Nullable JsonPlaylists getPlaylists(Device device) throws ConnectionException { - String url = alexaServer + "/api/cloudplayer/playlists?deviceSerialNumber=" + device.serialNumber - + "&deviceType=" + device.deviceType + "&mediaOwnerCustomerId=" - + getCustomerId(device.deviceOwnerCustomerId); + public @Nullable JsonPlaylists getPlaylists(DeviceTO device) throws ConnectionException { + String url = getAlexaServer() + "/api/cloudplayer/playlists?deviceSerialNumber=" + device.serialNumber + + "&deviceType=" + device.deviceType + "&mediaOwnerCustomerId=" + loginData.getAccountCustomerId(); return requestBuilder.get(url).syncSend(JsonPlaylists.class); } - public void command(Device device, Object command) throws ConnectionException { - String url = alexaServer + "/api/np/command?deviceSerialNumber=" + device.serialNumber + "&deviceType=" + public void command(DeviceTO device, Object command) throws ConnectionException { + String url = getAlexaServer() + "/api/np/command?deviceSerialNumber=" + device.serialNumber + "&deviceType=" + device.deviceType; requestBuilder.post(url).withContent(command).retry(false).syncSend(); } public void smartHomeCommand(String entityId, String action, Map values) throws IOException, InterruptedException { - String url = alexaServer + "/api/phoenix/state"; + String url = getAlexaServer() + "/api/phoenix/state"; JsonObject json = new JsonObject(); JsonArray controlRequests = new JsonArray(); @@ -839,132 +760,116 @@ public void smartHomeCommand(String entityId, String action, Map } } - public void notificationVolume(Device device, int volume) throws ConnectionException { - String url = alexaServer + "/api/device-notification-state/" + device.deviceType + "/" + device.softwareVersion - + "/" + device.serialNumber; - Map command = Map.of("deviceSerialNumber", "" + device.serialNumber, // - "deviceType", "" + device.deviceType, // - "softwareVersion", "" + device.softwareVersion, // - "volumeLevel", volume); + public void setNotificationVolume(DeviceTO device, int volume) throws ConnectionException { + String url = getAlexaServer() + "/api/device-notification-state/" + device.deviceType + "/" + + device.softwareVersion + "/" + device.serialNumber; + NotificationStateTO command = new NotificationStateTO(); + command.deviceSerialNumber = device.serialNumber; + command.deviceType = device.deviceType; + command.deviceSerialNumber = device.softwareVersion; + command.volumeLevel = volume; requestBuilder.put(url).withContent(command).retry(false).syncSend(); } - public void ascendingAlarm(Device device, boolean ascendingAlarm) throws ConnectionException { - String url = alexaServer + "/api/ascending-alarm/" + device.serialNumber; - ToggleAscendingAlarmTO command = new ToggleAscendingAlarmTO(); + public void setAscendingAlarm(DeviceTO device, boolean ascendingAlarm) throws ConnectionException { + String url = getAlexaServer() + "/api/ascending-alarm/" + device.serialNumber; + AscendingAlarmTO command = new AscendingAlarmTO(); command.ascendingAlarmEnabled = ascendingAlarm; command.deviceSerialNumber = device.serialNumber; command.deviceType = device.deviceType; requestBuilder.put(url).withContent(command).retry(false).syncSend(); } - public void doNotDisturb(Device device, boolean doNotDisturb) throws ConnectionException { - String url = alexaServer + "/api/dnd/status"; - ToggleDoNotDisturbTO command = new ToggleDoNotDisturbTO(); + public void setDoNotDisturb(DeviceTO device, boolean doNotDisturb) throws ConnectionException { + String url = getAlexaServer() + "/api/dnd/status"; + DoNotDisturbDeviceStatusTO command = new DoNotDisturbDeviceStatusTO(); command.enabled = doNotDisturb; command.deviceSerialNumber = device.serialNumber; command.deviceType = device.deviceType; requestBuilder.put(url).withContent(command).retry(false).syncSend(); } - public List getDeviceNotificationStates() { + public List getDeviceNotificationStates() { try { - String json = requestBuilder.get(alexaServer + "/api/device-notification-state").syncSend(String.class); - JsonDeviceNotificationState result = parseJson(json, JsonDeviceNotificationState.class); - if (result == null) { - return List.of(); - } - return Objects.requireNonNullElse(result.deviceNotificationStates, List.of()); + return requestBuilder.get(getAlexaServer() + "/api/device-notification-state") + .syncSend(DeviceNotificationStateResponseTO.class).deviceNotificationStates; } catch (ConnectionException e) { logger.info("Error getting device notification states", e); } return List.of(); } - public List getAscendingAlarm() { + public List getAscendingAlarms() { try { - String json = requestBuilder.get(alexaServer + "/api/ascending-alarm").syncSend(String.class); - JsonAscendingAlarm result = parseJson(json, JsonAscendingAlarm.class); - if (result == null) { - return List.of(); - } - return Objects.requireNonNullElse(result.ascendingAlarmModelList, List.of()); + return requestBuilder.get(getAlexaServer() + "/api/ascending-alarm") + .syncSend(AscendingAlarmModelResponseTO.class).ascendingAlarmModelList; } catch (ConnectionException e) { logger.info("Error getting ascending alarm states", e); } return List.of(); } - public List getDoNotDisturb() { + public List getDoNotDisturbs() { try { - String json = requestBuilder.get(alexaServer + "/api/dnd/device-status-list").syncSend(String.class); - JsonDoNotDisturb result = parseJson(json, JsonDoNotDisturb.class); - if (result == null) { - return List.of(); - } - return Objects.requireNonNullElse(result.doNotDisturbDeviceStatusList, List.of()); + return requestBuilder.get(getAlexaServer() + "/api/dnd/device-status-list") + .syncSend(DoNotDisturbDeviceStatusResponseTO.class).doNotDisturbDeviceStatusList; } catch (ConnectionException e) { logger.info("Error getting do not disturb status list", e); } return List.of(); } - public void bluetooth(Device device, @Nullable String address) throws ConnectionException { + public void bluetooth(DeviceTO device, @Nullable String address) throws ConnectionException { if (address == null || address.isEmpty()) { - String url = alexaServer + "/api/bluetooth/disconnect-sink/" + device.deviceType + "/" + String url = getAlexaServer() + "/api/bluetooth/disconnect-sink/" + device.deviceType + "/" + device.serialNumber; // disconnect requestBuilder.post(url).retry(false).syncSend(); } else { - String url = alexaServer + "/api/bluetooth/pair-sink/" + device.deviceType + "/" + device.serialNumber; + String url = getAlexaServer() + "/api/bluetooth/pair-sink/" + device.deviceType + "/" + device.serialNumber; requestBuilder.post(url).withContent(Map.of("bluetoothDeviceAddress", address)).retry(false).syncSend(); } } - private @Nullable String getCustomerId(@Nullable String defaultId) { - String accountCustomerId = this.loginData.accountCustomerId; - return accountCustomerId == null || accountCustomerId.isEmpty() ? defaultId : accountCustomerId; - } - - public void playRadio(Device device, @Nullable String stationId) throws ConnectionException { + public void playRadio(DeviceTO device, @Nullable String stationId) throws ConnectionException { if (stationId == null || stationId.isEmpty()) { command(device, Map.of("type", "PauseCommand")); } else { String content = "[\"music/tuneIn/stationId\",\"" + stationId + "\"]|{\"previousPageId\":null}"; String contentToken = new String( Base64.getEncoder().encode(Base64.getEncoder().encode(content.getBytes(StandardCharsets.UTF_8)))); - String url = alexaServer + "/api/entertainment/v1/player/queue?deviceSerialNumber=" + device.serialNumber - + "&deviceType=" + device.deviceType; + String url = getAlexaServer() + "/api/entertainment/v1/player/queue?deviceSerialNumber=" + + device.serialNumber + "&deviceType=" + device.deviceType; requestBuilder.put(url).withContent(Map.of("contentToken", "music:" + contentToken)).retry(false) .syncSend(); } } - public void playAmazonMusicTrack(Device device, @Nullable String trackId) throws ConnectionException { + public void playAmazonMusicTrack(DeviceTO device, @Nullable String trackId) throws ConnectionException { if (trackId == null || trackId.isEmpty()) { command(device, Map.of("type", "PauseCommand")); } else { Map command = Map.of("trackId", trackId, "playQueuePrime", true); - String url = alexaServer + "/api/cloudplayer/queue-and-play?deviceSerialNumber=" + device.serialNumber - + "&deviceType=" + device.deviceType + "&mediaOwnerCustomerId=" - + getCustomerId(device.deviceOwnerCustomerId) + "&shuffle=false"; + String url = getAlexaServer() + "/api/cloudplayer/queue-and-play?deviceSerialNumber=" + device.serialNumber + + "&deviceType=" + device.deviceType + "&mediaOwnerCustomerId=" + loginData.getAccountCustomerId() + + "&shuffle=false"; requestBuilder.post(url).withContent(command).retry(false).syncSend(); } } - public void playAmazonMusicPlayList(Device device, @Nullable String playListId) throws ConnectionException { + public void playAmazonMusicPlayList(DeviceTO device, @Nullable String playListId) throws ConnectionException { if (playListId == null || playListId.isEmpty()) { command(device, Map.of("type", "PauseCommand")); } else { Map command = Map.of("playlistId", playListId, "playQueuePrime", true); - String url = alexaServer + "/api/cloudplayer/queue-and-play?deviceSerialNumber=" + device.serialNumber - + "&deviceType=" + device.deviceType + "&mediaOwnerCustomerId=" - + getCustomerId(device.deviceOwnerCustomerId) + "&shuffle=false"; + String url = getAlexaServer() + "/api/cloudplayer/queue-and-play?deviceSerialNumber=" + device.serialNumber + + "&deviceType=" + device.deviceType + "&mediaOwnerCustomerId=" + loginData.getAccountCustomerId() + + "&shuffle=false"; requestBuilder.post(url).withContent(command).retry(false).syncSend(); } } - public void announcement(Device device, String speak, String bodyText, @Nullable String title, + public void announcement(DeviceTO device, String speak, String bodyText, @Nullable String title, @Nullable Integer ttsVolume, @Nullable Integer standardVolume) { String trimmedSpeak = speak.replaceAll("\\s+", " ").trim(); String trimmedBodyText = bodyText.replaceAll("\\s+", " ").trim(); @@ -1002,19 +907,16 @@ private void sendAnnouncement() { while (iterator.hasNext()) { AnnouncementWrapper announcement = iterator.next(); try { - List devices = announcement.getDevices(); + List devices = announcement.getDevices(); if (!devices.isEmpty()) { - JsonAnnouncementContent content = new JsonAnnouncementContent(announcement); + AnnouncementTO content = announcement.toAnnouncementTO(); Map parameters = new HashMap<>(); parameters.put("expireAfter", "PT5S"); - parameters.put("content", new JsonAnnouncementContent[] { content }); + parameters.put("content", List.of(content)); parameters.put("target", new JsonAnnouncementTarget(devices)); + parameters.put("customerId", loginData.getAccountCustomerId()); - String customerId = getCustomerId(devices.get(0).deviceOwnerCustomerId); - if (customerId != null) { - parameters.put("customerId", customerId); - } executeSequenceCommandWithVolume(devices, "AlexaAnnouncement", parameters, announcement.getTtsVolumes(), announcement.getStandardVolumes()); } @@ -1030,7 +932,7 @@ private void sendAnnouncement() { } } - public void textToSpeech(Device device, String text, @Nullable Integer ttsVolume, + public void textToSpeech(DeviceTO device, String text, @Nullable Integer ttsVolume, @Nullable Integer standardVolume) { String trimmedText = text.replaceAll("\\s+", " ").trim(); String plainText = trimmedText.replaceAll("<.+?>", "").trim(); @@ -1064,7 +966,7 @@ private void sendTextToSpeech() { while (iterator.hasNext()) { TextWrapper textToSpeech = iterator.next(); try { - List devices = textToSpeech.getDevices(); + List devices = textToSpeech.getDevices(); if (!devices.isEmpty()) { executeSequenceCommandWithVolume(devices, "Alexa.Speak", Map.of("textToSpeak", textToSpeech.getText()), textToSpeech.getTtsVolumes(), @@ -1082,7 +984,8 @@ private void sendTextToSpeech() { } } - public void textCommand(Device device, String text, @Nullable Integer ttsVolume, @Nullable Integer standardVolume) { + public void textCommand(DeviceTO device, String text, @Nullable Integer ttsVolume, + @Nullable Integer standardVolume) { String trimmedText = text.replaceAll("\\s+", " ").trim(); String plainText = trimmedText.replaceAll("<.+?>", "").trim(); if (plainText.isEmpty()) { @@ -1116,7 +1019,7 @@ private synchronized void sendTextCommand() { while (iterator.hasNext()) { TextWrapper textCommand = iterator.next(); try { - List devices = textCommand.getDevices(); + List devices = textCommand.getDevices(); if (!devices.isEmpty()) { executeSequenceCommandWithVolume(devices, "Alexa.TextCommand", Map.of("text", textCommand.getText()), textCommand.getTtsVolumes(), @@ -1134,7 +1037,7 @@ private synchronized void sendTextCommand() { } } - public void volume(Device device, int vol) { + public void setVolume(DeviceTO device, int vol) { // we lock volume until we have finished adding this one Lock lock = Objects.requireNonNull(locks.computeIfAbsent(TimerType.VOLUME, k -> new ReentrantLock())); lock.lock(); @@ -1159,7 +1062,7 @@ private void sendVolume() { while (iterator.hasNext()) { Volume volume = iterator.next(); try { - List devices = volume.devices; + List devices = volume.devices; if (!devices.isEmpty()) { executeSequenceCommandWithVolume(devices, null, Map.of(), volume.volumes, List.of()); } @@ -1175,7 +1078,7 @@ private void sendVolume() { } } - private void executeSequenceCommandWithVolume(List devices, @Nullable String command, + private void executeSequenceCommandWithVolume(List devices, @Nullable String command, Map parameters, List<@Nullable Integer> ttsVolumes, List<@Nullable Integer> standardVolumes) { JsonArray serialNodesToExecute = new JsonArray(); @@ -1199,7 +1102,7 @@ private void executeSequenceCommandWithVolume(List devices, @Nullable St if (command != null && !parameters.isEmpty()) { JsonArray commandNodesToExecute = new JsonArray(); if ("Alexa.Speak".equals(command) || "Alexa.TextCommand".equals(command)) { - for (Device device : devices) { + for (DeviceTO device : devices) { commandNodesToExecute.add(createExecutionNode(device, command, parameters)); } } else { @@ -1241,17 +1144,17 @@ private void executeSequenceCommandWithVolume(List devices, @Nullable St // commands: Alexa.Weather.Play, Alexa.Traffic.Play, Alexa.FlashBriefing.Play, // Alexa.GoodMorning.Play, // Alexa.SingASong.Play, Alexa.TellStory.Play, Alexa.Speak (textToSpeach) - public void executeSequenceCommand(Device device, String command, Map parameters) { + public void executeSequenceCommand(DeviceTO device, String command, Map parameters) { JsonObject nodeToExecute = createExecutionNode(device, command, parameters); executeSequenceNode(List.of(device), nodeToExecute); } - private void executeSequenceNode(List devices, JsonObject nodeToExecute) { + private void executeSequenceNode(List devices, JsonObject nodeToExecute) { QueueObject queueObject = new QueueObject(); queueObject.devices = devices; queueObject.nodeToExecute = nodeToExecute; List serials = new ArrayList<>(); - for (Device device : devices) { + for (DeviceTO device : devices) { String serialNumber = device.serialNumber; if (serialNumber != null) { Objects.requireNonNull(this.devices.computeIfAbsent(serialNumber, k -> new LinkedBlockingQueue<>())) @@ -1275,9 +1178,8 @@ private void handleExecuteSequenceNode() { if (future == null || future.isDone()) { boolean execute = true; List serials = new ArrayList<>(); - for (Device tmpDevice : queueObject.devices) { - String tmpSerialNumber = tmpDevice.serialNumber; - if (tmpSerialNumber != null && !serialNumber.equals(tmpSerialNumber)) { + for (DeviceTO tmpDevice : queueObject.devices) { + if (Objects.equals(tmpDevice.serialNumber, serialNumber)) { LinkedBlockingQueue tmpQueueObjects = devices .get(tmpDevice.serialNumber); if (tmpQueueObjects != null) { @@ -1292,7 +1194,7 @@ private void handleExecuteSequenceNode() { break; } - serials.add(tmpSerialNumber); + serials.add(tmpDevice.serialNumber); } } } @@ -1330,7 +1232,7 @@ private void queuedExecuteSequenceNode(QueueObject queueObject) { text = text.replaceAll("<.+?>", " ").replaceAll("\\s+", " ").trim(); delay += text.length() * 150L; } - requestBuilder.post(alexaServer + "/api/behaviors/preview").withContent(request).syncSend(); + requestBuilder.post(getAlexaServer() + "/api/behaviors/preview").withContent(request).syncSend(); Thread.sleep(delay); } catch (ConnectionException | InterruptedException e) { @@ -1342,7 +1244,7 @@ private void queuedExecuteSequenceNode(QueueObject queueObject) { private void removeObjectFromQueueAfterExecutionCompletion(QueueObject queueObject) { List serials = new ArrayList<>(); - for (Device device : queueObject.devices) { + for (DeviceTO device : queueObject.devices) { String serialNumber = device.serialNumber; if (serialNumber != null) { LinkedBlockingQueue queue = devices.get(serialNumber); @@ -1355,7 +1257,7 @@ private void removeObjectFromQueueAfterExecutionCompletion(QueueObject queueObje logger.debug("Removed {} device(s) {} from queue", queueObject.hashCode(), serials); } - private void executeSequenceNodes(List devices, JsonArray nodesToExecute, boolean parallel) { + private void executeSequenceNodes(List devices, JsonArray nodesToExecute, boolean parallel) { JsonObject serialNode = new JsonObject(); if (parallel) { serialNode.addProperty("@type", "com.amazon.alexa.behaviors.model.ParallelNode"); @@ -1368,13 +1270,13 @@ private void executeSequenceNodes(List devices, JsonArray nodesToExecute executeSequenceNode(devices, serialNode); } - private JsonObject createExecutionNode(@Nullable Device device, String command, Map parameters) { + private JsonObject createExecutionNode(@Nullable DeviceTO device, String command, Map parameters) { JsonObject operationPayload = new JsonObject(); if (device != null) { operationPayload.addProperty("deviceType", device.deviceType); operationPayload.addProperty("deviceSerialNumber", device.serialNumber); operationPayload.addProperty("locale", ""); - operationPayload.addProperty("customerId", getCustomerId(device.deviceOwnerCustomerId)); + operationPayload.addProperty("customerId", loginData.getAccountCustomerId()); } for (String key : parameters.keySet()) { Object value = parameters.get(key); @@ -1463,7 +1365,7 @@ private boolean processNodesToExecuteJsonObject(ExecutionNodeObject executionNod return false; } - public void startRoutine(Device device, String utterance) throws ConnectionException { + public void startRoutine(DeviceTO device, String utterance) throws ConnectionException { JsonAutomation found = null; String deviceLocale = ""; List routines = getRoutines(); @@ -1477,7 +1379,7 @@ public void startRoutine(Device device, String utterance) throws ConnectionExcep continue; } String payloadUtterance = payload.utterance; - if (payloadUtterance != null && payloadUtterance.equalsIgnoreCase(utterance)) { + if (utterance.equalsIgnoreCase(payloadUtterance)) { found = routine; deviceLocale = payload.locale; break; @@ -1504,7 +1406,7 @@ public void startRoutine(Device device, String utterance) throws ConnectionExcep // "customerId": "ALEXA_CUSTOMER_ID" String customerId = "\"customerId\":\"ALEXA_CUSTOMER_ID\""; - String newCustomerId = "\"customerId\":\"" + getCustomerId(device.deviceOwnerCustomerId) + "\""; + String newCustomerId = "\"customerId\":\"" + loginData.getAccountCustomerId() + "\""; sequenceJson = sequenceJson.replace(customerId, newCustomerId); // "locale": "ALEXA_CURRENT_LOCALE" @@ -1515,53 +1417,54 @@ public void startRoutine(Device device, String utterance) throws ConnectionExcep request.sequenceJson = sequenceJson; - requestBuilder.post(alexaServer + "/api/behaviors/preview").withContent(request).syncSend(); + requestBuilder.post(getAlexaServer() + "/api/behaviors/preview").withContent(request).syncSend(); } else { logger.warn("Routine {} not found", utterance); } } public List getRoutines() throws ConnectionException { - JsonAutomation[] result = requestBuilder.get(alexaServer + "/api/behaviors/v2/automations?limit=2000") + JsonAutomation[] result = requestBuilder.get(getAlexaServer() + "/api/behaviors/v2/automations?limit=2000") .syncSend(JsonAutomation[].class); - return result == null ? List.of() : Arrays.asList(result); + return Arrays.asList(result); } - public List getEnabledFlashBriefings() throws ConnectionException { - JsonEnabledFeeds result = requestBuilder.get(alexaServer + "/api/content-skills/enabled-feeds") - .syncSend(JsonEnabledFeeds.class); - return result == null ? List.of() : result.enabledFeeds; + public List getEnabledFlashBriefings() { + try { + return requestBuilder.get(getAlexaServer() + "/api/content-skills/enabled-feeds") + .syncSend(EnabledFeedsTO.class).enabledFeeds; + } catch (ConnectionException e) { + logger.warn("Failed to get enabled feeds: {}", e.getMessage()); + } + return List.of(); } - public void setEnabledFlashBriefings(List enabledFlashBriefing) throws ConnectionException { - JsonEnabledFeeds enabled = new JsonEnabledFeeds(); + public void setEnabledFlashBriefings(List enabledFlashBriefing) throws ConnectionException { + EnabledFeedsTO enabled = new EnabledFeedsTO(); enabled.enabledFeeds = enabledFlashBriefing; - requestBuilder.post(alexaServer + "/api/content-skills/enabled-feeds").withContent(enabled).retry(false) + requestBuilder.post(getAlexaServer() + "/api/content-skills/enabled-feeds").withContent(enabled).retry(false) .syncSend(); } - public List getNotificationSounds(Device device) throws ConnectionException { - JsonNotificationSounds result = requestBuilder - .get(alexaServer + "/api/notification/sounds?deviceSerialNumber=" + device.serialNumber + "&deviceType=" - + device.deviceType + "&softwareVersion=" + device.softwareVersion) - .syncSend(JsonNotificationSounds.class); - if (result == null) { - return List.of(); - } - return Objects.requireNonNullElse(result.notificationSounds, List.of()); + public List getNotificationSounds(DeviceTO device) throws ConnectionException { + return requestBuilder + .get(getAlexaServer() + "/api/notification/sounds?deviceSerialNumber=" + device.serialNumber + + "&deviceType=" + device.deviceType + "&softwareVersion=" + device.softwareVersion) + .syncSend(NotificationSoundResponseTO.class).notificationSounds; } - public List notifications() throws ConnectionException { - JsonNotificationsResponse result = requestBuilder.get(alexaServer + "/api/notifications") - .syncSend(JsonNotificationsResponse.class); - if (result == null) { - return List.of(); + public List getNotifications() { + try { + return requestBuilder.get(getAlexaServer() + "/api/notifications") + .syncSend(NotificationListResponseTO.class).notifications; + } catch (ConnectionException e) { + logger.warn("Failed to get notifications: {}", e.getMessage()); } - return Objects.requireNonNullElse(result.notifications, List.of()); + return List.of(); } - public @Nullable JsonNotificationResponse notification(Device device, String type, @Nullable String label, - @Nullable JsonNotificationSound sound) throws ConnectionException { + public @Nullable NotificationTO notification(DeviceTO device, String type, @Nullable String label, + @Nullable NotificationSoundTO sound) throws ConnectionException { Date date = new Date(new Date().getTime()); long createdDate = date.getTime(); Date alarm = new Date(createdDate + 5000); // add 5 seconds, because amazon does not accept calls for times in @@ -1581,36 +1484,39 @@ public List notifications() throws ConnectionException request.type = type; request.id = "create" + type; - String url = alexaServer + "/api/notifications/createReminder"; - return requestBuilder.put(url).withContent(request).syncSend(JsonNotificationResponse.class); + String url = getAlexaServer() + "/api/notifications/createReminder"; + return requestBuilder.put(url).withContent(request).syncSend(NotificationTO.class); } - public void stopNotification(JsonNotificationResponse notification) throws ConnectionException { - requestBuilder.delete(alexaServer + "/api/notifications/" + notification.id).syncSend(); + public void deleteNotification(String notificationId) { + try { + requestBuilder.delete(getAlexaServer() + "/api/notifications/" + notificationId).syncSend(); + } catch (ConnectionException e) { + logger.warn("Failed to delete notification {}: {}", notificationId, e.getMessage()); + } } - public @Nullable JsonNotificationResponse getNotificationState(JsonNotificationResponse notification) - throws ConnectionException { - return requestBuilder.get(alexaServer + "/api/notifications/" + notification.id) - .syncSend(JsonNotificationResponse.class); + public NotificationTO getNotificationState(String notificationId) throws ConnectionException { + return requestBuilder.get(getAlexaServer() + "/api/notifications/" + notificationId) + .syncSend(NotificationTO.class); } - public List getMusicProviders() { + public List getMusicProviders() { try { - JsonMusicProvider[] musicProviders = requestBuilder - .get(alexaServer + "/api/behaviors/entities?skillId=amzn1.ask.1p.music") - .withHeader("Routines-Version", "1.1.218665").syncSend(JsonMusicProvider[].class); - return Arrays.asList(Objects.requireNonNullElse(musicProviders, new JsonMusicProvider[] {})); + MusicProviderTO[] musicProviders = requestBuilder + .get(getAlexaServer() + "/api/behaviors/entities?skillId=amzn1.ask.1p.music") + .withHeader("Routines-Version", "1.1.218665").syncSend(MusicProviderTO[].class); + return Arrays.asList(musicProviders); } catch (ConnectionException e) { - logger.warn("getMusicProviders fails: {}", e.getMessage()); + logger.warn("Failed to get music providers: {}", e.getMessage()); } return List.of(); } - public void playMusicVoiceCommand(Device device, String providerId, String voiceCommand) + public void playMusicVoiceCommand(DeviceTO device, String providerId, String voiceCommand) throws ConnectionException { JsonPlaySearchPhraseOperationPayload payload = new JsonPlaySearchPhraseOperationPayload(); - payload.customerId = getCustomerId(device.deviceOwnerCustomerId); + payload.customerId = loginData.getAccountCustomerId(); payload.locale = "ALEXA_CURRENT_LOCALE"; payload.musicProviderId = providerId; payload.searchPhrase = voiceCommand; @@ -1622,7 +1528,7 @@ public void playMusicVoiceCommand(Device device, String providerId, String voice postValidationJson.addProperty("type", "Alexa.Music.PlaySearchPhrase"); postValidationJson.addProperty("operationPayload", playloadString); - String validateResultJson = requestBuilder.post(alexaServer + "/api/behaviors/operation/validate") + String validateResultJson = requestBuilder.post(getAlexaServer() + "/api/behaviors/operation/validate") .withContent(postValidationJson).syncSend(String.class); if (!validateResultJson.isEmpty()) { @@ -1652,27 +1558,27 @@ public void playMusicVoiceCommand(Device device, String providerId, String voice startRoutineRequest.sequenceJson = sequenceJson.toString(); startRoutineRequest.status = null; - requestBuilder.post(alexaServer + "/api/behaviors/preview").withContent(startRoutineRequest).syncSend(); + requestBuilder.post(getAlexaServer() + "/api/behaviors/preview").withContent(startRoutineRequest).syncSend(); } - public @Nullable JsonEqualizer getEqualizer(Device device) throws ConnectionException { - return requestBuilder.get(alexaServer + "/api/equalizer/" + device.serialNumber + "/" + device.deviceType) - .syncSend(JsonEqualizer.class); + public EqualizerTO getEqualizer(DeviceTO device) throws ConnectionException { + return requestBuilder.get(getAlexaServer() + "/api/equalizer/" + device.serialNumber + "/" + device.deviceType) + .syncSend(EqualizerTO.class); } - public void setEqualizer(Device device, JsonEqualizer settings) throws ConnectionException { - requestBuilder.post(alexaServer + "/api/equalizer/" + device.serialNumber + "/" + device.deviceType) + public void setEqualizer(DeviceTO device, EqualizerTO settings) throws ConnectionException { + requestBuilder.post(getAlexaServer() + "/api/equalizer/" + device.serialNumber + "/" + device.deviceType) .withContent(settings).retry(false).syncSend(); } private static class Volume { - public List devices = new ArrayList<>(); + public List devices = new ArrayList<>(); public List<@Nullable Integer> volumes = new ArrayList<>(); } private static class QueueObject { public @Nullable Future future; - public List devices = List.of(); + public List devices = List.of(); public JsonObject nodeToExecute = new JsonObject(); } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/LoginData.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/LoginData.java index 11d12c2042..1f93e87653 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/LoginData.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/LoginData.java @@ -41,14 +41,17 @@ public class LoginData { private final CookieManager cookieManager; // data fields - public String frc; - public String serial; - public String deviceId; - public @Nullable String refreshToken; - public String amazonSite = "amazon.com"; - public String deviceName = "Unknown"; - public @Nullable String accountCustomerId; - public @Nullable Date loginTime; + private String frc; + private String serial; + private String deviceId; + private @Nullable String refreshToken; + private String retailDomain = "amazon.com"; + private String retailUrl = "https://www.amazon.com"; + private String websiteApiUrl = "https://alexa.amazon.com"; + + private String deviceName = "Unknown"; + private String accountCustomerId = ""; + private @Nullable Date loginTime; private List cookies = new ArrayList<>(); public LoginData(CookieManager cookieManager, String deviceId, String frc, String serial) { @@ -78,18 +81,100 @@ public LoginData(CookieManager cookieManager) { this.deviceId = HexUtils.bytesToHex(hexStr.getBytes()); } + public String getFrc() { + return frc; + } + + public String getSerial() { + return serial; + } + + public String getDeviceId() { + return deviceId; + } + + public @Nullable String getRefreshToken() { + return refreshToken; + } + + public String getRetailDomain() { + return retailDomain; + } + + public String getRetailUrl() { + return retailUrl; + } + + public String getWebsiteApiUrl() { + return websiteApiUrl; + } + + public String getDeviceName() { + return deviceName; + } + + public String getAccountCustomerId() { + return accountCustomerId; + } + + public @Nullable Date getLoginTime() { + return loginTime; + } + + public void setFrc(String frc) { + this.frc = frc; + } + + public void setSerial(String serial) { + this.serial = serial; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public void setRefreshToken(@Nullable String refreshToken) { + this.refreshToken = refreshToken; + } + + public void setRetailDomain(String retailDomain) { + this.retailDomain = retailDomain; + } + + public void setRetailUrl(String retailUrl) { + this.retailUrl = retailUrl; + } + + public void setWebsiteApiUrl(String websiteApiUrl) { + this.websiteApiUrl = websiteApiUrl; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public void setAccountCustomerId(String accountCustomerId) { + this.accountCustomerId = accountCustomerId; + } + + public void setLoginTime(@Nullable Date loginTime) { + this.loginTime = loginTime; + } + public String serializeLoginData() { Date loginTime = this.loginTime; if (refreshToken == null || loginTime == null) { return ""; } StringBuilder builder = new StringBuilder(); - builder.append("7\n"); // version + builder.append("8\n"); // version builder.append(frc).append("\n"); builder.append(serial).append("\n"); builder.append(deviceId).append("\n"); builder.append(refreshToken).append("\n"); - builder.append(amazonSite).append("\n"); + builder.append(retailDomain).append("\n"); + builder.append(retailUrl).append("\n"); + builder.append(websiteApiUrl).append("\n"); builder.append(deviceName).append("\n"); builder.append(accountCustomerId).append("\n"); builder.append(loginTime.getTime()).append("\n"); @@ -104,7 +189,7 @@ public boolean deserialize(String data) { Scanner scanner = new Scanner(data); String version = scanner.nextLine(); // check if serialize version is supported - if (!"7".equals(version)) { + if (!"7".equals(version) && !"8".equals(version)) { scanner.close(); return false; } @@ -114,7 +199,11 @@ public boolean deserialize(String data) { deviceId = scanner.nextLine(); refreshToken = scanner.nextLine(); - amazonSite = scanner.nextLine(); + retailDomain = scanner.nextLine(); + if ("8".equals(version)) { + retailUrl = scanner.nextLine(); + websiteApiUrl = scanner.nextLine(); + } deviceName = scanner.nextLine(); accountCustomerId = scanner.nextLine(); loginTime = new Date(Long.parseLong(scanner.nextLine())); diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/TextWrapper.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/TextWrapper.java index af145afa77..8149b4a890 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/TextWrapper.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/connection/TextWrapper.java @@ -17,7 +17,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; /** * The {@link TextWrapper} is a wrapper class for text or TTS instructions @@ -26,7 +26,7 @@ */ @NonNullByDefault public class TextWrapper { - private final List devices = new ArrayList<>(); + private final List devices = new ArrayList<>(); private final String text; private final List<@Nullable Integer> ttsVolumes = new ArrayList<>(); private final List<@Nullable Integer> standardVolumes = new ArrayList<>(); @@ -35,13 +35,13 @@ public TextWrapper(String text) { this.text = text; } - public void add(JsonDevices.Device device, @Nullable Integer ttsVolume, @Nullable Integer standardVolume) { + public void add(DeviceTO device, @Nullable Integer ttsVolume, @Nullable Integer standardVolume) { devices.add(device); ttsVolumes.add(ttsVolume); standardVolumes.add(standardVolume); } - public List getDevices() { + public List getDevices() { return devices; } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java index c8d36676b9..418d49854a 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java @@ -38,7 +38,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; import org.smarthomej.binding.amazonechocontrol.internal.handler.AccountHandler; /** @@ -93,7 +93,7 @@ protected void startScan() { } setDevices(accountHandler.updateDeviceList()); - String currentFlashBriefingConfiguration = accountHandler.getNewCurrentFlashbriefingConfiguration(); + String currentFlashBriefingConfiguration = accountHandler.updateFlashBriefingHandlers(); discoverFlashBriefingProfiles(currentFlashBriefingConfiguration); } @@ -153,12 +153,12 @@ public void activate(@Nullable Map config) { } } - private synchronized void setDevices(List deviceList) { + private synchronized void setDevices(List deviceList) { AccountHandler accountHandler = this.accountHandler; if (accountHandler == null) { return; } - for (Device device : deviceList) { + for (DeviceTO device : deviceList) { String serialNumber = device.serialNumber; if (serialNumber != null) { String deviceFamily = device.deviceFamily; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/discovery/SmartHomeDevicesDiscovery.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/discovery/SmartHomeDevicesDiscovery.java index 033ded8a41..294ca395ec 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/discovery/SmartHomeDevicesDiscovery.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/discovery/SmartHomeDevicesDiscovery.java @@ -33,11 +33,11 @@ import org.openhab.core.thing.binding.ThingHandlerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice.DriverIdentity; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDeviceAlias; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeGroups.SmartHomeGroup; -import org.smarthomej.binding.amazonechocontrol.internal.dto.SmartHomeBaseDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice.DriverIdentity; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDeviceAlias; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeGroups.SmartHomeGroup; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.SmartHomeBaseDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.AccountHandler; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import org.smarthomej.binding.amazonechocontrol.internal.smarthome.Constants; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/ToggleAscendingAlarmTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/AscendingAlarmTO.java similarity index 57% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/ToggleAscendingAlarmTO.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/AscendingAlarmTO.java index 8e74df7290..bf9e0f378a 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/ToggleAscendingAlarmTO.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/AscendingAlarmTO.java @@ -10,19 +10,26 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto.request; +package org.smarthomej.binding.amazonechocontrol.internal.dto; +import org.eclipse.jdt.annotation.NonNull; import org.smarthomej.binding.amazonechocontrol.internal.util.SerializeNull; /** - * The {@link ToggleAscendingAlarmTO} encapsulates a command to enable/disable ascending alarms on a device + * The {@link AscendingAlarmTO} encapsulates the ascending alarm status of a device * * @author Jan N. Klug - Initial contribution */ -public class ToggleAscendingAlarmTO { +public class AscendingAlarmTO { public boolean ascendingAlarmEnabled; public String deviceSerialNumber; public String deviceType; @SerializeNull public Object deviceAccountId = null; + + @Override + public @NonNull String toString() { + return "AscendingAlarmTO{ascendingAlarmEnabled=" + ascendingAlarmEnabled + ", deviceSerialNumber='" + + deviceSerialNumber + "', deviceType='" + deviceType + "', deviceAccountId=" + deviceAccountId + "}"; + } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/BluetoothPairedDeviceTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/BluetoothPairedDeviceTO.java new file mode 100644 index 0000000000..814b46fac9 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/BluetoothPairedDeviceTO.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.BluetoothStateTO; + +/** + * The {@link BluetoothPairedDeviceTO} encapsulate a part of {@link BluetoothStateTO} + * + * @author Jan N. Klug - Initial contribution + */ +public class BluetoothPairedDeviceTO { + public String address; + public boolean connected; + public String deviceClass; + public String friendlyName; + public List profiles = List.of(); + + @Override + public @NonNull String toString() { + return "BluetoothPairedDeviceTO{address='" + address + "', connected=" + connected + ", deviceClass='" + + deviceClass + "', friendlyName='" + friendlyName + "', profiles=" + profiles + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DeviceNotificationStateTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DeviceNotificationStateTO.java new file mode 100644 index 0000000000..de6a3acb57 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DeviceNotificationStateTO.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link DeviceNotificationStateTO} encapsulates a command to enable/disable ascending alarms on a device + * + * @author Jan N. Klug - Initial contribution + */ +public class DeviceNotificationStateTO { + public String deviceSerialNumber; + public String deviceType; + public String softwareVersion; + public int volumeLevel; + + @Override + public @NonNull String toString() { + return "DeviceNotificationStateTO{deviceSerialNumber='" + deviceSerialNumber + "', deviceType='" + deviceType + + "', softwareVersion='" + softwareVersion + "', volumeLevel=" + volumeLevel + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DeviceTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DeviceTO.java new file mode 100644 index 0000000000..723ae94e0a --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DeviceTO.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; + +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link DeviceTO} encapsulate information about a single device + * + * @author Jan N. Klug - Initial contribution + */ +public class DeviceTO { + public String accountName; + public String serialNumber; + public String deviceOwnerCustomerId; + public String deviceAccountId; + public String deviceFamily; + public String deviceType; + public String softwareVersion; + public boolean online; + public Set capabilities = Set.of(); + + @Override + public @NonNull String toString() { + return "Device{accountName='" + accountName + "', serialNumber='" + serialNumber + "', deviceOwnerCustomerId='" + + deviceOwnerCustomerId + "', deviceAccountId='" + deviceAccountId + "', deviceFamily='" + deviceFamily + + "', deviceType='" + deviceType + "', softwareVersion='" + softwareVersion + "', online=" + online + + ", capabilities=" + capabilities + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DoNotDisturbDeviceStatusTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DoNotDisturbDeviceStatusTO.java new file mode 100644 index 0000000000..ad75c41ab3 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DoNotDisturbDeviceStatusTO.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; + +import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.util.SerializeNull; + +/** + * The {@link DoNotDisturbDeviceStatusTO} encapsulates a command to enable/disable ascending alarms on a device + * + * @author Jan N. Klug - Initial contribution + */ +public class DoNotDisturbDeviceStatusTO { + public boolean enabled; + public String deviceSerialNumber; + public String deviceType; + @SerializeNull + public Object deviceAccountId = null; + + @Override + public @NonNull String toString() { + return "DoNotDisturbDeviceStatusTO{enabled=" + enabled + ", deviceSerialNumber='" + deviceSerialNumber + + "', deviceType='" + deviceType + "', deviceAccountId=" + deviceAccountId + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonEnabledFeeds.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/EnabledFeedsTO.java similarity index 59% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonEnabledFeeds.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/EnabledFeedsTO.java index 5d310afd70..6618f23bcc 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonEnabledFeeds.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/EnabledFeedsTO.java @@ -15,14 +15,18 @@ import java.util.List; -import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.NonNull; /** - * The {@link JsonEnabledFeeds} encapsulate the GSON data of the enabled feeds list + * The {@link EnabledFeedsTO} encapsulate the data for handling enabled feeds * - * @author Michael Geramb - Initial contribution + * @author Jan N. Klug - Initial contribution */ -@NonNullByDefault -public class JsonEnabledFeeds { - public List enabledFeeds = List.of(); +public class EnabledFeedsTO { + public List enabledFeeds = List.of(); + + @Override + public @NonNull String toString() { + return "EnabledFeedsTO{enabledFeeds=" + enabledFeeds + "}"; + } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonColorTemperature.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/EqualizerTO.java similarity index 53% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonColorTemperature.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/EqualizerTO.java index 6179ebed0c..e1f97fa628 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonColorTemperature.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/EqualizerTO.java @@ -1,5 +1,4 @@ /** - * Copyright (c) 2010-2021 Contributors to the openHAB project * Copyright (c) 2021-2023 Contributors to the SmartHome/J project * * See the NOTICE file(s) distributed with this work for additional @@ -13,17 +12,20 @@ */ package org.smarthomej.binding.amazonechocontrol.internal.dto; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jdt.annotation.NonNull; /** - * @author Lukas Knoeller - Initial contribution + * The {@link EqualizerTO} encapsulate an equalizer command/response + * + * @author Jan N. Klug - Initial contribution */ -@NonNullByDefault -public class JsonColorTemperature { - public @Nullable String temperatureName; +public class EqualizerTO { + public int bass = 0; + public int mid = 0; + public int treble = 0; - public JsonColorTemperature(String temperature) { - temperatureName = temperature; + @Override + public @NonNull String toString() { + return "JsonEqualizer{bass=" + bass + ", mid=" + mid + ", treble=" + treble + "}"; } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonColors.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/FeedTO.java similarity index 50% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonColors.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/FeedTO.java index 431a5b482b..2a02aa4eac 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonColors.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/FeedTO.java @@ -1,5 +1,4 @@ /** - * Copyright (c) 2010-2021 Contributors to the openHAB project * Copyright (c) 2021-2023 Contributors to the SmartHome/J project * * See the NOTICE file(s) distributed with this work for additional @@ -13,17 +12,22 @@ */ package org.smarthomej.binding.amazonechocontrol.internal.dto; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jdt.annotation.NonNull; /** - * @author Lukas Knoeller - Initial contribution + * The {@link FeedTO} encapsulate a single feed + * + * @author Jan N. Klug - Initial contribution */ -@NonNullByDefault -public class JsonColors { - public @Nullable String colorName; +public class FeedTO { + public Object feedId; + public String name; + public String skillId; + public String imageUrl; - public JsonColors(String colorName) { - this.colorName = colorName; + @Override + public @NonNull String toString() { + return "FeedTO{feedId=" + feedId + ", name='" + name + "', skillId='" + skillId + "', imageUrl='" + imageUrl + + "'}"; } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonActivities.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonActivities.java deleted file mode 100644 index 96c5584bcc..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonActivities.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; -import java.util.Objects; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; - -/** - * The {@link JsonActivities} encapsulate the GSON data of the push command for push activity - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonActivities { - - public @Nullable List activities; - - public static class Activity { - public @Nullable String activityStatus; - public @Nullable Long creationTimestamp; - public @Nullable String description; - public @Nullable Object domainAttributes; - public @Nullable Object domainType; - public @Nullable Object feedbackAttributes; - public @Nullable String id; - public @Nullable String intentType; - public @Nullable String providerInfoDescription; - public @Nullable String registeredCustomerId; - public @Nullable Object sourceActiveUsers; - public @Nullable List sourceDeviceIds; - public @Nullable String utteranceId; - public @Nullable Long version; - - public List getSourceDeviceIds() { - return Objects.requireNonNullElse(sourceDeviceIds, List.of()); - } - - public static class SourceDeviceId { - public @Nullable String deviceAccountId; - public @Nullable String deviceType; - public @Nullable String serialNumber; - } - - public static class Description { - public @Nullable String summary; - public @Nullable String firstUtteranceId; - public @Nullable String firstStreamId; - } - - public Description parseDescription() { - String description = this.description; - if (description == null || description.isEmpty() || !description.startsWith("{") - || !description.endsWith("}")) { - return new Description(); - } - Gson gson = new Gson(); - try { - Description description1 = gson.fromJson(description, Description.class); - return description1 != null ? description1 : new Description(); - } catch (JsonSyntaxException e) { - return new Description(); - } - } - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonAnnouncementContent.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonAnnouncementContent.java deleted file mode 100644 index ea7233e45a..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonAnnouncementContent.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.smarthomej.binding.amazonechocontrol.internal.connection.AnnouncementWrapper; - -/** - * The {@link JsonAnnouncementContent} encapsulate the GSON data of the sequence command AlexaAnnouncement for sending - * announcements - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonAnnouncementContent { - public String locale = ""; - public Display display; - public Speak speak; - - public JsonAnnouncementContent(AnnouncementWrapper announcement) { - display = new Display(announcement.getBodyText(), announcement.getTitle()); - speak = new Speak(announcement.getSpeak()); - } - - public static class Display { - public String title; - public String body; - - public Display(String body, @Nullable String title) { - this.body = body; - this.title = (title == null || title.isEmpty() ? "openHAB" : title); - } - } - - public static class Speak { - public String type; - public String value; - - public Speak(String speakText) { - type = (speakText.startsWith("") && speakText.endsWith("")) ? "ssml" : "text"; - value = speakText; - } - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonAnnouncementTarget.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonAnnouncementTarget.java index 9aa2f095ab..55bf59e8f4 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonAnnouncementTarget.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonAnnouncementTarget.java @@ -31,7 +31,7 @@ public class JsonAnnouncementTarget { public @Nullable String customerId; public List devices; - public JsonAnnouncementTarget(List deviceList) { + public JsonAnnouncementTarget(List deviceList) { customerId = deviceList.get(0).deviceOwnerCustomerId; devices = deviceList.stream().map(TargetDevice::new).collect(Collectors.toList()); } @@ -40,7 +40,7 @@ public static class TargetDevice { public @Nullable String deviceSerialNumber; public @Nullable String deviceTypeId; - public TargetDevice(JsonDevices.Device device) { + public TargetDevice(DeviceTO device) { deviceSerialNumber = device.serialNumber; deviceTypeId = device.deviceType; } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonAscendingAlarm.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonAscendingAlarm.java deleted file mode 100644 index c5fd088ca2..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonAscendingAlarm.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonAscendingAlarm} encapsulate the GSON data of the /api/ascending-alarm response - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonAscendingAlarm { - - public @Nullable List ascendingAlarmModelList; - - public static class AscendingAlarmModel { - public @Nullable Boolean ascendingAlarmEnabled; - public @Nullable String deviceSerialNumber; - public @Nullable String deviceType; - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonBluetoothStates.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonBluetoothStates.java deleted file mode 100644 index fb845715fd..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonBluetoothStates.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; -import java.util.Objects; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; - -/** - * The {@link JsonBluetoothStates} encapsulate the GSON data of bluetooth state - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonBluetoothStates { - - public @Nullable BluetoothState findStateByDevice(@Nullable Device device) { - if (device == null) { - return null; - } - @Nullable - BluetoothState @Nullable [] bluetoothStates = this.bluetoothStates; - if (bluetoothStates == null) { - return null; - } - for (BluetoothState state : bluetoothStates) { - if (state != null && Objects.equals(state.deviceSerialNumber, device.serialNumber)) { - return state; - } - } - return null; - } - - public BluetoothState @Nullable [] bluetoothStates; - - public static class PairedDevice { - public @Nullable String address; - public boolean connected; - public @Nullable String deviceClass; - public @Nullable String friendlyName; - public @Nullable List profiles; - } - - public static class BluetoothState { - public @Nullable String deviceSerialNumber; - public @Nullable String deviceType; - public @Nullable String friendlyName; - public boolean gadgetPaired; - public boolean online; - public @Nullable List pairedDeviceList; - - public List getPairedDeviceList() { - return Objects.requireNonNullElse(pairedDeviceList, List.of()); - } - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonCustomerHistoryRecords.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonCustomerHistoryRecords.java deleted file mode 100644 index 6b01bf4f58..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonCustomerHistoryRecords.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; -import java.util.Objects; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonCustomerHistoryRecords} encapsulate the GSON data of the push command for push customer history record - * - * @author Tom Blum - Initial contribution - */ -@NonNullByDefault -public class JsonCustomerHistoryRecords { - - public List customerHistoryRecords = List.of(); - - public static class CustomerHistoryRecord { - public @Nullable String recordKey; - public @Nullable String recordType; - public @Nullable Long timestamp; - public @Nullable String customerId; - public @Nullable Object device; - public @Nullable Boolean isBinaryFeedbackProvided; - public @Nullable Boolean isFeedbackPositive; - public @Nullable String utteranceType; - public @Nullable String domain; - public @Nullable String intent; - public @Nullable String skillName; - public List voiceHistoryRecordItems = List.of(); - public @Nullable List personsInfo; - - public static class VoiceHistoryRecordItem { - public @Nullable String recordItemKey; - public @Nullable String recordItemType; - public @Nullable String utteranceId; - public @Nullable Long timestamp; - public @Nullable String transcriptText; - public @Nullable String agentVisualName; - public @Nullable List personsInfo; - } - - public long getTimestamp() { - return Objects.requireNonNullElse(timestamp, 0L); - } - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonDeviceNotificationState.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonDeviceNotificationState.java deleted file mode 100644 index dda8863146..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonDeviceNotificationState.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonDeviceNotificationState} encapsulate the GSON data of the /api/device-notification-state response - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonDeviceNotificationState { - - public @Nullable List deviceNotificationStates; - - public static class DeviceNotificationState { - public @Nullable String deviceSerialNumber; - public @Nullable String deviceType; - public @Nullable String softwareVersion; - public @Nullable Integer volumeLevel; - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonDevices.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonDevices.java deleted file mode 100644 index 3816750d8f..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonDevices.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonDevices} encapsulate the GSON data of device list - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonDevices { - - public static class Device { - public @Nullable String accountName; - public @Nullable String serialNumber; - public @Nullable String deviceOwnerCustomerId; - public @Nullable String deviceAccountId; - public @Nullable String deviceFamily; - public @Nullable String deviceType; - public @Nullable String softwareVersion; - public boolean online; - public @Nullable Set capabilities; - - public Set getCapabilities() { - return Objects.requireNonNullElse(capabilities, Set.of()); - } - - @Override - public String toString() { - return "Device{" + "accountName='" + accountName + '\'' + ", serialNumber='" + serialNumber + '\'' - + ", deviceOwnerCustomerId='" + deviceOwnerCustomerId + '\'' + ", deviceAccountId='" - + deviceAccountId + '\'' + ", deviceFamily='" + deviceFamily + '\'' + ", deviceType='" + deviceType - + '\'' + ", softwareVersion='" + softwareVersion + '\'' + ", online=" + online + ", capabilities=" - + capabilities + '}'; - } - } - - public List devices = List.of(); -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonDoNotDisturb.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonDoNotDisturb.java deleted file mode 100644 index 886478d5b9..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonDoNotDisturb.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonDoNotDisturb} encapsulate the GSON data of the /api/dnd/device-status-list response - * - * @author Cody Cutrer - Initial contribution - */ -@NonNullByDefault -public class JsonDoNotDisturb { - - public @Nullable List doNotDisturbDeviceStatusList; - - public static class DoNotDisturbDeviceStatus { - public @Nullable Boolean enabled; - public @Nullable String deviceSerialNumber; - public @Nullable String deviceType; - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonEqualizer.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonEqualizer.java deleted file mode 100644 index dc91fc68a9..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonEqualizer.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonEqualizer} encapsulate the GSON data of the get equalizer command - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonEqualizer { - public @Nullable Integer bass = 0; - public @Nullable Integer mid = 0; - public @Nullable Integer treble = 0; - - public JsonEqualizer createClone() { - JsonEqualizer result = new JsonEqualizer(); - result.bass = this.bass; - result.mid = this.mid; - result.treble = this.treble; - return result; - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonFeed.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonFeed.java deleted file mode 100644 index 6b23f8d7ce..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonFeed.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonFeed} encapsulate the GSON data of feed - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonFeed { - public @Nullable Object feedId; - public @Nullable String name; - public @Nullable String skillId; - public @Nullable String imageUrl; - - public JsonFeed(@Nullable Object feedId, @Nullable String skillId) { - this.feedId = feedId; - this.skillId = skillId; - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonMusicProvider.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonMusicProvider.java deleted file mode 100644 index 85a6e4424a..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonMusicProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonMusicProvider} encapsulate the GSON returned for a music provider - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonMusicProvider { - public @Nullable String displayName; - public List @Nullable [] supportedTriggers; - public @Nullable String icon; - public @Nullable List supportedProperties; - public @Nullable String id; - public @Nullable String availability; - public @Nullable String description; -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationRequest.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationRequest.java index f8169de661..b9769bcd01 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationRequest.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationRequest.java @@ -30,7 +30,7 @@ public class JsonNotificationRequest { public @Nullable String originalDate; public @Nullable String timeZoneId; public @Nullable String reminderIndex; - public @Nullable JsonNotificationSound sound; + public @Nullable NotificationSoundTO sound; public @Nullable String deviceSerialNumber; public @Nullable String deviceType; public @Nullable String recurringPattern; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationResponse.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationResponse.java deleted file mode 100644 index 944eb509aa..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationResponse.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonNotificationResponse} encapsulate the GSON data for the result of a notification request - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonNotificationResponse { - // This is only a partial definition, see the example JSON below - public long alarmTime; - public long createdDate; - public @Nullable String deviceSerialNumber; - public @Nullable String deviceType; - public @Nullable String id; - public @Nullable String status; - public @Nullable String type; - public long remainingTime; - public @Nullable String recurringPattern; - public @Nullable String originalDate; - public @Nullable String originalTime; -} - -/* - * Example JSON: - * { - *    "alarmTime":1518864868060, - *    "createdDate":1518864863801, - *    "deviceSerialNumber":"XXXXXXXXXX", - *    "deviceType":"XXXXXXXXXX", - *    "id":"XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX", - *    "musicAlarmId":null, - *    "musicEntity":null, - *    "notificationIndex":"XXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX", - *    "originalDate":null, - *    "originalTime":"11:54:28.060", - *    "provider":null, - *    "recurringPattern":null, - *    "remainingTime":0, - *    "reminderLabel":null, - *    "sound":{ - *       "displayName":"Clarity", - *       "folder":null, - *       "id":"system_alerts_melodic_05", - *       "providerId":"ECHO", - *       "sampleUrl":"https://s3.amazonaws.com/deeappservice.prod.notificationtones/system_alerts_melodic_05.mp3" - *    }, - *    "status":"OFF", - *    "timeZoneId":null, - *    "timerLabel":null, - *    "triggerTime":0, - *    "type":"Alarm", - *    "version":"2", - *    "alarmIndex":null, - *    "isSaveInFlight":true - * } - * - */ diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationSound.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationSound.java deleted file mode 100644 index 183e228946..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationSound.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonNotificationSound} encapsulate the GSON data for a notification sound - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonNotificationSound { - public @Nullable String displayName; - public @Nullable String folder; - public @Nullable String id = "system_alerts_melodic_01"; - public @Nullable String providerId = "ECHO"; - public @Nullable String sampleUrl; -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationsResponse.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationsResponse.java deleted file mode 100644 index d6d5f29b32..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationsResponse.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonNotificationsResponse} encapsulate the GSON data for the result of a notifications request - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonNotificationsResponse { - public @Nullable List notifications; -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonRegisterAppRequest.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonRegisterAppRequest.java deleted file mode 100644 index fa29bdd1de..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonRegisterAppRequest.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -import com.google.gson.annotations.SerializedName; - -/** - * The {@link JsonRegisterAppRequest} encapsulate the GSON data of register application request - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonRegisterAppRequest { - - public JsonRegisterAppRequest(String serial, @Nullable String accessToken, String frc, - List webSiteCookies) { - registrationData.deviceSerial = serial; - authData.accessToken = accessToken; - userContextMap.frc = frc; - cookies.webSiteCookies = webSiteCookies; - } - - @SerializedName("requested_extensions") - public String[] requestedExtensions = { "device_info", "customer_info" }; - - public Cookies cookies = new Cookies(); - @SerializedName("registration_data") - public RegistrationData registrationData = new RegistrationData(); - @SerializedName("auth_data") - public AuthData authData = new AuthData(); - @SerializedName("user_context_map") - public UserContextMap userContextMap = new UserContextMap(); - @SerializedName("requested_token_type") - public String[] requestedTokenType = { "bearer", "mac_dms", "website_cookies" }; - - public static class Cookies { - @SerializedName("website_cookies") - public List webSiteCookies = List.of(); - public @Nullable String domain = ".amazon.com"; - } - - public static class RegistrationData { - public String domain = "Device"; - @SerializedName("app_version") - public String appVersion = "2.2.223830.0"; - @SerializedName("device_type") - public String deviceType = "A2IVLV5VM2W81"; - @SerializedName("device_name") - public String deviceName = "%FIRST_NAME%'s%DUPE_STRATEGY_1ST%openHAB Alexa Binding"; - @SerializedName("os_version") - public String osVersion = "11.4.1"; - @SerializedName("device_serial") - public @Nullable String deviceSerial; - @SerializedName("device_model") - public String deviceModel = "iPhone"; - @SerializedName("app_name") - public String appName = "openHAB Alexa Binding"; - @SerializedName("software_version") - public String softwareVersion = "1"; - } - - public static class AuthData { - @SerializedName("access_token") - public @Nullable String accessToken; - } - - public static class UserContextMap { - public String frc = ""; - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonRegisterAppResponse.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonRegisterAppResponse.java deleted file mode 100644 index 657d794045..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonRegisterAppResponse.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -import com.google.gson.annotations.SerializedName; - -/** - * The {@link JsonRegisterAppResponse} encapsulate the GSON data of response from the register command - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonRegisterAppResponse { - - public Response response = new Response(); - - @SerializedName("request_id") - public @Nullable String requestId; - - public static class Response { - public Success success = new Success(); - } - - public static class Success { - public Extensions extensions = new Extensions(); - - public Tokens tokens = new Tokens(); - - @SerializedName("customer_id") - public @Nullable String customerId; - } - - public static class Extensions { - @SerializedName("device_info") - public DeviceInfo deviceInfo = new DeviceInfo(); - - @SerializedName("customer_info") - public CustomerInfo customerInfo = new CustomerInfo(); - - @SerializedName("customer_id") - public @Nullable String customerId; - } - - public static class DeviceInfo { - @SerializedName("device_name") - public String deviceName = "Unknown"; - - @SerializedName("device_serial_number") - public @Nullable String deviceSerialNumber; - - @SerializedName("device_type") - public @Nullable String deviceType; - } - - public static class CustomerInfo { - @SerializedName("account_pool") - public @Nullable String accountPool; - - @SerializedName("user_id") - public @Nullable String userId; - - @SerializedName("home_region") - public @Nullable String homeRegion; - - public @Nullable String name; - - @SerializedName("given_name") - public @Nullable String givenName; - } - - public static class Tokens { - @SerializedName("website_cookies") - public @Nullable Object websiteCookies; - - @SerializedName("mac_dms") - public MacDms macDms = new MacDms(); - - public Bearer bearer = new Bearer(); - } - - public static class MacDms { - @SerializedName("device_private_key") - public @Nullable String devicePrivateKey; - - @SerializedName("adp_token") - public @Nullable String adpToken; - } - - public static class Bearer { - @SerializedName("access_token") - public @Nullable String accessToken; - - @SerializedName("refresh_token") - public @Nullable String refreshToken; - - @SerializedName("expires_in") - public @Nullable String expiresIn; - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonRenewTokenResponse.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonRenewTokenResponse.java deleted file mode 100644 index 859133c952..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonRenewTokenResponse.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -import com.google.gson.annotations.SerializedName; - -/** - * The {@link JsonRenewTokenResponse} encapsulate the GSON response of the renew token request - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonRenewTokenResponse { - @SerializedName("access_token") - public @Nullable String accessToken; - @SerializedName("token_type") - public @Nullable String tokenType; - @SerializedName("expires_in") - public long expiresIn = 0; -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonUsersMeResponse.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonUsersMeResponse.java deleted file mode 100644 index e80591dcfa..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonUsersMeResponse.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonUsersMeResponse} encapsulate the GSON data of the users me response - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonUsersMeResponse { - public @Nullable String countryOfResidence; - public @Nullable String effectiveMarketPlaceId; - public @Nullable String email; - public @Nullable Boolean eulaAcceptance; - public @Nullable List features; - public @Nullable String fullName; - public @Nullable Boolean hasActiveDopplers; - public @Nullable String id; - public @Nullable String marketPlaceDomainName; - public @Nullable String marketPlaceId; - public @Nullable String marketPlaceLocale; -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonWakeWords.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonWakeWords.java deleted file mode 100644 index db0eb19728..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonWakeWords.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * The {@link JsonWakeWords} encapsulate the GSON data of the wake word request - * - * @author Michael Geramb - Initial contribution - */ -@NonNullByDefault -public class JsonWakeWords { - public List wakeWords = List.of(); - - public static class WakeWord { - public @Nullable Boolean active; - public @Nullable String deviceSerialNumber; - public @Nullable String deviceType; - public @Nullable Object midFieldState; - public @Nullable String wakeWord; - } -} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonBootstrapResult.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/NotificationSoundTO.java similarity index 50% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonBootstrapResult.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/NotificationSoundTO.java index 9864fccf13..de2feb8cb1 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonBootstrapResult.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/NotificationSoundTO.java @@ -13,24 +13,23 @@ */ package org.smarthomej.binding.amazonechocontrol.internal.dto; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jdt.annotation.NonNull; /** - * The {@link JsonBluetoothStates} encapsulate the bootstrap result + * The {@link NotificationSoundTO} encapsulate a notification sound * * @author Michael Geramb - Initial contribution */ -@NonNullByDefault -public class JsonBootstrapResult { +public class NotificationSoundTO { + public String displayName; + public String folder; + public String id = "system_alerts_melodic_01"; + public String providerId = "ECHO"; + public String sampleUrl; - public @Nullable Authentication authentication; - - public static class Authentication { - public boolean authenticated; - public @Nullable Boolean canAccessPrimeMusicContent; - public @Nullable String customerEmail; - public @Nullable String customerId; - public @Nullable String customerName; + @Override + public @NonNull String toString() { + return "NotificationSoundTO{displayName='" + displayName + "', folder='" + folder + "', id='" + id + + "', providerId='" + providerId + "', sampleUrl='" + sampleUrl + "'}"; } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/NotificationStateTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/NotificationStateTO.java new file mode 100644 index 0000000000..9ebb42c5f9 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/NotificationStateTO.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link NotificationStateTO} encapsulates the request to set notification states + * + * @author Jan N. Klug - Initial contribution + */ +public class NotificationStateTO { + public String deviceSerialNumber; + public String deviceType; + public String softwareVersion; + public int volumeLevel; + + @Override + public @NonNull String toString() { + return "NotificationStateTO{deviceSerialNumber='" + deviceSerialNumber + "', deviceType='" + deviceType + + "', softwareVersion='" + softwareVersion + "', volumeLevel=" + volumeLevel + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/NotificationTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/NotificationTO.java new file mode 100644 index 0000000000..84d609ce80 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/NotificationTO.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link NotificationTO} encapsulate a single notification + * + * @author Jan N. Klug - Initial contribution + */ +public class NotificationTO { + public long alarmTime; + public long createdDate; + public String deviceSerialNumber; + public String deviceType; + public String id; + public Object musicAlarmId; + public Object musicEntity; + public String notificationIndex; + public String originalDate; + public String originalTime; + public Object provider; + public String recurringPattern; + public long remainingTime; + public String reminderLabel; + public NotificationSoundTO sound = new NotificationSoundTO(); + public String status; + public String timeZoneId; + public String timerLabel; + public long triggerTime; + public String type; + public String version; + public Object alarmIndex; + public boolean isSaveInFlight; + + @Override + public @NonNull String toString() { + return "NotificationResponseTO{alarmTime=" + alarmTime + ", createdDate=" + createdDate + + ", deviceSerialNumber='" + deviceSerialNumber + "', deviceType='" + deviceType + "', id='" + id + + "', musicAlarmId=" + musicAlarmId + ", musicEntity=" + musicEntity + ", notificationIndex='" + + notificationIndex + "', originalDate='" + originalDate + "', originalTime='" + originalTime + + "', provider=" + provider + ", recurringPattern='" + recurringPattern + "', remainingTime=" + + remainingTime + ", reminderLabel='" + reminderLabel + "', sound=" + sound + ", status='" + status + + "', timeZoneId='" + timeZoneId + "', timerLabel='" + timerLabel + "', triggerTime=" + triggerTime + + ", type='" + type + "', version='" + version + "', alarmIndex=" + alarmIndex + ", isSaveInFlight=" + + isSaveInFlight + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/ToggleDoNotDisturbTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementDisplayTO.java similarity index 57% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/ToggleDoNotDisturbTO.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementDisplayTO.java index 7d3fdca07c..29cb6a22db 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/ToggleDoNotDisturbTO.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementDisplayTO.java @@ -12,17 +12,19 @@ */ package org.smarthomej.binding.amazonechocontrol.internal.dto.request; -import org.smarthomej.binding.amazonechocontrol.internal.util.SerializeNull; +import org.eclipse.jdt.annotation.NonNull; /** - * The {@link ToggleDoNotDisturbTO} encapsulates a command to enable/disable ascending alarms on a device - * + * The {@link AnnouncementDisplayTO} encapsulates the display part of an announcement + * * @author Jan N. Klug - Initial contribution */ -public class ToggleDoNotDisturbTO { - public boolean enabled; - public String deviceSerialNumber; - public String deviceType; - @SerializeNull - public Object deviceAccountId = null; +public class AnnouncementDisplayTO { + public String title; + public String body; + + @Override + public @NonNull String toString() { + return "AnnouncementDisplayTO{title='" + title + "', body='" + body + "'}"; + } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementSpeakTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementSpeakTO.java new file mode 100644 index 0000000000..36b0e43399 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementSpeakTO.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.request; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link AnnouncementSpeakTO} encapsulates the speak part of an announcement + * + * @author Jan N. Klug - Initial contribution + */ +public class AnnouncementSpeakTO { + public String type; + public String value; + + @Override + public @NonNull String toString() { + return "AnnouncementSpeakTO{type='" + type + "', value='" + value + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementTO.java new file mode 100644 index 0000000000..2cf38ec8a7 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementTO.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.request; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link AnnouncementTO} encapsulate a single announcement + * announcements + * + * @author Jan N. Klug - Initial contribution + */ +public class AnnouncementTO { + public String locale = ""; + public AnnouncementDisplayTO display = new AnnouncementDisplayTO(); + public AnnouncementSpeakTO speak = new AnnouncementSpeakTO(); + + @Override + public @NonNull String toString() { + return "AnnouncementTO{locale='" + locale + "'" + ", display=" + display + ", speak=" + speak + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonTokenResponse.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AuthDataTO.java similarity index 53% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonTokenResponse.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AuthDataTO.java index ec3c2e45cd..8a5ad0f03b 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonTokenResponse.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AuthDataTO.java @@ -1,5 +1,4 @@ /** - * Copyright (c) 2010-2021 Contributors to the openHAB project * Copyright (c) 2021-2023 Contributors to the SmartHome/J project * * See the NOTICE file(s) distributed with this work for additional @@ -11,24 +10,24 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.request; -import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import com.google.gson.annotations.SerializedName; /** - * The {@link JsonTokenResponse} encapsulate the GSON data of the token response + * The {@link AuthDataTO} encapsulates the auth information of an app registration request * - * @author Michael Geramb - Initial contribution + * @author Jan N. Klug - Initial contribution */ -@NonNullByDefault -public class JsonTokenResponse { +public class AuthDataTO { @SerializedName("access_token") public @Nullable String accessToken; - @SerializedName("token_type") - public @Nullable String tokenType; - @SerializedName("expires_in") - public @Nullable Integer expiresIn; + + @Override + public @NonNull String toString() { + return "AuthDataTO{accessToken='" + accessToken + "'}"; + } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/CookiesTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/CookiesTO.java new file mode 100644 index 0000000000..ceb72427b7 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/CookiesTO.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.request; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link CookiesTO} encapsulates the cookie information for a given domain + * + * @author Jan N. Klug - Initial contribution + */ +public class CookiesTO { + @SerializedName("website_cookies") + public List webSiteCookies = List.of(); + public String domain = ".amazon.com"; + + @Override + public @NonNull String toString() { + return "CookiesTO{webSiteCookies=" + webSiteCookies + ", domain='" + domain + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/PlayerSeekMediaTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/PlayerSeekMediaTO.java index cd0139d35a..41cb7b46d3 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/PlayerSeekMediaTO.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/PlayerSeekMediaTO.java @@ -12,6 +12,7 @@ */ package org.smarthomej.binding.amazonechocontrol.internal.dto.request; +import org.eclipse.jdt.annotation.NonNull; import org.smarthomej.binding.amazonechocontrol.internal.util.SerializeNull; /** @@ -24,4 +25,10 @@ public class PlayerSeekMediaTO { public long mediaPosition; @SerializeNull public Object contentFocusClientId = null; + + @Override + public @NonNull String toString() { + return "PlayerSeekMediaTO{type='" + type + "', mediaPosition=" + mediaPosition + ", contentFocusClientId=" + + contentFocusClientId + "}"; + } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/RegisterAppRequestTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/RegisterAppRequestTO.java new file mode 100644 index 0000000000..af1fc659d0 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/RegisterAppRequestTO.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.request; + +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNull; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link RegisterAppRequestTO} encapsulate the app registration request + * + * @author Jan N. Klug - Initial contribution + */ +public class RegisterAppRequestTO { + @SerializedName("requested_extensions") + public List requestedExtensions = List.of("device_info", "customer_info"); + public CookiesTO cookies = new CookiesTO(); + @SerializedName("registration_data") + public RegistrationDataTO registrationData = new RegistrationDataTO(); + @SerializedName("auth_data") + public AuthDataTO authData = new AuthDataTO(); + @SerializedName("user_context_map") + public Map userContextMap = Map.of(); + @SerializedName("requested_token_type") + public List requestedTokenType = List.of("bearer", "mac_dms", "website_cookies"); + + @Override + public @NonNull String toString() { + return "RegisterAppRequestTO{requestedExtensions=" + requestedExtensions + ", cookies=" + cookies + + ", registrationData=" + registrationData + ", authData=" + authData + ", userContextMap=" + + userContextMap + ", requestedTokenType=" + requestedTokenType + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/RegistrationDataTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/RegistrationDataTO.java new file mode 100644 index 0000000000..d7697cf1fb --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/RegistrationDataTO.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.request; + +import static org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.API_VERSION; +import static org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.DI_OS_VERSION; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link RegistrationDataTO} encapsulates the registration data for an app registration request + * + * @author Jan N. Klug - Initial contribution + */ +public class RegistrationDataTO { + public String domain = "Device"; + @SerializedName("app_version") + public String appVersion = API_VERSION; + @SerializedName("device_type") + public String deviceType = "A2IVLV5VM2W81"; + @SerializedName("device_name") + public String deviceName = "%FIRST_NAME%'s%DUPE_STRATEGY_1ST%openHAB Alexa Binding"; + @SerializedName("os_version") + public String osVersion = DI_OS_VERSION; + @SerializedName("device_serial") + public @Nullable String deviceSerial; + @SerializedName("device_model") + public String deviceModel = "iPhone"; + @SerializedName("app_name") + public String appName = "openHAB Alexa Binding"; + @SerializedName("software_version") + public String softwareVersion = "1"; + + @Override + public @NonNull String toString() { + return "RegistrationDataTO{domain='" + domain + "', appVersion='" + appVersion + "', deviceType='" + deviceType + + "', deviceName='" + deviceName + "', osVersion='" + osVersion + "', deviceSerial='" + deviceSerial + + "', deviceModel='" + deviceModel + "', appName='" + appName + "', softwareVersion='" + softwareVersion + + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/WHAVolumeLevelTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/WHAVolumeLevelTO.java index dac18781d9..074b86d5bd 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/WHAVolumeLevelTO.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/WHAVolumeLevelTO.java @@ -12,8 +12,10 @@ */ package org.smarthomej.binding.amazonechocontrol.internal.dto.request; +import org.eclipse.jdt.annotation.NonNull; + /** - * The {@link WHAVolumeLevelTO} encapsulates a command toset the WHA volume + * The {@link WHAVolumeLevelTO} encapsulates a command to set the WHA volume * * @author Jan N. Klug - Initial contribution */ @@ -21,4 +23,10 @@ public class WHAVolumeLevelTO { public String type = "VolumeLevelCommand"; public int volumeLevel; public Object contentFocusClientId = "Default"; + + @Override + public @NonNull String toString() { + return "WHAVolumeLevelTO{type='" + type + "', volumeLevel=" + volumeLevel + ", contentFocusClientId=" + + contentFocusClientId + "}"; + } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonWebSiteCookie.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/WebSiteCookieTO.java similarity index 56% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonWebSiteCookie.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/WebSiteCookieTO.java index 5bd79dad89..67541bf731 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonWebSiteCookie.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/WebSiteCookieTO.java @@ -11,27 +11,25 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.request; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jdt.annotation.NonNull; import com.google.gson.annotations.SerializedName; /** - * The {@link JsonWebSiteCookie} encapsulate the GSON data of register cookie array + * The {@link WebSiteCookieTO} encapsulate a website cookie * * @author Michael Geramb - Initial contribution */ -@NonNullByDefault -public class JsonWebSiteCookie { - public JsonWebSiteCookie(String name, String value) { - this.name = name; - this.value = value; - } - +public class WebSiteCookieTO { @SerializedName("Value") - public @Nullable String value; + public String value; @SerializedName("Name") - public @Nullable String name; + public String name; + + @Override + public @NonNull String toString() { + return "WebSiteCookieTO{value='" + value + "', name='" + name + "'}"; + } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/AscendingAlarmModelResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/AscendingAlarmModelResponseTO.java new file mode 100644 index 0000000000..9d5efd6d89 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/AscendingAlarmModelResponseTO.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.dto.AscendingAlarmTO; + +/** + * The {@link AscendingAlarmModelResponseTO} encapsulates the response of the /api/ascending-alarm + * + * @author Jan N. Klug - Initial contribution + */ +public class AscendingAlarmModelResponseTO { + public List ascendingAlarmModelList = List.of(); + + @Override + public @NonNull String toString() { + return "AscendingAlarmModelResponseTO{ascendingAlarmModelList=" + ascendingAlarmModelList + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/AuthTokenResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/AuthTokenResponseTO.java new file mode 100644 index 0000000000..3bc037843a --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/AuthTokenResponseTO.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link AuthTokenResponseTO} encapsulates the response of a request to /auth/token + * + * @author Jan N. Klug - Initial contribution + */ +public class AuthTokenResponseTO { + @SerializedName("access_token") + public String accessToken; + @SerializedName("token_type") + public String tokenType; + @SerializedName("expires_in") + public long expiresIn; + + @Override + public @NonNull String toString() { + return "AuthTokenResponseTO{accessToken='" + accessToken + "', tokenType='" + tokenType + "', expiresIn=" + + expiresIn + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/AuthenticationTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/AuthenticationTO.java new file mode 100644 index 0000000000..02c2b1d231 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/AuthenticationTO.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link AuthenticationTO} encapsulates the authentication information of a bootstrap response + * + * @author Jan N. Klug - Initial contribution + */ +public class AuthenticationTO { + public boolean authenticated; + public Boolean canAccessPrimeMusicContent; + public String customerEmail; + public String customerId; + public String customerName; + + @Override + public @NonNull String toString() { + return "AuthenticationTO{authenticated=" + authenticated + ", canAccessPrimeMusicContent=" + + canAccessPrimeMusicContent + ", customerEmail='" + customerEmail + "', customerId='" + customerId + + "', customerName='" + customerName + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BearerTokenTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BearerTokenTO.java new file mode 100644 index 0000000000..b30da69eb8 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BearerTokenTO.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link BearerTokenTO} encapsulates the bearer token information + * + * @author Jan N. Klug - Initial contribution + */ +public class BearerTokenTO { + @SerializedName("access_token") + public String accessToken; + + @SerializedName("refresh_token") + public String refreshToken; + + @SerializedName("expires_in") + public String expiresIn; + + @Override + public @NonNull String toString() { + return "BearerTO{accessToken='" + accessToken + "', refreshToken='" + refreshToken + "', expiresIn='" + + expiresIn + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BluetoothStateResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BluetoothStateResponseTO.java new file mode 100644 index 0000000000..4d7211a2c2 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BluetoothStateResponseTO.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link BluetoothStateResponseTO} encapsulate the response of /api/bluetooth + * + * @author Jan N. Klug - Initial contribution + */ +public class BluetoothStateResponseTO { + public List bluetoothStates = List.of(); + + @Override + public @NonNull String toString() { + return "BluetoothStateResponseTO{bluetoothStates=" + bluetoothStates + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BluetoothStateTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BluetoothStateTO.java new file mode 100644 index 0000000000..e95c5bdf32 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BluetoothStateTO.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.dto.BluetoothPairedDeviceTO; + +/** + * The {@link BluetoothStateTO} encapsulate a single bluetoth state + * + * @author Jan N. Klug - Initial contribution + */ +public class BluetoothStateTO { + public String deviceSerialNumber; + public String deviceType; + public String friendlyName; + public boolean gadgetPaired; + public boolean online; + public List pairedDeviceList = List.of(); + + @Override + public @NonNull String toString() { + return "BluetoothStateTO{deviceSerialNumber='" + deviceSerialNumber + "', deviceType='" + deviceType + + "', friendlyName='" + friendlyName + "', gadgetPaired=" + gadgetPaired + ", online=" + online + + ", pairedDeviceList=" + pairedDeviceList + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BootstrapResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BootstrapResponseTO.java new file mode 100644 index 0000000000..8c7b60ff70 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/BootstrapResponseTO.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link BootstrapResponseTO} encapsulate the response of a boostrap request + * + * @author Jan N. Klug - Initial contribution + */ +public class BootstrapResponseTO { + public AuthenticationTO authentication; + + @Override + public @NonNull String toString() { + return "BootstrapResponseTO{authentication=" + authentication + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/CustomerHistoryRecordResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/CustomerHistoryRecordResponseTO.java new file mode 100644 index 0000000000..e8b47468e2 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/CustomerHistoryRecordResponseTO.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link CustomerHistoryRecordResponseTO} encapsulate the response for customer history record requests + * + * @author Jan N. Klug - Initial contribution + */ +public class CustomerHistoryRecordResponseTO { + public List customerHistoryRecords = List.of(); + + @Override + public @NonNull String toString() { + return "CustomerHistoryRecordResponseTO{customerHistoryRecords=" + customerHistoryRecords + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/CustomerHistoryRecordTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/CustomerHistoryRecordTO.java new file mode 100644 index 0000000000..c5a35cd0af --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/CustomerHistoryRecordTO.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +/** + * The {@link CustomerHistoryRecordTO} is + * + * @author Jan N. Klug - Initial contribution + */ +public class CustomerHistoryRecordTO { + public String recordKey; + public String recordType; + public long timestamp; + public String customerId; + public Object device; + public Boolean isBinaryFeedbackProvided; + public Boolean isFeedbackPositive; + public String utteranceType; + public String domain; + public String intent; + public String skillName; + public List voiceHistoryRecordItems = List.of(); + public List personsInfo = List.of(); +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/CustomerInfoTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/CustomerInfoTO.java new file mode 100644 index 0000000000..68256f26c5 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/CustomerInfoTO.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link CustomerInfoTO} encapsulates the customer information of a registration response + * + * @author Jan N. Klug - Initial contribution + */ +public class CustomerInfoTO { + @SerializedName("account_pool") + public String accountPool; + @SerializedName("user_id") + public String userId; + @SerializedName("home_region") + public String homeRegion; + public String name; + @SerializedName("given_name") + public String givenName; + + @Override + public @NonNull String toString() { + return "CustomerInfoTO{accountPool='" + accountPool + "', userId='" + userId + "', homeRegion='" + homeRegion + + "', name='" + name + "', givenName='" + givenName + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DeviceInfoTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DeviceInfoTO.java new file mode 100644 index 0000000000..c5713cda73 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DeviceInfoTO.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link DeviceInfoTO} encapsulates the device information of an app registration response + * + * @author Jan N. Klug - Initial contribution + */ +public class DeviceInfoTO { + @SerializedName("device_name") + public String deviceName = "Unknown"; + @SerializedName("device_serial_number") + public String deviceSerialNumber; + @SerializedName("device_type") + public String deviceType; + + @Override + public @NonNull String toString() { + return "DeviceInfoTO{deviceName='" + deviceName + "', deviceSerialNumber='" + deviceSerialNumber + + "', deviceType='" + deviceType + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DeviceListResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DeviceListResponseTO.java new file mode 100644 index 0000000000..735f3eb5a1 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DeviceListResponseTO.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; + +/** + * The {@link DeviceListResponseTO} encapsulate the response of /api/devices-v2 + * + * @author Jan N. Klug - Initial contribution + */ +public class DeviceListResponseTO { + public List devices = List.of(); + + @Override + public @NonNull String toString() { + return "DeviceListResponseTO{devices=" + devices + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DeviceNotificationStateResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DeviceNotificationStateResponseTO.java new file mode 100644 index 0000000000..affee995e7 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DeviceNotificationStateResponseTO.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceNotificationStateTO; + +/** + * The {@link DeviceNotificationStateResponseTO} encapsulate the response of the /api/device-notification-state + * + * @author Jan N. Klug - Initial contribution + */ +@NonNullByDefault +public class DeviceNotificationStateResponseTO { + public List deviceNotificationStates = List.of(); + + @Override + public @NonNull String toString() { + return "DeviceNotificationStateResponseTO{deviceNotificationStates=" + deviceNotificationStates + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DoNotDisturbDeviceStatusResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DoNotDisturbDeviceStatusResponseTO.java new file mode 100644 index 0000000000..9208a9c50a --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/DoNotDisturbDeviceStatusResponseTO.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DoNotDisturbDeviceStatusTO; + +/** + * The {@link DoNotDisturbDeviceStatusResponseTO} encapsulate the response of /api/dnd/device-status-list + * + * @author Jan N. Klug - Initial contribution + */ +public class DoNotDisturbDeviceStatusResponseTO { + public List doNotDisturbDeviceStatusList = List.of(); + + @Override + public @NonNull String toString() { + return "DoNotDisturbDeviceStatusResponseTO{doNotDisturbDeviceStatusList=" + doNotDisturbDeviceStatusList + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/EndpointResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/EndpointResponseTO.java new file mode 100644 index 0000000000..47c0b9f76e --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/EndpointResponseTO.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +/** + * The {@link DoNotDisturbDeviceStatusResponseTO} encapsulate the response of /api/endpoints + * + * @author Jan N. Klug - Initial contribution + */ +public class EndpointResponseTO { + public String alexaApiUrl; + public String awsRegion; + public String retailDomain; + public String retailUrl; + public String skillsStoreUrl; + public String websiteApiUrl; + public String websiteUrl; +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ExtensionsTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ExtensionsTO.java new file mode 100644 index 0000000000..60e211330d --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ExtensionsTO.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link ExtensionsTO} encapsulates the extension part of an app registration response + * + * @author Jan N. Klug - Initial contribution + */ +public class ExtensionsTO { + @SerializedName("device_info") + public DeviceInfoTO deviceInfo = new DeviceInfoTO(); + @SerializedName("customer_info") + public CustomerInfoTO customerInfo = new CustomerInfoTO(); + @SerializedName("customer_id") + public @Nullable String customerId; + + @Override + public @NonNull String toString() { + return "ExtensionsTO{deviceInfo=" + deviceInfo + ", customerInfo=" + customerInfo + ", customerId='" + + customerId + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MacDmsTokenTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MacDmsTokenTO.java new file mode 100644 index 0000000000..5ffbe0cbcd --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MacDmsTokenTO.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link MacDmsTokenTO} encapsulates MAC dms tokens + * + * @author Jan N. Klug - Initial contribution + */ +public class MacDmsTokenTO { + @SerializedName("device_private_key") + public String devicePrivateKey; + + @SerializedName("adp_token") + public String adpToken; + + @Override + public @NonNull String toString() { + return "MacDmsTokenTO{devicePrivateKey='" + devicePrivateKey + "', adpToken='" + adpToken + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MusicProviderTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MusicProviderTO.java new file mode 100644 index 0000000000..7f804480e1 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MusicProviderTO.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link MusicProviderTO} encapsulate a single music provider + * + * @author Jan N. Klug - Initial contribution + */ +public class MusicProviderTO { + public String id; + public String displayName; + public String description; + public List supportedProperties = List.of(); + public List supportedTriggers = List.of(); + public List supportedOperations = List.of(); + public String availability; + public String icon; + public ProviderDataTO providerData = new ProviderDataTO(); + + @Override + public @NonNull String toString() { + return "MusicProviderTO{id='" + id + "', displayName='" + displayName + "', description='" + description + + "', supportedProperties=" + supportedProperties + ", supportedTriggers=" + supportedTriggers + + ", supportedOperations=" + supportedOperations + ", availability='" + availability + "', icon='" + + icon + "', providerData=" + providerData + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/NotificationListResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/NotificationListResponseTO.java new file mode 100644 index 0000000000..615fe4b282 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/NotificationListResponseTO.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.dto.NotificationTO; + +/** + * The {@link NotificationListResponseTO} encapsulate response of a /api/notifications + * + * @author Jan N. Klug - Initial contribution + */ +public class NotificationListResponseTO { + public List notifications = List.of(); + + @Override + public @NonNull String toString() { + return "NotificationListResponseTO{notifications=" + notifications + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/NotificationSoundResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/NotificationSoundResponseTO.java new file mode 100644 index 0000000000..8f93a22124 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/NotificationSoundResponseTO.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.dto.NotificationSoundTO; + +/** + * The {@link NotificationSoundResponseTO} encapsulate response of /api/notification/sounds + * + * @author Jan N. Klug - Initial contribution + */ +public class NotificationSoundResponseTO { + public List notificationSounds = List.of(); + + @Override + public @NonNull String toString() { + return "NotificationSoundResponseTO{notificationSounds=" + notificationSounds + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ProviderDataTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ProviderDataTO.java new file mode 100644 index 0000000000..bcf6e100ae --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ProviderDataTO.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link ProviderDataTO} encapsulates music provider metadata + * + * @author Jan N. Klug - Initial contribution + */ +public class ProviderDataTO { + public boolean isDefaultMusicProvider; + public boolean isDefaultStationProvider; + + @Override + public @NonNull String toString() { + return "ProviderDataTO{isDefaultMusicProvider=" + isDefaultMusicProvider + ", isDefaultStationProvider=" + + isDefaultStationProvider + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/RegisterAppResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/RegisterAppResponseTO.java new file mode 100644 index 0000000000..d72e9362ac --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/RegisterAppResponseTO.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link RegisterAppResponseTO} encapsulate an app registration response + * + * @author Jan N. Klug - Initial contribution + */ +public class RegisterAppResponseTO { + @SerializedName("request_id") + public String requestId; + public ResponseTO response = new ResponseTO(); + + @Override + public @NonNull String toString() { + return "RegisterAppResponseTO{requestId='" + requestId + "', response=" + response + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ResponseTO.java new file mode 100644 index 0000000000..2d6f6ee477 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ResponseTO.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link ResponseTO} encapsulates the internal response section of an app registration response + * + * @author Jan N. Klug - Initial contribution + */ +public class ResponseTO { + public SuccessTO success = new SuccessTO(); + + @Override + public @NonNull String toString() { + return "ResponseTO{success=" + success + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/SuccessTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/SuccessTO.java new file mode 100644 index 0000000000..8deae5d5b7 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/SuccessTO.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link SuccessTO} encapsulates the success section of an app registration response + * + * @author Jan N. Klug - Initial contribution + */ +public class SuccessTO { + public ExtensionsTO extensions = new ExtensionsTO(); + public TokensTO tokens = new TokensTO(); + @SerializedName("customer_id") + public String customerId; + + @Override + public @NonNull String toString() { + return "SuccessTO{extensions=" + extensions + ", tokens=" + tokens + ", customerId='" + customerId + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/TokensTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/TokensTO.java new file mode 100644 index 0000000000..f198cfdfbb --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/TokensTO.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link TokensTO} encapsulates all tokens for a connection registration response + * + * @author Jan N. Klug - Initial contribution + */ +public class TokensTO { + @SerializedName("website_cookies") + public @Nullable Object websiteCookies; + @SerializedName("mac_dms") + public MacDmsTokenTO macDms = new MacDmsTokenTO(); + public BearerTokenTO bearer = new BearerTokenTO(); + + @Override + public @NonNull String toString() { + return "TokensTO{websiteCookies=" + websiteCookies + ", macDms=" + macDms + ", bearer=" + bearer + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/UsersMeResponseTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/UsersMeResponseTO.java new file mode 100644 index 0000000000..426e5c0f0a --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/UsersMeResponseTO.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link UsersMeResponseTO} encapsulate the response of /api/users/me + * + * @author Michael Geramb - Initial contribution + */ +public class UsersMeResponseTO { + public String countryOfResidence; + public String effectiveMarketPlaceId; + public String email; + public Boolean eulaAcceptance; + public List features = List.of(); + public String fullName; + public Boolean hasActiveDopplers; + public String id; + public String marketPlaceDomainName; + public String marketPlaceId; + public String marketPlaceLocale; + + @Override + public @NonNull String toString() { + return "UsersMeResponseTO{countryOfResidence='" + countryOfResidence + "', effectiveMarketPlaceId='" + + effectiveMarketPlaceId + "', email='" + email + "', eulaAcceptance=" + eulaAcceptance + ", features=" + + features + ", fullName='" + fullName + "'" + ", hasActiveDopplers=" + hasActiveDopplers + ", id='" + + id + "', marketPlaceDomainName='" + marketPlaceDomainName + "', marketPlaceId='" + marketPlaceId + + "', marketPlaceLocale='" + marketPlaceLocale + "'" + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/VoiceHistoryRecordItemTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/VoiceHistoryRecordItemTO.java new file mode 100644 index 0000000000..9540704a8c --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/VoiceHistoryRecordItemTO.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link VoiceHistoryRecordItemTO} encapsulates a voice history record of a customer history + * + * @author Jan N. Klug - Initial contribution + */ +public class VoiceHistoryRecordItemTO { + public String recordItemKey; + public String recordItemType; + public String utteranceId; + public long timestamp; + public String transcriptText; + public String agentVisualName; + public List personsInfo = List.of(); + + @Override + public @NonNull String toString() { + return "VoiceHistoryRecordItemTO{recordItemKey='" + recordItemKey + "', recordItemType='" + recordItemType + + "', utteranceId='" + utteranceId + "', timestamp=" + timestamp + ", transcriptText='" + transcriptText + + "', agentVisualName='" + agentVisualName + "', personsInfo=" + personsInfo + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationSounds.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/WakeWordResponseTO.java similarity index 51% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationSounds.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/WakeWordResponseTO.java index c68440accc..ba5b31de9a 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonNotificationSounds.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/WakeWordResponseTO.java @@ -1,5 +1,4 @@ /** - * Copyright (c) 2010-2021 Contributors to the openHAB project * Copyright (c) 2021-2023 Contributors to the SmartHome/J project * * See the NOTICE file(s) distributed with this work for additional @@ -11,19 +10,22 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.response; import java.util.List; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jdt.annotation.NonNull; /** - * The {@link JsonNotificationSounds} encapsulate the GSON data for a notification sounds + * The {@link WakeWordResponseTO} encapsulate the response of a request to /api/wake-word * * @author Michael Geramb - Initial contribution */ -@NonNullByDefault -public class JsonNotificationSounds { - public @Nullable List notificationSounds; +public class WakeWordResponseTO { + public List wakeWords = List.of(); + + @Override + public @NonNull String toString() { + return "WakeWordResponseTO{wakeWords=" + wakeWords + "}"; + } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/WakeWordTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/WakeWordTO.java new file mode 100644 index 0000000000..6b0b79afc5 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/WakeWordTO.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link WakeWordTO} encapsulates a single wake word definition + * + * @author Jan N. Klug - Initial contribution + */ +public class WakeWordTO { + public boolean active; + public String deviceSerialNumber; + public String deviceType; + public Object midFieldState; + public String wakeWord; + + @Override + public @NonNull String toString() { + return "WakeWordTO{active=" + active + ", deviceSerialNumber='" + deviceSerialNumber + "', deviceType='" + + deviceType + "', midFieldState=" + midFieldState + ", wakeWord='" + wakeWord + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeCapability.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeCapability.java similarity index 98% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeCapability.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeCapability.java index f23476c7e6..a7470fc15c 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeCapability.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeCapability.java @@ -11,7 +11,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome; import java.util.List; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeDevice.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeDevice.java similarity index 92% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeDevice.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeDevice.java index 8908ae4c16..2bf481e088 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeDevice.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeDevice.java @@ -11,15 +11,15 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome; import java.util.List; import java.util.Objects; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDeviceNetworkState.SmartHomeDeviceNetworkState; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeTags.JsonSmartHomeTag; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDeviceNetworkState.SmartHomeDeviceNetworkState; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeTags.JsonSmartHomeTag; /** * The {@link JsonSmartHomeDevice} encapsulates smarthome device API responses diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeDeviceAlias.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeDeviceAlias.java similarity index 92% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeDeviceAlias.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeDeviceAlias.java index a1ac605314..ee9eefd847 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeDeviceAlias.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeDeviceAlias.java @@ -11,7 +11,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeDeviceNetworkState.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeDeviceNetworkState.java similarity index 93% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeDeviceNetworkState.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeDeviceNetworkState.java index 24b445c066..8f9a546a13 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeDeviceNetworkState.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeDeviceNetworkState.java @@ -11,7 +11,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeGroupIdentifiers.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeGroupIdentifiers.java similarity index 93% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeGroupIdentifiers.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeGroupIdentifiers.java index 6870b2d01c..5472fe7956 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeGroupIdentifiers.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeGroupIdentifiers.java @@ -11,7 +11,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeGroupIdentity.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeGroupIdentity.java similarity index 94% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeGroupIdentity.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeGroupIdentity.java index c56881881b..d0a80d4a90 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeGroupIdentity.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeGroupIdentity.java @@ -11,7 +11,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome; import java.util.List; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeGroups.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeGroups.java similarity index 90% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeGroups.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeGroups.java index d9aa1a39d5..fb8df6d6ca 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeGroups.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeGroups.java @@ -11,13 +11,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome; import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeGroupIdentifiers.SmartHomeGroupIdentifier; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeGroupIdentifiers.SmartHomeGroupIdentifier; /** * @author Lukas Knoeller - Initial contribution diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeTags.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeTags.java similarity index 81% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeTags.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeTags.java index b3ac4cb686..f136981ca0 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/JsonSmartHomeTags.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/JsonSmartHomeTags.java @@ -11,11 +11,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeGroupIdentity.SmartHomeGroupIdentity; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeGroupIdentity.SmartHomeGroupIdentity; /** * @author Lukas Knoeller - Initial contribution diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/SmartHomeBaseDevice.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/SmartHomeBaseDevice.java similarity index 91% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/SmartHomeBaseDevice.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/SmartHomeBaseDevice.java index 47dede0c37..80c32313ff 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/SmartHomeBaseDevice.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/smarthome/SmartHomeBaseDevice.java @@ -11,7 +11,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto; +package org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java index e6d4fb39a3..5d4350a904 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java @@ -14,6 +14,7 @@ package org.smarthomej.binding.amazonechocontrol.internal.handler; import static org.smarthomej.binding.amazonechocontrol.internal.push.PushConnection.State.CLOSED; +import static org.smarthomej.binding.amazonechocontrol.internal.util.Util.findInList; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -21,7 +22,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -63,25 +63,25 @@ import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; import org.smarthomej.binding.amazonechocontrol.internal.discovery.AmazonEchoDiscovery; import org.smarthomej.binding.amazonechocontrol.internal.discovery.SmartHomeDevicesDiscovery; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonAscendingAlarm.AscendingAlarmModel; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonBluetoothStates; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonBluetoothStates.BluetoothState; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonCustomerHistoryRecords.CustomerHistoryRecord; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDeviceNotificationState.DeviceNotificationState; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDoNotDisturb.DoNotDisturbDeviceStatus; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonFeed; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonMusicProvider; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNotificationResponse; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNotificationSound; +import org.smarthomej.binding.amazonechocontrol.internal.dto.AscendingAlarmTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceNotificationStateTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DoNotDisturbDeviceStatusTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.FeedTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlaylists; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonWakeWords.WakeWord; -import org.smarthomej.binding.amazonechocontrol.internal.dto.SmartHomeBaseDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.NotificationSoundTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.NotificationTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.push.PushCommandTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.push.PushDeviceTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.push.PushDopplerIdTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.push.PushNotificationChangeTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.BluetoothStateResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.BluetoothStateTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.CustomerHistoryRecordTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.MusicProviderTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.WakeWordTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.SmartHomeBaseDevice; import org.smarthomej.binding.amazonechocontrol.internal.push.PushConnection; import org.smarthomej.binding.amazonechocontrol.internal.smarthome.SmartHomeDeviceStateGroupUpdateCalculator; @@ -106,7 +106,7 @@ public class AccountHandler extends BaseBridgeHandler implements AmazonHandlerCa private final Set flashBriefingProfileHandlers = new CopyOnWriteArraySet<>(); private final Object synchronizeConnection = new Object(); - private Map jsonSerialNumberDeviceMapping = new HashMap<>(); + private Map jsonSerialNumberDeviceMapping = new HashMap<>(); private Map jsonIdSmartHomeDeviceMapping = new HashMap<>(); private @Nullable ScheduledFuture checkDataJob; @@ -203,7 +203,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { String channelId = channelUID.getId(); for (ChannelHandler channelHandler : channelHandlers) { - if (channelHandler.tryHandleCommand(new Device(), connection, channelId, command)) { + if (channelHandler.tryHandleCommand(new DeviceTO(), connection, channelId, command)) { return; } } @@ -216,7 +216,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { } @Override - public void startAnnouncement(Device device, String speak, String bodyText, @Nullable String title, + public void startAnnouncement(DeviceTO device, String speak, String bodyText, @Nullable String title, @Nullable Integer volume) { EchoHandler echoHandler = findEchoHandlerBySerialNumber(device.serialNumber); if (echoHandler != null) { @@ -228,7 +228,7 @@ public Set getFlashBriefingProfileHandlers() { return new HashSet<>(flashBriefingProfileHandlers); } - public List getLastKnownDevices() { + public List getLastKnownDevices() { return new ArrayList<>(jsonSerialNumberDeviceMapping.values()); } @@ -236,16 +236,6 @@ public List getLastKnownSmartHomeDevices() { return new ArrayList<>(jsonIdSmartHomeDeviceMapping.values()); } - public void addEchoHandler(EchoHandler echoHandler) { - if (echoHandlers.add(echoHandler)) { - forceCheckData(); - } - } - - public void removeEchoHandler(EchoHandler echoHandler) { - echoHandlers.remove(echoHandler); - } - public void addSmartHomeDeviceHandler(SmartHomeDeviceHandler smartHomeDeviceHandler) { if (smartHomeDeviceHandlers.add(smartHomeDeviceHandler)) { forceCheckData(); @@ -282,7 +272,7 @@ public void forceCheckData() { public void addFlashBriefingProfileHandler(FlashBriefingProfileHandler flashBriefingProfileHandler) { flashBriefingProfileHandlers.add(flashBriefingProfileHandler); Connection connection = this.connection; - if (connection != null && connection.getIsLoggedIn()) { + if (connection != null && connection.isLoggedIn()) { if (currentFlashBriefingJson.isEmpty()) { updateFlashBriefingProfiles(connection); } @@ -298,6 +288,10 @@ private void scheduleUpdate() { @Override public void childHandlerInitialized(ThingHandler childHandler, Thing childThing) { + if (childHandler instanceof EchoHandler echoHandler) { + echoHandlers.add(echoHandler); + forceCheckData(); + } scheduleUpdate(); } @@ -388,7 +382,7 @@ private void checkLogin() { } try { - if (currentConnection.getIsLoggedIn()) { + if (currentConnection.isLoggedIn()) { if (currentConnection.checkRenewSession()) { setConnection(currentConnection); } @@ -401,7 +395,7 @@ private void checkLogin() { setConnection(currentConnection); } } - if (!currentConnection.getIsLoggedIn()) { + if (!currentConnection.isLoggedIn()) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING, "Please login in through web site: http(s)://:/amazonechocontrol/" + URLEncoder.encode(uid.getId(), StandardCharsets.UTF_8)); @@ -447,7 +441,7 @@ private void checkData() { synchronized (synchronizeConnection) { try { Connection connection = this.connection; - if (connection != null && connection.getIsLoggedIn()) { + if (connection != null && connection.isLoggedIn()) { checkDataCounter++; if (checkDataCounter > 60 || forceCheckDataJob != null) { checkDataCounter = 0; @@ -468,19 +462,14 @@ private void checkData() { private void refreshNotifications(@Nullable PushNotificationChangeTO notificationChange) { Connection currentConnection = this.connection; - if (currentConnection == null || !currentConnection.getIsLoggedIn()) { + if (currentConnection == null || !currentConnection.isLoggedIn()) { return; } ZonedDateTime timeStamp = ZonedDateTime.now(); - try { - List notifications = currentConnection.notifications(); - ZonedDateTime timeStampNow = ZonedDateTime.now(); - echoHandlers - .forEach(echoHandler -> echoHandler.updateNotifications(timeStamp, timeStampNow, notifications)); - } catch (ConnectionException e) { - logger.debug("refreshNotifications failed", e); - } + List notifications = currentConnection.getNotifications(); + ZonedDateTime timeStampNow = ZonedDateTime.now(); + echoHandlers.forEach(echoHandler -> echoHandler.updateNotifications(timeStamp, timeStampNow, notifications)); } private void refreshData() { @@ -491,7 +480,7 @@ private void refreshData() { // check if logged in Connection currentConnection = connection; if (currentConnection != null) { - if (!currentConnection.getIsLoggedIn()) { + if (!currentConnection.isLoggedIn()) { return; } } @@ -504,26 +493,26 @@ private void refreshData() { updateSmartHomeDeviceList(false); updateFlashBriefingHandlers(); - List deviceNotificationStates = List.of(); - List ascendingAlarmModels = List.of(); - List doNotDisturbDeviceStatuses = List.of(); - JsonBluetoothStates states = null; - List musicProviders = null; - if (currentConnection.getIsLoggedIn()) { + List deviceNotificationStates = List.of(); + List ascendingAlarmModels = List.of(); + List doNotDisturbDeviceStatuses = List.of(); + BluetoothStateResponseTO states = null; + List musicProviders = null; + if (currentConnection.isLoggedIn()) { // update notification states deviceNotificationStates = currentConnection.getDeviceNotificationStates(); // update ascending alarm - ascendingAlarmModels = currentConnection.getAscendingAlarm(); + ascendingAlarmModels = currentConnection.getAscendingAlarms(); // update do not disturb - doNotDisturbDeviceStatuses = currentConnection.getDoNotDisturb(); + doNotDisturbDeviceStatuses = currentConnection.getDoNotDisturbs(); // update bluetooth states states = currentConnection.getBluetoothConnectionStates(); // update music providers - if (currentConnection.getIsLoggedIn()) { + if (currentConnection.isLoggedIn()) { try { musicProviders = currentConnection.getMusicProviders(); } catch (JsonSyntaxException e) { @@ -533,11 +522,11 @@ private void refreshData() { } // forward device information to echo handler for (EchoHandler child : echoHandlers) { - Device device = findDeviceJson(child.findSerialNumber()); + DeviceTO device = findDeviceJson(child.findSerialNumber()); - List notificationSounds = List.of(); + List notificationSounds = List.of(); JsonPlaylists playlists = null; - if (device != null && currentConnection.getIsLoggedIn()) { + if (device != null && currentConnection.isLoggedIn()) { // update notification sounds try { notificationSounds = currentConnection.getNotificationSounds(device); @@ -552,13 +541,15 @@ private void refreshData() { } } - BluetoothState state = null; - if (states != null) { - state = states.findStateByDevice(device); + BluetoothStateTO state = null; + if (states != null && device != null) { + state = findInList(states.bluetoothStates, k -> k.deviceSerialNumber, device.serialNumber) + .orElse(null); } - DeviceNotificationState deviceNotificationState = null; - AscendingAlarmModel ascendingAlarmModel = null; - DoNotDisturbDeviceStatus doNotDisturbDeviceStatus = null; + + DeviceNotificationStateTO deviceNotificationState = null; + AscendingAlarmTO ascendingAlarmModel = null; + DoNotDisturbDeviceStatusTO doNotDisturbDeviceStatus = null; if (device != null) { final String serialNumber = device.serialNumber; if (serialNumber != null) { @@ -592,14 +583,14 @@ private void refreshData() { } } - public @Nullable Device findDeviceJson(@Nullable String serialNumber) { + public @Nullable DeviceTO findDeviceJson(@Nullable String serialNumber) { if (serialNumber == null || serialNumber.isEmpty()) { return null; } return this.jsonSerialNumberDeviceMapping.get(serialNumber); } - public @Nullable Device findDeviceJsonBySerialOrName(@Nullable String serialOrName) { + public @Nullable DeviceTO findDeviceJsonBySerialOrName(@Nullable String serialOrName) { if (serialOrName == null || serialOrName.isEmpty()) { return null; } @@ -609,15 +600,15 @@ private void refreshData() { .findFirst().orElse(null); } - public List updateDeviceList() { + public List updateDeviceList() { Connection currentConnection = connection; if (currentConnection == null) { return new ArrayList<>(); } - List devices = null; + List devices = null; try { - if (currentConnection.getIsLoggedIn()) { + if (currentConnection.isLoggedIn()) { devices = currentConnection.getDeviceList(); } } catch (ConnectionException e) { @@ -631,12 +622,11 @@ public List updateDeviceList() { flashBriefingProfileHandlers.forEach(h -> h.setCommandDescription(jsonSerialNumberDeviceMapping.values())); } - List wakeWords = currentConnection.getWakeWords(); + List wakeWords = currentConnection.getWakeWords(); // update handlers for (EchoHandler echoHandler : echoHandlers) { String serialNumber = echoHandler.findSerialNumber(); - String deviceWakeWord = wakeWords.stream() - .filter(wakeWord -> serialNumber.equals(wakeWord.deviceSerialNumber)).findFirst() + String deviceWakeWord = findInList(wakeWords, w -> w.deviceSerialNumber, serialNumber) .map(wakeWord -> wakeWord.wakeWord).orElse(null); echoHandler.setDeviceAndUpdateThingState(this, findDeviceJson(serialNumber), deviceWakeWord); } @@ -649,7 +639,7 @@ public List updateDeviceList() { public void setEnabledFlashBriefingsJson(String flashBriefingJson) { Connection currentConnection = connection; - JsonFeed[] feeds = gson.fromJson(flashBriefingJson, JsonFeed[].class); + FeedTO[] feeds = gson.fromJson(flashBriefingJson, FeedTO[].class); if (currentConnection != null && feeds != null) { try { currentConnection.setEnabledFlashBriefings(Arrays.asList(feeds)); @@ -660,10 +650,6 @@ public void setEnabledFlashBriefingsJson(String flashBriefingJson) { updateFlashBriefingHandlers(); } - public String getNewCurrentFlashbriefingConfiguration() { - return updateFlashBriefingHandlers(); - } - public String updateFlashBriefingHandlers() { Connection currentConnection = connection; if (currentConnection != null) { @@ -700,14 +686,16 @@ public String getEnabledFlashBriefingsJson() { } private void updateFlashBriefingProfiles(Connection currentConnection) { - try { - // Make a copy and remove changeable parts - JsonFeed[] forSerializer = currentConnection.getEnabledFlashBriefings().stream() - .map(source -> new JsonFeed(source.feedId, source.skillId)).toArray(JsonFeed[]::new); - this.currentFlashBriefingJson = gson.toJson(forSerializer); - } catch (JsonSyntaxException | ConnectionException e) { - logger.warn("get flash briefing profiles fails", e); - } + // Make a copy and remove changeable parts + List forSerializer = currentConnection.getEnabledFlashBriefings().stream().map(this::copyFeed).toList(); + this.currentFlashBriefingJson = gson.toJson(forSerializer); + } + + private FeedTO copyFeed(FeedTO feed) { + FeedTO newFeed = new FeedTO(); + newFeed.feedId = feed.feedId; + newFeed.skillId = feed.skillId; + return newFeed; } @Override @@ -723,7 +711,7 @@ public void onPushCommandReceived(PushCommandTO pushCommand) { if (refreshDataDelayed != null) { refreshDataDelayed.cancel(false); } - this.refreshAfterCommandJob = scheduler.schedule(() -> refreshData(), 700, TimeUnit.MILLISECONDS); + this.refreshAfterCommandJob = scheduler.schedule(this::refreshData, 700, TimeUnit.MILLISECONDS); break; case "PUSH_NOTIFICATION_CHANGE": @@ -765,7 +753,7 @@ public void onPushCommandReceived(PushCommandTO pushCommand) { private void handlePushActivity(PushDopplerIdTO dopplerId, @Nullable Long timestamp) { Connection connection = this.connection; - if (connection == null || !connection.getIsLoggedIn()) { + if (connection == null || !connection.isLoggedIn()) { return; } long real_timestamp = Objects.requireNonNullElse(timestamp, System.currentTimeMillis()); @@ -773,8 +761,8 @@ private void handlePushActivity(PushDopplerIdTO dopplerId, @Nullable Long timest long endTimestamp = real_timestamp + 30000; String deviceKey = dopplerId.deviceType + "#" + dopplerId.deviceSerialNumber; - List customerHistoryRecords = connection.getActivities(startTimestamp, endTimestamp); - for (CustomerHistoryRecord customerHistoryRecord : customerHistoryRecords) { + List customerHistoryRecords = connection.getActivities(startTimestamp, endTimestamp); + for (CustomerHistoryRecordTO customerHistoryRecord : customerHistoryRecords) { String recordKey = customerHistoryRecord.recordKey; if (recordKey != null && recordKey.endsWith(deviceKey)) { EchoHandler echoHandler = findEchoHandlerBySerialNumber(dopplerId.deviceSerialNumber); @@ -800,37 +788,36 @@ public int getSmartHomeDevicesDiscoveryMode() { public List updateSmartHomeDeviceList(boolean forceUpdate) { Connection currentConnection = connection; if (currentConnection == null) { - return Collections.emptyList(); + return List.of(); } - if (!forceUpdate && smartHomeDeviceHandlers.isEmpty() && getSmartHomeDevicesDiscoveryMode() == 0) { - return Collections.emptyList(); + if (!forceUpdate && smartHomeDeviceHandlers.isEmpty() && handlerConfig.discoverSmartHome == 0) { + return List.of(); } - List smartHomeDevices = null; try { - if (currentConnection.getIsLoggedIn()) { - smartHomeDevices = currentConnection.getSmarthomeDeviceList(); + if (currentConnection.isLoggedIn()) { + List smartHomeDevices = currentConnection.getSmarthomeDeviceList(); + // create new id map + Map newJsonIdSmartHomeDeviceMapping = new HashMap<>(); + for (SmartHomeBaseDevice smartHomeDevice : smartHomeDevices) { + String id = smartHomeDevice.findId(); + if (id != null) { + newJsonIdSmartHomeDeviceMapping.put(id, smartHomeDevice); + } + } + jsonIdSmartHomeDeviceMapping = newJsonIdSmartHomeDeviceMapping; + + // update handlers + smartHomeDeviceHandlers + .forEach(child -> child.setDeviceAndUpdateThingState(this, findSmartHomeDeviceJson(child))); + return smartHomeDevices; } } catch (ConnectionException e) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getLocalizedMessage()); } - if (smartHomeDevices != null) { - // create new id map - Map newJsonIdSmartHomeDeviceMapping = new HashMap<>(); - for (SmartHomeBaseDevice smartHomeDevice : smartHomeDevices) { - String id = smartHomeDevice.findId(); - if (id != null) { - newJsonIdSmartHomeDeviceMapping.put(id, smartHomeDevice); - } - } - jsonIdSmartHomeDeviceMapping = newJsonIdSmartHomeDeviceMapping; - } - // update handlers - smartHomeDeviceHandlers - .forEach(child -> child.setDeviceAndUpdateThingState(this, findSmartHomeDeviceJson(child))); - return Objects.requireNonNullElse(smartHomeDevices, List.of()); + return List.of(); } public void forceDelayedSmartHomeStateUpdate(String deviceId) { @@ -850,7 +837,7 @@ private void updateSmartHomeStateJob() { synchronized (synchronizeSmartHomeJobScheduler) { Connection connection = this.connection; - if (connection == null || !connection.getIsLoggedIn()) { + if (connection == null || !connection.isLoggedIn()) { this.refreshSmartHomeAfterCommandJob = scheduler.schedule(this::updateSmartHomeStateJob, 1000, TimeUnit.MILLISECONDS); return; @@ -866,7 +853,7 @@ private synchronized void updateSmartHomeState(@Nullable String deviceFilterId) try { logger.trace("updateSmartHomeState started with deviceFilterId={}", deviceFilterId); Connection connection = this.connection; - if (connection == null || !connection.getIsLoggedIn()) { + if (connection == null || !connection.isLoggedIn()) { return; } List allDevices = getLastKnownSmartHomeDevices(); diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/EchoHandler.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/EchoHandler.java index eb3d8bb5a2..b875f0ec2d 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/EchoHandler.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/EchoHandler.java @@ -13,6 +13,8 @@ */ package org.smarthomej.binding.amazonechocontrol.internal.handler; +import static org.eclipse.jetty.util.StringUtil.isBlank; +import static org.eclipse.jetty.util.StringUtil.isNotBlank; import static org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.*; import java.time.Duration; @@ -64,20 +66,14 @@ import org.smarthomej.binding.amazonechocontrol.internal.channelhandler.ChannelHandler; import org.smarthomej.binding.amazonechocontrol.internal.channelhandler.ChannelHandlerAnnouncement; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonAscendingAlarm.AscendingAlarmModel; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonBluetoothStates.BluetoothState; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonBluetoothStates.PairedDevice; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonCustomerHistoryRecords.CustomerHistoryRecord; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonCustomerHistoryRecords.CustomerHistoryRecord.VoiceHistoryRecordItem; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDeviceNotificationState.DeviceNotificationState; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDoNotDisturb.DoNotDisturbDeviceStatus; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonEqualizer; +import org.smarthomej.binding.amazonechocontrol.internal.dto.AscendingAlarmTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.BluetoothPairedDeviceTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceNotificationStateTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DoNotDisturbDeviceStatusTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.EqualizerTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonMediaState; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonMediaState.QueueEntry; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonMusicProvider; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNotificationResponse; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonNotificationSound; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlayerState; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlayerState.PlayerInfo; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlayerState.PlayerInfo.InfoText; @@ -86,10 +82,17 @@ import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlayerState.PlayerInfo.Provider; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlayerState.PlayerInfo.Volume; import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonPlaylists; +import org.smarthomej.binding.amazonechocontrol.internal.dto.NotificationSoundTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.NotificationTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.push.PushEqualizerStateChangeTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.push.PushVolumeChangeTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.request.PlayerSeekMediaTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.request.WHAVolumeLevelTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.BluetoothStateResponseTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.BluetoothStateTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.CustomerHistoryRecordTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.MusicProviderTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.VoiceHistoryRecordItemTO; import org.smarthomej.commons.SimpleDynamicCommandDescriptionProvider; import org.smarthomej.commons.SimpleDynamicStateDescriptionProvider; import org.smarthomej.commons.UpdatingBaseThingHandler; @@ -108,7 +111,7 @@ public class EchoHandler extends UpdatingBaseThingHandler implements AmazonHandl private final SimpleDynamicStateDescriptionProvider dynamicStateDescriptionProvider; private final SimpleDynamicCommandDescriptionProvider dynamicCommandDescriptionProvider; - private @Nullable Device device; + private @Nullable DeviceTO device; private Set capabilities = new HashSet<>(); private @Nullable AccountHandler account; private @Nullable ScheduledFuture updateStateJob; @@ -124,7 +127,7 @@ public class EchoHandler extends UpdatingBaseThingHandler implements AmazonHandl private boolean isPaused = false; private int lastKnownVolume = 25; private int textToSpeechVolume = 0; - private @Nullable JsonEqualizer lastKnownEqualizer = null; + private @Nullable EqualizerTO lastKnownEqualizer = null; private boolean disableUpdate = false; private boolean updateRemind = true; private boolean updateTextToSpeech = true; @@ -136,7 +139,7 @@ public class EchoHandler extends UpdatingBaseThingHandler implements AmazonHandl private @Nullable Boolean doNotDisturb; private final List channelHandlers = new ArrayList<>(); - private @Nullable JsonNotificationResponse currentNotification; + private @Nullable NotificationTO currentNotification; private @Nullable ScheduledFuture currentNotificationUpdateTimer; long mediaLengthMs; long mediaProgressMs; @@ -163,12 +166,11 @@ public void initialize() { if (account != null) { setDeviceAndUpdateThingState(account, this.device, null); createStartCommandCommandOptions(account.getFlashBriefingProfileHandlers()); - account.addEchoHandler(this); } } } - public boolean setDeviceAndUpdateThingState(AccountHandler accountHandler, @Nullable Device device, + public boolean setDeviceAndUpdateThingState(AccountHandler accountHandler, @Nullable DeviceTO device, @Nullable String wakeWord) { this.account = accountHandler; if (wakeWord != null) { @@ -179,7 +181,7 @@ public boolean setDeviceAndUpdateThingState(AccountHandler accountHandler, @Null return false; } this.device = device; - this.capabilities = device.getCapabilities(); + this.capabilities = device.capabilities; if (!device.online) { updateStatus(ThingStatus.OFFLINE); return false; @@ -251,7 +253,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (connection == null) { return; } - Device device = this.device; + DeviceTO device = this.device; if (device == null) { return; } @@ -288,7 +290,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (channelId.equals(CHANNEL_NOTIFICATION_VOLUME)) { if (command instanceof PercentType) { int volume = ((PercentType) command).intValue(); - connection.notificationVolume(device, volume); + connection.setNotificationVolume(device, volume); this.notificationVolumeLevel = volume; waitForUpdate = -1; account.forceCheckData(); @@ -296,13 +298,13 @@ public void handleCommand(ChannelUID channelUID, Command command) { } if (channelId.equals(CHANNEL_ASCENDING_ALARM)) { if (command == OnOffType.OFF) { - connection.ascendingAlarm(device, false); + connection.setAscendingAlarm(device, false); this.ascendingAlarm = false; waitForUpdate = -1; account.forceCheckData(); } if (command == OnOffType.ON) { - connection.ascendingAlarm(device, true); + connection.setAscendingAlarm(device, true); this.ascendingAlarm = true; waitForUpdate = -1; account.forceCheckData(); @@ -311,7 +313,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { // Do Not Disturb command if (channelId.equals(CHANNEL_DO_NOT_DISTURB) && command instanceof OnOffType) { boolean newDnd = OnOffType.ON.equals(command); - connection.doNotDisturb(device, newDnd); + connection.setDoNotDisturb(device, newDnd); this.doNotDisturb = true; waitForUpdate = -1; account.forceCheckData(); @@ -372,7 +374,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { volumeCommand.volumeLevel = volume; connection.command(device, volumeCommand); } else { - connection.volume(device, volume); + connection.setVolume(device, volume); } lastKnownVolume = volume; updateState(CHANNEL_VOLUME, new PercentType(lastKnownVolume)); @@ -520,7 +522,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (!alarmSound.isEmpty()) { waitForUpdate = 3000; String[] parts = alarmSound.split(":", 2); - JsonNotificationSound sound = new JsonNotificationSound(); + NotificationSoundTO sound = new NotificationSoundTO(); if (parts.length == 2) { sound.providerId = parts[0]; sound.id = parts[1]; @@ -629,9 +631,12 @@ public void handleCommand(ChannelUID channelUID, Command command) { final boolean bluetoothRefresh = needBluetoothRefresh; Runnable doRefresh = () -> { this.disableUpdate = false; - BluetoothState state = null; + BluetoothStateTO state = null; if (bluetoothRefresh) { - state = connection.getBluetoothConnectionStates().findStateByDevice(device); + BluetoothStateResponseTO bluetoothStateResponseTO = connection.getBluetoothConnectionStates(); + state = bluetoothStateResponseTO.bluetoothStates.stream() + .filter(state1 -> Objects.equals(state1.deviceSerialNumber, device.serialNumber)).findAny() + .orElse(null); } updateState(account, device, state, null, null, null, null, null, null); }; @@ -651,7 +656,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } - private boolean handleEqualizerCommands(String channelId, Command command, Connection connection, Device device) { + private boolean handleEqualizerCommands(String channelId, Command command, Connection connection, DeviceTO device) { if (command instanceof RefreshType) { this.lastKnownEqualizer = null; } @@ -659,20 +664,23 @@ private boolean handleEqualizerCommands(String channelId, Command command, Conne if (this.lastKnownEqualizer == null) { updateEqualizerState(); } - JsonEqualizer lastKnownEqualizer = this.lastKnownEqualizer; + EqualizerTO lastKnownEqualizer = this.lastKnownEqualizer; if (lastKnownEqualizer != null) { - JsonEqualizer newEqualizerSetting = lastKnownEqualizer.createClone(); + EqualizerTO newEqualizer = new EqualizerTO(); + newEqualizer.bass = lastKnownEqualizer.bass; + newEqualizer.mid = lastKnownEqualizer.mid; + newEqualizer.treble = lastKnownEqualizer.treble; if (channelId.equals(CHANNEL_EQUALIZER_BASS)) { - newEqualizerSetting.bass = decimal.intValue(); + newEqualizer.bass = decimal.intValue(); } if (channelId.equals(CHANNEL_EQUALIZER_MIDRANGE)) { - newEqualizerSetting.mid = decimal.intValue(); + newEqualizer.mid = decimal.intValue(); } if (channelId.equals(CHANNEL_EQUALIZER_TREBLE)) { - newEqualizerSetting.treble = decimal.intValue(); + newEqualizer.treble = decimal.intValue(); } try { - connection.setEqualizer(device, newEqualizerSetting); + connection.setEqualizer(device, newEqualizer); return true; } catch (ConnectionException e) { logger.debug("Failed to update equalizer"); @@ -683,18 +691,18 @@ private boolean handleEqualizerCommands(String channelId, Command command, Conne return false; } - private void startTextToSpeech(Connection connection, Device device, String text) { + private void startTextToSpeech(Connection connection, DeviceTO device, String text) { Integer volume = textToSpeechVolume != 0 ? textToSpeechVolume : null; connection.textToSpeech(device, text, volume, lastKnownVolume); } - private void startTextCommand(Connection connection, Device device, String text) { + private void startTextCommand(Connection connection, DeviceTO device, String text) { Integer volume = textToSpeechVolume != 0 ? textToSpeechVolume : null; connection.textCommand(device, text, volume, lastKnownVolume); } @Override - public void startAnnouncement(Device device, String speak, String bodyText, @Nullable String title, + public void startAnnouncement(DeviceTO device, String speak, String bodyText, @Nullable String title, @Nullable Integer volume) { Connection connection = this.findConnection(); if (connection == null) { @@ -715,29 +723,25 @@ private void stopCurrentNotification() { this.currentNotificationUpdateTimer = null; currentNotificationUpdateTimer.cancel(true); } - JsonNotificationResponse currentNotification = this.currentNotification; + NotificationTO currentNotification = this.currentNotification; if (currentNotification != null) { this.currentNotification = null; Connection currentConnection = this.findConnection(); if (currentConnection != null) { - try { - currentConnection.stopNotification(currentNotification); - } catch (ConnectionException e) { - logger.warn("Failed to stop notification"); - } + currentConnection.deleteNotification(currentNotification.id); } } } private void updateNotificationTimerState() { boolean stopCurrentNotification = true; - JsonNotificationResponse currentNotification = this.currentNotification; + NotificationTO currentNotification = this.currentNotification; try { if (currentNotification != null) { Connection currentConnection = this.findConnection(); if (currentConnection != null) { - JsonNotificationResponse newState = currentConnection.getNotificationState(currentNotification); - if (newState != null && "ON".equals(newState.status)) { + NotificationTO newState = currentConnection.getNotificationState(currentNotification.id); + if ("ON".equals(newState.status)) { stopCurrentNotification = false; } } @@ -757,16 +761,16 @@ private void updateNotificationTimerState() { } } - private void createMusicProviderStateDescription(List jsonMusicProviders) { + private void createMusicProviderStateDescription(List musicProviders) { List options = new ArrayList<>(); - for (JsonMusicProvider musicProvider : jsonMusicProviders) { - List properties = musicProvider.supportedProperties; + for (MusicProviderTO musicProvider : musicProviders) { + if (!musicProvider.supportedProperties.contains("Alexa.Music.PlaySearchPhrase")) { + continue; + } String providerId = musicProvider.id; String displayName = musicProvider.displayName; - if (properties != null && properties.contains("Alexa.Music.PlaySearchPhrase") && providerId != null - && !providerId.isEmpty() && "AVAILABLE".equals(musicProvider.availability) && displayName != null - && !displayName.isEmpty()) { - options.add(new StateOption(providerId, displayName)); + if (isNotBlank(providerId) && "AVAILABLE".equals(musicProvider.availability)) { + options.add(new StateOption(providerId, isNotBlank(displayName) ? displayName : providerId)); } } ChannelUID channelUID = new ChannelUID(thing.getUID(), CHANNEL_MUSIC_PROVIDER_ID); @@ -778,9 +782,9 @@ private void createMusicProviderStateDescription(List jsonMus } } - private void createAlarmSoundsCommandOptions(List alarmSounds) { + private void createAlarmSoundsCommandOptions(List alarmSounds) { List options = new ArrayList<>(); - for (JsonNotificationSound notificationSound : alarmSounds) { + for (NotificationSoundTO notificationSound : alarmSounds) { if (notificationSound.folder == null && notificationSound.providerId != null && notificationSound.id != null && notificationSound.displayName != null) { String providerSoundId = notificationSound.providerId + ":" + notificationSound.id; @@ -828,10 +832,10 @@ public void createStartCommandCommandOptions(Set fl dynamicCommandDescriptionProvider.setCommandOptions(channelUID, options); } - private void createBluetoothMACStateDescription(BluetoothState bluetoothState) { + private void createBluetoothMACStateDescription(BluetoothStateTO bluetoothState) { List options = new ArrayList<>(); options.add(new StateOption("", "")); - for (PairedDevice device : bluetoothState.getPairedDeviceList()) { + for (BluetoothPairedDeviceTO device : bluetoothState.pairedDeviceList) { final String value = device.address; if (value != null && device.friendlyName != null) { options.add(new StateOption(value, device.friendlyName)); @@ -846,11 +850,11 @@ private void createBluetoothMACStateDescription(BluetoothState bluetoothState) { } } - public void updateState(AccountHandler accountHandler, @Nullable Device device, - @Nullable BluetoothState bluetoothState, @Nullable DeviceNotificationState deviceNotificationState, - @Nullable AscendingAlarmModel ascendingAlarmModel, - @Nullable DoNotDisturbDeviceStatus doNotDisturbDeviceStatus, @Nullable JsonPlaylists playlists, - @Nullable List alarmSounds, @Nullable List musicProviders) { + public void updateState(AccountHandler accountHandler, @Nullable DeviceTO device, + @Nullable BluetoothStateTO bluetoothState, @Nullable DeviceNotificationStateTO deviceNotificationState, + @Nullable AscendingAlarmTO ascendingAlarmModel, + @Nullable DoNotDisturbDeviceStatusTO doNotDisturbDeviceStatus, @Nullable JsonPlaylists playlists, + @Nullable List alarmSounds, @Nullable List musicProviders) { try { this.logger.debug("Handle updateState {}", this.getThing().getUID()); @@ -903,40 +907,38 @@ public void updateState(AccountHandler accountHandler, @Nullable Device device, Progress progress = null; try { JsonPlayerState playerState = connection.getPlayer(device); - if (playerState != null) { - playerInfo = playerState.playerInfo; - if (playerInfo != null) { - infoText = playerInfo.infoText; - if (infoText == null) { - infoText = playerInfo.miniInfoText; - } - mainArt = playerInfo.mainArt; - provider = playerInfo.provider; - if (provider != null) { - musicProviderId = provider.providerName; - // Map the music provider id to the one used for starting music with voice command - if (musicProviderId != null) { - musicProviderId = musicProviderId.toUpperCase(); - - if ("AMAZON MUSIC".equals(musicProviderId)) { - musicProviderId = "AMAZON_MUSIC"; - } - if ("CLOUD_PLAYER".equals(musicProviderId)) { - musicProviderId = "AMAZON_MUSIC"; - } - if (musicProviderId.startsWith("TUNEIN")) { - musicProviderId = "TUNEIN"; - } - if (musicProviderId.startsWith("IHEARTRADIO")) { - musicProviderId = "I_HEART_RADIO"; - } - if (musicProviderId.startsWith("APPLE") && musicProviderId.contains("MUSIC")) { - musicProviderId = "APPLE_MUSIC"; - } + playerInfo = playerState.playerInfo; + if (playerInfo != null) { + infoText = playerInfo.infoText; + if (infoText == null) { + infoText = playerInfo.miniInfoText; + } + mainArt = playerInfo.mainArt; + provider = playerInfo.provider; + if (provider != null) { + musicProviderId = provider.providerName; + // Map the music provider id to the one used for starting music with voice command + if (musicProviderId != null) { + musicProviderId = musicProviderId.toUpperCase(); + + if ("AMAZON MUSIC".equals(musicProviderId)) { + musicProviderId = "AMAZON_MUSIC"; + } + if ("CLOUD_PLAYER".equals(musicProviderId)) { + musicProviderId = "AMAZON_MUSIC"; + } + if (musicProviderId.startsWith("TUNEIN")) { + musicProviderId = "TUNEIN"; + } + if (musicProviderId.startsWith("IHEARTRADIO")) { + musicProviderId = "I_HEART_RADIO"; + } + if (musicProviderId.startsWith("APPLE") && musicProviderId.contains("MUSIC")) { + musicProviderId = "APPLE_MUSIC"; } } - progress = playerInfo.progress; } + progress = playerInfo.progress; } } catch (ConnectionException e) { logger.info("Failed to get player queue"); @@ -960,8 +962,8 @@ public void updateState(AccountHandler accountHandler, @Nullable Device device, mediaStartMs = System.currentTimeMillis() - mediaProgressMs; if (isPlaying) { if (updateProgressJob == null) { - updateProgressJob = scheduler.scheduleWithFixedDelay(this::updateMediaProgress, 1000, 1000, - TimeUnit.MILLISECONDS); + updateProgressJob = scheduler.scheduleWithFixedDelay(() -> updateMediaProgress(false), 1000, + 1000, TimeUnit.MILLISECONDS); } } else { stopProgressTimer(); @@ -1007,7 +1009,7 @@ public void updateState(AccountHandler accountHandler, @Nullable Device device, boolean bluetoothIsConnected = false; if (bluetoothState != null) { - for (PairedDevice paired : bluetoothState.getPairedDeviceList()) { + for (BluetoothPairedDeviceTO paired : bluetoothState.pairedDeviceList) { String pairedAddress = paired.address; if (paired.connected && pairedAddress != null) { bluetoothIsConnected = true; @@ -1066,13 +1068,13 @@ public void updateState(AccountHandler accountHandler, @Nullable Device device, if (!queueEntries.isEmpty()) { QueueEntry entry = queueEntries.get(0); if (isRadio) { - if ((imageUrl == null || imageUrl.isEmpty()) && entry.imageURL != null) { + if (isBlank(imageUrl) && entry.imageURL != null) { imageUrl = entry.imageURL; } - if ((subTitle1 == null || subTitle1.isEmpty()) && entry.radioStationSlogan != null) { + if (isBlank(subTitle1) && entry.radioStationSlogan != null) { subTitle1 = entry.radioStationSlogan; } - if ((subTitle2 == null || subTitle2.isEmpty()) && entry.radioStationLocation != null) { + if (isBlank(subTitle2) && entry.radioStationLocation != null) { subTitle2 = entry.radioStationLocation; } } @@ -1084,8 +1086,8 @@ public void updateState(AccountHandler accountHandler, @Nullable Device device, if (provider != null) { providerDisplayName = Objects.requireNonNullElse(provider.providerDisplayName, providerDisplayName); String providerName = provider.providerName; - if (providerName != null && !providerName.isEmpty() && providerDisplayName.isEmpty()) { - providerDisplayName = provider.providerName; + if (isNotBlank(providerName) && providerDisplayName.isEmpty()) { + providerDisplayName = providerName; } } @@ -1151,11 +1153,12 @@ public void updateState(AccountHandler accountHandler, @Nullable Device device, updateState(CHANNEL_BLUETOOTH_DEVICE_NAME, new StringType(bluetoothDeviceName)); } + Boolean ascendingAlarm = this.ascendingAlarm; updateState(CHANNEL_ASCENDING_ALARM, - ascendingAlarm != null ? (ascendingAlarm ? OnOffType.ON : OnOffType.OFF) : UnDefType.UNDEF); + ascendingAlarm != null ? OnOffType.from(ascendingAlarm) : UnDefType.UNDEF); - updateState(CHANNEL_DO_NOT_DISTURB, - doNotDisturb != null ? (doNotDisturb ? OnOffType.ON : OnOffType.OFF) : UnDefType.UNDEF); + Boolean doNotDisturb = this.doNotDisturb; + updateState(CHANNEL_DO_NOT_DISTURB, doNotDisturb != null ? OnOffType.from(doNotDisturb) : UnDefType.UNDEF); final Integer notificationVolumeLevel = this.notificationVolumeLevel; if (notificationVolumeLevel != null) { @@ -1176,39 +1179,22 @@ private void updateEqualizerState() { } Connection connection = findConnection(); - if (connection == null) { - return; - } - Device device = this.device; - if (device == null) { + DeviceTO device = this.device; + if (connection == null || device == null) { return; + } try { - JsonEqualizer equalizer = connection.getEqualizer(device); - if (equalizer != null) { - Integer bass = equalizer.bass; - if (bass != null) { - updateState(CHANNEL_EQUALIZER_BASS, new DecimalType(bass)); - } - Integer midrange = equalizer.mid; - if (midrange != null) { - updateState(CHANNEL_EQUALIZER_MIDRANGE, new DecimalType(midrange)); - } - Integer treble = equalizer.treble; - if (treble != null) { - updateState(CHANNEL_EQUALIZER_TREBLE, new DecimalType(treble)); - } - } + EqualizerTO equalizer = connection.getEqualizer(device); + updateState(CHANNEL_EQUALIZER_BASS, new DecimalType(equalizer.bass)); + updateState(CHANNEL_EQUALIZER_MIDRANGE, new DecimalType(equalizer.mid)); + updateState(CHANNEL_EQUALIZER_TREBLE, new DecimalType(equalizer.treble)); this.lastKnownEqualizer = equalizer; } catch (ConnectionException e) { logger.debug("Failed to get equalizer"); } } - private void updateMediaProgress() { - updateMediaProgress(false); - } - private void updateMediaProgress(boolean updateMediaLength) { synchronized (progressLock) { if (mediaStartMs > 0) { @@ -1235,24 +1221,24 @@ private void updateMediaProgress(boolean updateMediaLength) { } } - public synchronized void handlePushActivity(CustomerHistoryRecord customerHistoryRecord) { - long recordTimestamp = customerHistoryRecord.getTimestamp(); + public synchronized void handlePushActivity(CustomerHistoryRecordTO customerHistoryRecord) { + long recordTimestamp = customerHistoryRecord.timestamp; if (recordTimestamp <= lastCustomerHistoryRecordTimestamp) { return; } lastCustomerHistoryRecordTimestamp = recordTimestamp; - List voiceHistoryRecordItems = customerHistoryRecord.voiceHistoryRecordItems; - for (VoiceHistoryRecordItem voiceHistoryRecordItem : voiceHistoryRecordItems) { + List voiceHistoryRecordItems = customerHistoryRecord.voiceHistoryRecordItems; + for (VoiceHistoryRecordItemTO voiceHistoryRecordItem : voiceHistoryRecordItems) { String recordItemType = voiceHistoryRecordItem.recordItemType; if ("CUSTOMER_TRANSCRIPT".equals(recordItemType) || "ASR_REPLACEMENT_TEXT".equals(recordItemType)) { String customerTranscript = voiceHistoryRecordItem.transcriptText; - if (customerTranscript != null && !customerTranscript.isEmpty()) { - // REMOVE WAKEWORD + if (!customerTranscript.isEmpty()) { + // REMOVE WAKE WORD String wakeWordPrefix = this.wakeWord; if (wakeWordPrefix != null && customerTranscript.toLowerCase().startsWith(wakeWordPrefix.toLowerCase())) { customerTranscript = customerTranscript.substring(wakeWordPrefix.length()).trim(); - // STOP IF WAKEWORD ONLY + // STOP IF WAKE WORD ONLY if (customerTranscript.isEmpty()) { return; } @@ -1292,7 +1278,7 @@ public void handlePushCommand(String command, String payload) { break; default: AccountHandler account = this.account; - Device device = this.device; + DeviceTO device = this.device; if (account != null && device != null) { this.disableUpdate = false; updateState(account, device, null, null, null, null, null, null, null); @@ -1300,9 +1286,8 @@ public void handlePushCommand(String command, String payload) { } } - public void updateNotifications(ZonedDateTime currentTime, ZonedDateTime now, - List notifications) { - Device device = this.device; + public void updateNotifications(ZonedDateTime currentTime, ZonedDateTime now, List notifications) { + DeviceTO device = this.device; if (device == null) { return; } @@ -1311,7 +1296,7 @@ public void updateNotifications(ZonedDateTime currentTime, ZonedDateTime now, ZonedDateTime nextAlarm = null; ZonedDateTime nextMusicAlarm = null; ZonedDateTime nextTimer = null; - for (JsonNotificationResponse notification : notifications) { + for (NotificationTO notification : notifications) { if (Objects.equals(notification.deviceSerialNumber, device.serialNumber)) { // notification for this device if ("ON".equals(notification.status)) { diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/FlashBriefingProfileHandler.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/FlashBriefingProfileHandler.java index 49315d4e7e..95316b7b43 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/FlashBriefingProfileHandler.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/FlashBriefingProfileHandler.java @@ -38,7 +38,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonDevices.Device; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceTO; import org.smarthomej.commons.SimpleDynamicCommandDescriptionProvider; /** @@ -137,7 +137,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (!currentConfigurationJson.isEmpty()) { String old = accountHandler.getEnabledFlashBriefingsJson(); accountHandler.setEnabledFlashBriefingsJson(currentConfigurationJson); - Device device = accountHandler.findDeviceJsonBySerialOrName(deviceSerialOrName); + DeviceTO device = accountHandler.findDeviceJsonBySerialOrName(deviceSerialOrName); if (device == null) { logger.warn("Device '{}' not found", deviceSerialOrName); } else { @@ -203,16 +203,16 @@ private String saveCurrentProfile(AccountHandler connection) { return configurationJson; } - public void setCommandDescription(Collection devices) { + public void setCommandDescription(Collection devices) { if (devices.isEmpty()) { return; } List options = new ArrayList<>(); options.add(new CommandOption("", "")); - for (Device device : devices) { + for (DeviceTO device : devices) { final String value = device.serialNumber; - if (value != null && device.getCapabilities().contains("FLASH_BRIEFING")) { + if (value != null && device.capabilities.contains("FLASH_BRIEFING")) { options.add(new CommandOption(value, device.accountName)); } } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/SmartHomeDeviceHandler.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/SmartHomeDeviceHandler.java index cba501cac6..1d1dd9e18d 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/SmartHomeDeviceHandler.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/SmartHomeDeviceHandler.java @@ -47,13 +47,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeGroupIdentifiers; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeGroupIdentity; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeGroups.SmartHomeGroup; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeTags; -import org.smarthomej.binding.amazonechocontrol.internal.dto.SmartHomeBaseDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeGroupIdentifiers; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeGroupIdentity; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeGroups.SmartHomeGroup; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeTags; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.SmartHomeBaseDevice; import org.smarthomej.binding.amazonechocontrol.internal.smarthome.ChannelInfo; import org.smarthomej.binding.amazonechocontrol.internal.smarthome.Constants; import org.smarthomej.binding.amazonechocontrol.internal.smarthome.InterfaceHandler; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/push/PushConnection.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/push/PushConnection.java index 442092de37..988376648d 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/push/PushConnection.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/push/PushConnection.java @@ -79,7 +79,7 @@ public void open(String amazonSite, String accessToken) { Session session = this.session; if (state != CLOSED || session != null) { logger.warn( - "Tried to open a new session, but there the current state is {} - session hash {}. Please enable TRACE logging and report a bug.", + "Tried to open a new session, but the the current state is {} - session hash {}. Please enable TRACE logging and report a bug.", state, session != null ? session.hashCode() : ""); return; } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/AbstractInterfaceHandler.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/AbstractInterfaceHandler.java index 14a0fb0263..6f82be2d85 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/AbstractInterfaceHandler.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/AbstractInterfaceHandler.java @@ -31,9 +31,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability.Properties; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability.Properties; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/Constants.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/Constants.java index 73e38605b7..a58690b55f 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/Constants.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/Constants.java @@ -13,13 +13,14 @@ */ package org.smarthomej.binding.amazonechocontrol.internal.smarthome; +import static org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.BINDING_ID; + import java.util.Map; import java.util.Set; import java.util.function.Function; import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.thing.type.ChannelTypeUID; -import org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; /** @@ -49,64 +50,40 @@ public class Constants { 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_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_AIR_QUALITY_INDOOR_AIR_QUALITY = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "indoorAirQuality"); - public static final ChannelTypeUID CHANNEL_TYPE_AIR_QUALITY_HUMIDITY = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "humidity"); - public static final ChannelTypeUID CHANNEL_TYPE_AIR_QUALITY_PM25 = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "pm25"); - public static final ChannelTypeUID CHANNEL_TYPE_AIR_QUALITY_CARBON_MONOXIDE = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "carbonMonoxide"); - public static final ChannelTypeUID CHANNEL_TYPE_AIR_QUALITY_VOC = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "voc"); - public static final ChannelTypeUID CHANNEL_TYPE_FAN_SPEED = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "fanSpeed"); - public static final ChannelTypeUID CHANNEL_TYPE_POWER_STATE = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "powerState"); - public static final ChannelTypeUID CHANNEL_TYPE_LOCK_STATE = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "lockState"); - public static final ChannelTypeUID CHANNEL_TYPE_UID_ACOUSTIC_EVENT_DETECTION = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "acousticEventDetectionState"); - public static final ChannelTypeUID CHANNEL_TYPE_BRIGHTNESS = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "brightness"); - public static final ChannelTypeUID CHANNEL_TYPE_COLOR_NAME = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "colorName"); - public static final ChannelTypeUID CHANNEL_TYPE_COLOR = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "color"); - public static final ChannelTypeUID CHANNEL_TYPE_COLOR_TEMPERATURE_NAME = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "colorTemperatureName"); - public static final ChannelTypeUID CHANNEL_TYPE_COLOR_TEMPERATURE_IN_KELVIN = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "colorTemperatureInKelvin"); - public static final ChannelTypeUID CHANNEL_TYPE_PERCENTAGE = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "percentage"); - public static final ChannelTypeUID CHANNEL_TYPE_POWER_LEVEL = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "powerLevel"); - public static final ChannelTypeUID CHANNEL_TYPE_ARM_STATE = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "armState"); - public static final ChannelTypeUID CHANNEL_TYPE_BURGLARY_ALARM = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "burglaryAlarm"); - public static final ChannelTypeUID CHANNEL_TYPE_CARBON_MONOXIDE_ALARM = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "carbonMonoxideAlarm"); - public static final ChannelTypeUID CHANNEL_TYPE_FIRE_ALARM = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "fireAlarm"); - public static final ChannelTypeUID CHANNEL_TYPE_WATER_ALARM = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "waterAlarm"); - public static final ChannelTypeUID CHANNEL_TYPE_MOTION_DETECTED = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "motionDetected"); - public static final ChannelTypeUID CHANNEL_TYPE_CONTACT_STATUS = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "contact"); - public static final ChannelTypeUID CHANNEL_TYPE_GEOLOCATION = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "geoLocation"); - public static final ChannelTypeUID CHANNEL_TYPE_CONNECTIVITY = new ChannelTypeUID( - AmazonEchoControlBindingConstants.BINDING_ID, "connectivity"); + public static final ChannelTypeUID CHANNEL_TYPE_TEMPERATURE = new ChannelTypeUID(BINDING_ID, "temperature"); + public static final ChannelTypeUID CHANNEL_TYPE_TARGETSETPOINT = new ChannelTypeUID(BINDING_ID, "targetSetpoint"); + public static final ChannelTypeUID CHANNEL_TYPE_LOWERSETPOINT = new ChannelTypeUID(BINDING_ID, "lowerSetpoint"); + public static final ChannelTypeUID CHANNEL_TYPE_UPPERSETPOINT = new ChannelTypeUID(BINDING_ID, "upperSetpoint"); + public static final ChannelTypeUID CHANNEL_TYPE_THERMOSTATMODE = new ChannelTypeUID(BINDING_ID, "thermostatMode"); + public static final ChannelTypeUID CHANNEL_TYPE_AIR_QUALITY_INDOOR_AIR_QUALITY = new ChannelTypeUID(BINDING_ID, + "indoorAirQuality"); + public static final ChannelTypeUID CHANNEL_TYPE_AIR_QUALITY_HUMIDITY = new ChannelTypeUID(BINDING_ID, "humidity"); + public static final ChannelTypeUID CHANNEL_TYPE_AIR_QUALITY_PM25 = new ChannelTypeUID(BINDING_ID, "pm25"); + public static final ChannelTypeUID CHANNEL_TYPE_AIR_QUALITY_CARBON_MONOXIDE = new ChannelTypeUID(BINDING_ID, + "carbonMonoxide"); + public static final ChannelTypeUID CHANNEL_TYPE_AIR_QUALITY_VOC = new ChannelTypeUID(BINDING_ID, "voc"); + public static final ChannelTypeUID CHANNEL_TYPE_FAN_SPEED = new ChannelTypeUID(BINDING_ID, "fanSpeed"); + public static final ChannelTypeUID CHANNEL_TYPE_POWER_STATE = new ChannelTypeUID(BINDING_ID, "powerState"); + public static final ChannelTypeUID CHANNEL_TYPE_LOCK_STATE = new ChannelTypeUID(BINDING_ID, "lockState"); + public static final ChannelTypeUID CHANNEL_TYPE_UID_ACOUSTIC_EVENT_DETECTION = new ChannelTypeUID(BINDING_ID, + "acousticEventDetectionState"); + public static final ChannelTypeUID CHANNEL_TYPE_BRIGHTNESS = new ChannelTypeUID(BINDING_ID, "brightness"); + public static final ChannelTypeUID CHANNEL_TYPE_COLOR_NAME = new ChannelTypeUID(BINDING_ID, "colorName"); + public static final ChannelTypeUID CHANNEL_TYPE_COLOR = new ChannelTypeUID(BINDING_ID, "color"); + public static final ChannelTypeUID CHANNEL_TYPE_COLOR_TEMPERATURE_NAME = new ChannelTypeUID(BINDING_ID, + "colorTemperatureName"); + public static final ChannelTypeUID CHANNEL_TYPE_COLOR_TEMPERATURE_IN_KELVIN = new ChannelTypeUID(BINDING_ID, + "colorTemperatureInKelvin"); + public static final ChannelTypeUID CHANNEL_TYPE_PERCENTAGE = new ChannelTypeUID(BINDING_ID, "percentage"); + public static final ChannelTypeUID CHANNEL_TYPE_POWER_LEVEL = new ChannelTypeUID(BINDING_ID, "powerLevel"); + public static final ChannelTypeUID CHANNEL_TYPE_ARM_STATE = new ChannelTypeUID(BINDING_ID, "armState"); + public static final ChannelTypeUID CHANNEL_TYPE_BURGLARY_ALARM = new ChannelTypeUID(BINDING_ID, "burglaryAlarm"); + public static final ChannelTypeUID CHANNEL_TYPE_CARBON_MONOXIDE_ALARM = new ChannelTypeUID(BINDING_ID, + "carbonMonoxideAlarm"); + public static final ChannelTypeUID CHANNEL_TYPE_FIRE_ALARM = new ChannelTypeUID(BINDING_ID, "fireAlarm"); + public static final ChannelTypeUID CHANNEL_TYPE_WATER_ALARM = new ChannelTypeUID(BINDING_ID, "waterAlarm"); + public static final ChannelTypeUID CHANNEL_TYPE_MOTION_DETECTED = new ChannelTypeUID(BINDING_ID, "motionDetected"); + public static final ChannelTypeUID CHANNEL_TYPE_CONTACT_STATUS = new ChannelTypeUID(BINDING_ID, "contact"); + public static final ChannelTypeUID CHANNEL_TYPE_GEOLOCATION = new ChannelTypeUID(BINDING_ID, "geoLocation"); + public static final ChannelTypeUID CHANNEL_TYPE_CONNECTIVITY = new ChannelTypeUID(BINDING_ID, "connectivity"); } diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerAcousticEventSensor.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerAcousticEventSensor.java index b609818f5b..e32ca054e2 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerAcousticEventSensor.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerAcousticEventSensor.java @@ -23,8 +23,8 @@ import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.types.Command; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerBrightnessController.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerBrightnessController.java index 88a1826cf6..7d79e3f88f 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerBrightnessController.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerBrightnessController.java @@ -26,8 +26,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerColorController.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerColorController.java index 03822a917d..b1dc243215 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerColorController.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerColorController.java @@ -37,8 +37,8 @@ import org.slf4j.LoggerFactory; import org.smarthomej.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerColorTemperatureController.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerColorTemperatureController.java index 599a2ce76e..b488a96a27 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerColorTemperatureController.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerColorTemperatureController.java @@ -25,8 +25,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerContactSensor.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerContactSensor.java index 6294255829..c863ade465 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerContactSensor.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerContactSensor.java @@ -22,8 +22,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerEndpointHealth.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerEndpointHealth.java index 29869f647e..c798e9a8cb 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerEndpointHealth.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerEndpointHealth.java @@ -29,8 +29,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonElement; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerHumiditySensor.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerHumiditySensor.java index e2d45b4631..ee2e94b563 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerHumiditySensor.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerHumiditySensor.java @@ -28,8 +28,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerLocation.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerLocation.java index 29f22ff998..c03bc40cfb 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerLocation.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerLocation.java @@ -23,8 +23,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonElement; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerLockController.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerLockController.java index db9ab34285..10bdd802ea 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerLockController.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerLockController.java @@ -23,8 +23,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerMotionSensor.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerMotionSensor.java index 79ac7372be..36493321d2 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerMotionSensor.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerMotionSensor.java @@ -22,8 +22,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPercentageController.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPercentageController.java index d15b2dadc2..8e4b50dfb5 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPercentageController.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPercentageController.java @@ -26,8 +26,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPowerController.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPowerController.java index 9d7d477b7b..ed16ed148f 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPowerController.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPowerController.java @@ -24,8 +24,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPowerLevelController.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPowerLevelController.java index 9dd7c24f5b..c3cb20df45 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPowerLevelController.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerPowerLevelController.java @@ -26,8 +26,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerRangeController.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerRangeController.java index 87c707c9b4..9dc11d0975 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerRangeController.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerRangeController.java @@ -36,8 +36,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonElement; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerSecurityPanelController.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerSecurityPanelController.java index 0ca3f6e787..2734fee861 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerSecurityPanelController.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerSecurityPanelController.java @@ -25,8 +25,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerTemperatureSensor.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerTemperatureSensor.java index b44118a4d9..b0ded2e1e2 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerTemperatureSensor.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerTemperatureSensor.java @@ -29,8 +29,8 @@ import org.openhab.core.types.Command; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerThermostatController.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerThermostatController.java index e942ac547b..66921cd60f 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerThermostatController.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/HandlerThermostatController.java @@ -34,8 +34,8 @@ import org.openhab.core.types.Type; import org.openhab.core.types.UnDefType; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import org.smarthomej.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/InterfaceHandler.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/InterfaceHandler.java index ded37b05d4..19e97ccca3 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/InterfaceHandler.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/InterfaceHandler.java @@ -23,8 +23,8 @@ import org.openhab.core.types.CommandOption; import org.openhab.core.types.StateDescription; import org.smarthomej.binding.amazonechocontrol.internal.connection.Connection; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeCapability; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeCapability; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; import com.google.gson.JsonObject; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/SmartHomeDeviceStateGroupUpdateCalculator.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/SmartHomeDeviceStateGroupUpdateCalculator.java index c41cee0bc6..2bc1759667 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/SmartHomeDeviceStateGroupUpdateCalculator.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/SmartHomeDeviceStateGroupUpdateCalculator.java @@ -23,8 +23,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice; -import org.smarthomej.binding.amazonechocontrol.internal.dto.JsonSmartHomeDevice.DriverIdentity; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice; +import org.smarthomej.binding.amazonechocontrol.internal.dto.smarthome.JsonSmartHomeDevice.DriverIdentity; /** * Handles the update interval calculation diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/util/HttpRequestBuilder.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/util/HttpRequestBuilder.java index c25f1e432b..e27164cff5 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/util/HttpRequestBuilder.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/util/HttpRequestBuilder.java @@ -33,6 +33,8 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import javax.ws.rs.core.MediaType; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jetty.client.HttpClient; @@ -203,6 +205,7 @@ public Builder redirect(boolean redirect) { public Builder withContent(@Nullable Object content) { if (content == null || content instanceof String) { this.body = (String) content; + this.isJson = false; } else if (content instanceof JsonObject) { this.body = content.toString(); this.isJson = true; @@ -213,6 +216,19 @@ public Builder withContent(@Nullable Object content) { return this; } + /** + * Override the autodetected type + *

+ * This needs to be called AFTER the content has been set + * + * @param isJson if the request content should be considered as JSON + * @return the request builder + */ + public Builder withJson(boolean isJson) { + this.isJson = isJson; + return this; + } + public CompletableFuture send() { RequestParams params = new RequestParams(httpMethod, body, isJson, headers); CompletableFuture httpResponse = new CompletableFuture<>(); @@ -231,9 +247,18 @@ public CompletableFuture send(Class returnType) { if (returnType.equals(HttpRequestBuilder.HttpResponse.class)) { return (T) response; } + String contentType = response.headers.get(CONTENT_TYPE); + if (!contentType.startsWith(MediaType.APPLICATION_JSON)) { + logger.warn("JSON conversion to {} was requested but the response has a Content-Type {}", + returnType.getName(), contentType); + } try { + T returnValue = gson.fromJson(response.content(), returnType); // gson.fromJson is non-null if json is non-null and not empty - return gson.fromJson(response.content(), returnType); + if (returnValue == null) { + throw new JsonParseException("Empty result"); + } + return returnValue; } catch (JsonParseException e) { logger.warn("Parsing json failed: {}", isJson, e); throw e; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/util/NonNullListTypeAdapterFactory.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/util/NonNullListTypeAdapterFactory.java new file mode 100644 index 0000000000..251737f81b --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/util/NonNullListTypeAdapterFactory.java @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.util; + +import java.io.IOException; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; + +/** + * The {@link NonNullListTypeAdapterFactory} is a {@link TypeAdapterFactory} for allowing annotation based + * null-serialization + *

+ * Fields that shall be serialized even if they are null need a {@link SerializeNull} annotation + * + * @author Jan N. Klug - Initial contribution + */ +@NonNullByDefault +public class NonNullListTypeAdapterFactory implements TypeAdapterFactory { + @Override + @SuppressWarnings("unchecked") + public @Nullable TypeAdapter create(@NonNullByDefault({}) Gson gson, + @NonNullByDefault({}) TypeToken type) { + + Class rawType = (Class) type.getRawType(); + if (rawType != List.class) { + return null; + } + TypeAdapter delegateAdapter = gson.getDelegateAdapter(NonNullListTypeAdapterFactory.this, type); + + return new DeserializeNonNullTypeAdapter<>(delegateAdapter); + } + + private static class DeserializeNonNullTypeAdapter extends TypeAdapter { + private final TypeAdapter delegateTypeAdapter; + + public DeserializeNonNullTypeAdapter(TypeAdapter delegateTypeAdapter) { + this.delegateTypeAdapter = delegateTypeAdapter; + } + + @Override + public void write(JsonWriter writer, @Nullable T value) throws IOException { + delegateTypeAdapter.write(writer, value); + } + + @Override + @SuppressWarnings("unchecked") + public @Nullable T read(JsonReader reader) throws IOException { + final JsonToken peek = reader.peek(); + if (peek == JsonToken.NULL) { + reader.nextNull(); + return (T) List.of(); + } + return delegateTypeAdapter.read(reader); + } + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/util/Util.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/util/Util.java new file mode 100644 index 0000000000..7b37abfd5b --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/util/Util.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.util; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link Util} contains helper methods + * + * @author Jan N. Klug - Initial contribution + */ +@NonNullByDefault +public class Util { + + private Util() { + // prevent instantiation + } + + public static Optional findInList(List list, Function keyExtractor, U searchKey) { + return list.stream().filter(e -> Objects.equals(searchKey, keyExtractor.apply(e))).findAny(); + } + + public static List filterList(List list, Function keyExtractor, U searchKey) { + return list.stream().filter(e -> Objects.equals(searchKey, keyExtractor.apply(e))).toList(); + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/resources/device_type.properties b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/resources/device_type.properties new file mode 100644 index 0000000000..fa047bf0fe --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/resources/device_type.properties @@ -0,0 +1,79 @@ +# DeviceTypeIds to human readable description +# originally found here: https://github.com/Apollon77/ioBroker.alexa2/blob/master/main.js +A10A33FOX2NUBK = Echo Spot +A10L5JEZTKKCZ8 = Vobot-Clock +A12GXV8XMS007S = FireTV +A15ERDAKK5HQQG = Sonos +A17LGWINFBUTZZ = Anker Roav Viva Alexa +A18O6U1UQFJ0XK = Echo Plus 2nd Gen +A1C66CX2XD756O = Fire HD 8 +A1DL2DVDQVK3Q = Apps +A1ETW4IXK2PYBP = Echo Auto +A1H0CMF1XM0ZP4 = Echo Dot/Bose +A1J16TEDOYCZTN = Fire Tab +A1JJ0KFC4ZPNJ3 = Echo Input +A1NL4BVLQ4L3N3 = Echo Show +A1P31Q3MOWSHOD = Anker Zalo Halo Speaker +A1Q7QCGNMXAKYW = Fire Tab 7 +A1QKZ9D0IJY332 = Samsung QLED +A1RABVCI4QCIKC = Echo Dot 3rd Gen +A1RTAM01W29CUP = Windows App +A1X7HJX9QL16M5 = Bespoken.io +A1Z88NGR2BK6A2 = Echo Show 8 +A1ZB65LA390I4K = Fire HD 10 +A21Z3CGI8UIP0F = Apps +A265XOI9586NML = FireTV Stick v3 +A2825NDLA7WDZV = Apps +A2E0SNTXJVT7WK = FireTV V1 +A2GFL5ZMWNE0PX = FireTV +A2H4LV5GIZ1JFT = Echo 4 Clock +A2IVLV5VM2W81 = Apps +A2J0R2SD7G9LPA = Tablet +A2JKHJ0PX4J3L3 = FireTV Cube +A2L8KG0CT86ADW = RaspPi +A2LWARUGJLBYEW = FireTV Stick V2 +A2M35JJZWCQOMZ = Echo Plus +A2M4YX06LWP8WI = Fire Tab +A2OSP3UA4VC85F = Sonos +A2T0P32DY3F7VB = echosim.io +A2TF17PFR55MTB = Apps +A2U21SRK4QGSE1 = Echo Dot 4th Gen +A2Z8O30CD35N8F = Sonos Arc +A303PJF6ISQ7IC = Echo Auto +A30YDR2MK8HMRV = Echo Dot 3rd Gen Clock +A31DTMEEVDDOIV = FireTV Stick Lite 2020 +A32DOYMUN6DTXA = Echo Dot 3rd Gen +A378ND93PD0NC4 = VR Radio +A37SHHQ3NUL7B5 = Bose Homespeaker +A38BPK7OW001EX = Raspberry Alexa +A38EHHIB10L47V = Echo Dot +A39Y3UG1XLEJLZ = Fitbit Sense +A3C9PE6TNYLTCH = Multiroom +A3FX4UWTP28V1P = Echo 3 +A3GZUE7F9MEB4U = FireTV Cube +A3H674413M2EKB = echosim.io +A3HF4YRA2L7XGC = FireTV Cube +A3NPD82ABCPIDP = Sonos Beam +A3R8XIAIU4HJAX = Echo Show +A3R9S4ZZECZ6YL = Fire Tab HD 10 +A3RBAYBE7VM004 = Echo Studio +A3RMGO6LYLH7YN = Echo 4 Bridge +A3S5BH2HU6VAYF = Echo Dot 2nd Gen +A3SSG6GR8UU7SN = Echo Sub +A3TCJ8RTT3NVI7 = Listens for Alexa +A3V3VA38K169FO = Fire Tab +A3VRME03NAXFUB = Echo Flex +A4ZP7ZC4PI6TO = Echo Show 5th Gen +A7WXQPH584YP = Echo 2nd Gen +A8DM4FYR6D3HT = LG WebOS TV +AB72C64C86AW2 = Echo +ADVBD696BHNV5 = FireTV Stick V1 +AILBSA2LNTOYL = reverb App +AINRG27IL8AS0 = Megablast Speaker +AKOAGQTKAS9YB = Echo Connect +AKPGW064GI9HE = FireTV Stick 4K +AP1F6KUH00XPV = Stereo/Subwoofer Pair +AVD3HM0HOJAAL = Sonos One 2nd Gen +AVE5HX13UR5NO = Logitech Zero Touch +AVU7CPPF2ZRAS = Fire HD 8 +AWZZ5CVHX2CD = Echo Show 2nd Gen diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/test/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/GsonTypeAdapterFactoriesTest.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/test/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/GsonTypeAdapterFactoriesTest.java new file mode 100644 index 0000000000..0845736ad6 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/test/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/GsonTypeAdapterFactoriesTest.java @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.smarthome; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +import java.util.List; +import java.util.Objects; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.jupiter.api.Test; +import org.smarthomej.binding.amazonechocontrol.internal.util.NonNullListTypeAdapterFactory; +import org.smarthomej.binding.amazonechocontrol.internal.util.SerializeNull; +import org.smarthomej.binding.amazonechocontrol.internal.util.SerializeNullTypeAdapterFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; + +/** + * The {@link GsonTypeAdapterFactoriesTest} contains tests for the various {@link TypeAdapterFactory} implementations + * + * @author Jan N. Klug - Initial contribution + */ +@NonNullByDefault +public class GsonTypeAdapterFactoriesTest { + @Test + public void testSerializeNullFactoryReturnsNullForNonAnnotatedClass() { + TypeAdapterFactory factory = new SerializeNullTypeAdapterFactory(); + TypeToken typeToken = TypeToken.get(NonAnnotatedTestTO.class); + TypeAdapter typeAdapter = factory.create(new Gson(), typeToken); + + assertThat(typeAdapter, is(nullValue())); + } + + @Test + public void testSerializeNullFactoryReturnsTypeAdapterForAnnotatedClass() { + TypeAdapterFactory factory = new SerializeNullTypeAdapterFactory(); + TypeToken typeToken = TypeToken.get(AnnotatedTestTO.class); + TypeAdapter typeAdapter = factory.create(new Gson(), typeToken); + + assertThat(typeAdapter, is(notNullValue())); + } + + @Test + public void testNonNullListFactoryReturnsNullForNonListClass() { + TypeAdapterFactory factory = new NonNullListTypeAdapterFactory(); + TypeToken typeToken = TypeToken.get(String.class); + TypeAdapter typeAdapter = factory.create(new Gson(), typeToken); + + assertThat(typeAdapter, is(nullValue())); + } + + @Test + public void testNonNullListFactoryReturnsTypeAdapterForAnnotatedClass() { + TypeAdapterFactory factory = new NonNullListTypeAdapterFactory(); + TypeToken typeToken = TypeToken.getParameterized(List.class, String.class); + TypeAdapter typeAdapter = factory.create(new Gson(), typeToken); + + assertThat(typeAdapter, is(notNullValue())); + } + + @Test + public void testSerializeAnnotatedNull() { + Gson gson = new GsonBuilder().registerTypeAdapterFactory(new SerializeNullTypeAdapterFactory()).create(); + + String serialized = gson.toJson(new AnnotatedTestTO()); + String expected = "{\"annotatedNullValue\":null,\"annotatedNonNullValue\":\"bar\"," + + "\"nonNullValue\":\"foo\",\"serializedNameNonNullValue\":\"foo\"}"; + + assertThat(serialized, is(expected)); + } + + @Test + public void testNullListsAreNotDeserialized() { + Gson gson = new GsonBuilder().registerTypeAdapterFactory(new NonNullListTypeAdapterFactory()).create(); + + String in = "{\"list\" : [\"foo\"],\"nullList\" : null}"; + + ListTestTO listTest = Objects.requireNonNull(gson.fromJson(in, ListTestTO.class)); + assertThat(listTest.list, is(List.of("foo"))); + assertThat(listTest.nullList, is(List.of())); + assertThat(listTest.missingList, is(List.of())); + } + + @Test + public void combinedTest() { + String in = "{\"list\" : null}"; + + Gson gson = new GsonBuilder().registerTypeAdapterFactory(new SerializeNullTypeAdapterFactory()) + .registerTypeAdapterFactory(new NonNullListTypeAdapterFactory()).create(); + + CombinedTestTO combined = Objects.requireNonNull(gson.fromJson(in, CombinedTestTO.class)); + assertThat(combined.list, is(List.of())); + + String expected = "{\"serializeNullString\":null,\"list\":[]}"; + String out = gson.toJson(combined); + assertThat(out, is(expected)); + } + + private static class ListTestTO { + public List list = List.of(); + public List nullList = List.of(); + public List missingList = List.of(); + } + + private static class CombinedTestTO { + @SerializeNull + public @Nullable String serializeNullString = null; + public @Nullable String noSerializeNullString = null; + public List list = List.of(); + } + + private static class AnnotatedTestTO extends NonAnnotatedTestTO { + @SerializeNull + public @Nullable String annotatedNullValue = null; + + @SerializeNull + public @Nullable String annotatedNonNullValue = "bar"; + } + + private static class NonAnnotatedTestTO { + public @Nullable String nullValue = null; + + public String nonNullValue = "foo"; + + @SerializedName("serializedNameNullValue") + public @Nullable String nullValue2 = null; + + @SerializedName("serializedNameNonNullValue") + public String nonNullNullValue2 = "foo"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/test/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/SerializeNullTest.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/test/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/SerializeNullTest.java deleted file mode 100644 index 8b8f80366d..0000000000 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/test/java/org/smarthomej/binding/amazonechocontrol/internal/smarthome/SerializeNullTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.amazonechocontrol.internal.smarthome; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.smarthomej.binding.amazonechocontrol.internal.dto.request.PlayerSeekMediaTO; -import org.smarthomej.binding.amazonechocontrol.internal.util.SerializeNull; -import org.smarthomej.binding.amazonechocontrol.internal.util.SerializeNullTypeAdapterFactory; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.TypeAdapter; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; - -/** - * The {@link SerializeNullTest} annotation is used to indicate that a field should be serialized even if it is null - * - * @author Jan N. Klug - Initial contribution - */ -@NonNullByDefault -public class SerializeNullTest { - @Test - public void testSerialization() { - Gson gson = new GsonBuilder().registerTypeAdapterFactory(new SerializeNullTypeAdapterFactory()).create(); - - String serialized = gson.toJson(new AnnotatedTestTO()); - String expected = "{\"annotatedNullValue\":null,\"annotatedNonNullValue\":\"bar\"," - + "\"nonNullValue\":\"foo\",\"serializedNameNonNullValue\":\"foo\"}"; - - assertThat(serialized, is(expected)); - } - - @Test - public void testFactoryReturnsTypeAdapterForAnnotatedClass() { - TypeAdapterFactory factory = new SerializeNullTypeAdapterFactory(); - TypeToken typeToken = TypeToken.get(AnnotatedTestTO.class); - TypeAdapter typeAdapter = factory.create(new Gson(), typeToken); - - assertThat(typeAdapter, is(notNullValue())); - } - - @Test - public void testFactoryReturnsNullForNonAnnotatedClass() { - TypeAdapterFactory factory = new SerializeNullTypeAdapterFactory(); - TypeToken typeToken = TypeToken.get(NonAnnotatedTestTO.class); - TypeAdapter typeAdapter = factory.create(new Gson(), typeToken); - - assertThat(typeAdapter, is(nullValue())); - } - - @Test - public void xxxTst() { - PlayerSeekMediaTO command = new PlayerSeekMediaTO(); - command.mediaPosition = -1; - - assertThat(command, is(notNullValue())); - } - - private static class AnnotatedTestTO extends NonAnnotatedTestTO { - @SerializeNull - public @Nullable String annotatedNullValue = null; - - @SerializeNull - public @Nullable String annotatedNonNullValue = "bar"; - } - - private static class NonAnnotatedTestTO { - public @Nullable String nullValue = null; - - public String nonNullValue = "foo"; - - @SerializedName("serializedNameNullValue") - public @Nullable String nullValue2 = null; - - @SerializedName("serializedNameNonNullValue") - public String nonNullNullValue2 = "foo"; - } -}