From 7c839a7c1a25e13fbe5ae926861eb9360e8c8052 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sat, 11 May 2019 13:12:52 +0200 Subject: [PATCH 01/20] [amazonechocontrol] Fix json parsing Signed-off-by: Michael Geramb (github: mgeramb) --- .../amazonechocontrol/internal/Connection.java | 2 +- .../internal/handler/AccountHandler.java | 2 +- .../internal/jsons/JsonActivities.java | 6 +++--- .../jsons/JsonAnnouncementContent.java | 4 ++-- .../internal/jsons/JsonAnnouncementTarget.java | 2 +- .../internal/jsons/JsonAscendingAlarm.java | 2 +- .../internal/jsons/JsonAutomation.java | 4 ++-- .../internal/jsons/JsonBluetoothStates.java | 4 ++-- .../jsons/JsonCommandPayloadPushActivity.java | 2 +- .../jsons/JsonCommandPayloadPushDevice.java | 2 +- .../jsons/JsonDeviceNotificationState.java | 2 +- .../internal/jsons/JsonDevices.java | 2 +- .../jsons/JsonExchangeTokenResponse.java | 6 +++--- .../internal/jsons/JsonMediaState.java | 2 +- .../internal/jsons/JsonPlayerState.java | 12 ++++++------ .../internal/jsons/JsonPlaylists.java | 2 +- .../internal/jsons/JsonRegisterAppRequest.java | 8 ++++---- .../jsons/JsonRegisterAppResponse.java | 18 ++++++++++-------- .../internal/jsons/JsonWakeWords.java | 2 +- 19 files changed, 43 insertions(+), 41 deletions(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index 052f1b0430cc6..166aecf8276b8 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -1051,7 +1051,7 @@ public void sendAnnouncement(Device device, String text, @Nullable String title, JsonAnnouncementTarget target = new JsonAnnouncementTarget(); target.customerId = device.deviceOwnerCustomerId; TargetDevice[] devices = new TargetDevice[1]; - TargetDevice deviceTarget = target.new TargetDevice(); + TargetDevice deviceTarget = new TargetDevice(); deviceTarget.deviceSerialNumber = device.serialNumber; deviceTarget.deviceTypeId = device.deviceType; devices[0] = deviceTarget; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java index bc9b622ea1e33..3a3db9cd87cc5 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java @@ -185,7 +185,7 @@ public void addFlashBriefingProfileHandler(FlashBriefingProfileHandler flashBrie flashBriefingProfileHandlers.add(flashBriefingProfileHandler); } Connection connection = this.connection; - if (connection != null) { + if (connection != null && connection.getIsLoggedIn()) { if (currentFlashBriefingJson.isEmpty()) { updateFlashBriefingProfiles(connection); } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonActivities.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonActivities.java index 910b1f347cf54..b09660af70a1e 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonActivities.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonActivities.java @@ -29,7 +29,7 @@ public class JsonActivities { public @Nullable Activity @Nullable [] activities; - public class Activity { + public static class Activity { public @Nullable String activityStatus; public @Nullable Long creationTimestamp; public @Nullable String description; @@ -45,14 +45,14 @@ public class Activity { public @Nullable String utteranceId; public @Nullable Long version; - public class SourceDeviceId { + public static class SourceDeviceId { public @Nullable String deviceAccountId; public @Nullable String deviceType; public @Nullable String serialNumber; } - public class Description { + public static class Description { public @Nullable String summary; public @Nullable String firstUtteranceId; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAnnouncementContent.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAnnouncementContent.java index c33aaa6323d42..ce2296773e417 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAnnouncementContent.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAnnouncementContent.java @@ -28,13 +28,13 @@ public class JsonAnnouncementContent { public final Display display = new Display(); public final Speak speak = new Speak(); - public class Display { + public static class Display { public @Nullable String title; public @Nullable String body; } - public class Speak { + public static class Speak { public String type = "text"; public @Nullable String value; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAnnouncementTarget.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAnnouncementTarget.java index fcb8e884541f2..6e99bec84f1c6 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAnnouncementTarget.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAnnouncementTarget.java @@ -26,7 +26,7 @@ public class JsonAnnouncementTarget { public @Nullable String customerId; public @Nullable TargetDevice @Nullable [] devices; - public class TargetDevice { + public static class TargetDevice { public @Nullable String deviceSerialNumber; public @Nullable String deviceTypeId; } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAscendingAlarm.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAscendingAlarm.java index 68ebe7d70d936..95c4d6c81a8a5 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAscendingAlarm.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAscendingAlarm.java @@ -25,7 +25,7 @@ public class JsonAscendingAlarm { public @Nullable AscendingAlarmModel @Nullable [] ascendingAlarmModelList; - public class AscendingAlarmModel { + public static class AscendingAlarmModel { public @Nullable Boolean ascendingAlarmEnabled; public @Nullable String deviceSerialNumber; public @Nullable String deviceType; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAutomation.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAutomation.java index 9f9b7cf99faf3..d3be585e7c7f4 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAutomation.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonAutomation.java @@ -32,13 +32,13 @@ public class JsonAutomation { public long creationTimeEpochMillis; public long lastUpdatedTimeEpochMillis; - public class Trigger { + public static class Trigger { public @Nullable Payload payload; public @Nullable String id; public @Nullable String type; } - public class Payload { + public static class Payload { public @Nullable String customerId; public @Nullable String utterance; public @Nullable String locale; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonBluetoothStates.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonBluetoothStates.java index 5361887d5afb2..4d2ba0adb07cc 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonBluetoothStates.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonBluetoothStates.java @@ -44,7 +44,7 @@ public class JsonBluetoothStates { public @Nullable BluetoothState @Nullable [] bluetoothStates; - public class PairedDevice { + public static class PairedDevice { public @Nullable String address; public boolean connected; public @Nullable String deviceClass; @@ -53,7 +53,7 @@ public class PairedDevice { } - public class BluetoothState { + public static class BluetoothState { public @Nullable String deviceSerialNumber; public @Nullable String deviceType; public @Nullable String friendlyName; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonCommandPayloadPushActivity.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonCommandPayloadPushActivity.java index 9fc7800324326..c53128cf0966a 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonCommandPayloadPushActivity.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonCommandPayloadPushActivity.java @@ -28,7 +28,7 @@ public class JsonCommandPayloadPushActivity { public @Nullable Key key; - public class Key { + public static class Key { public @Nullable String entryId; public @Nullable String registeredUserId; } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonCommandPayloadPushDevice.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonCommandPayloadPushDevice.java index f606635ab5e22..c7b42709229ec 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonCommandPayloadPushDevice.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonCommandPayloadPushDevice.java @@ -25,7 +25,7 @@ public class JsonCommandPayloadPushDevice { public @Nullable DopplerId dopplerId; - public class DopplerId { + public static class DopplerId { public @Nullable String deviceSerialNumber; public @Nullable String deviceType; } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonDeviceNotificationState.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonDeviceNotificationState.java index 2f0a6ccb7701b..596c172a2048b 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonDeviceNotificationState.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonDeviceNotificationState.java @@ -25,7 +25,7 @@ public class JsonDeviceNotificationState { public @Nullable DeviceNotificationState @Nullable [] deviceNotificationStates; - public class DeviceNotificationState { + public static class DeviceNotificationState { public @Nullable String deviceSerialNumber; public @Nullable String deviceType; public @Nullable String softwareVersion; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonDevices.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonDevices.java index 16f00449aac06..2ff3a02ad65d1 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonDevices.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonDevices.java @@ -23,7 +23,7 @@ @NonNullByDefault public class JsonDevices { - public class Device { + public static class Device { public @Nullable String accountName; public @Nullable String serialNumber; public @Nullable String deviceOwnerCustomerId; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonExchangeTokenResponse.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonExchangeTokenResponse.java index e95a1df7a873e..48807bea68910 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonExchangeTokenResponse.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonExchangeTokenResponse.java @@ -26,15 +26,15 @@ public class JsonExchangeTokenResponse { public @Nullable Response response; - public class Response { + public static class Response { public @Nullable Tokens tokens; } - public class Tokens { + public static class Tokens { public @Nullable Map cookies; } - public class Cookie { + public static class Cookie { public @Nullable String Path; public @Nullable Boolean Secure; public @Nullable String Value; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonMediaState.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonMediaState.java index 69033b938c5e5..0d23fb92d1995 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonMediaState.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonMediaState.java @@ -47,7 +47,7 @@ public class JsonMediaState { // public long timeLastShuffled; parsing fails with some values, so do not use it public int volume; - public class QueueEntry { + public static class QueueEntry { public @Nullable String album; public @Nullable String albumAsin; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonPlayerState.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonPlayerState.java index 79e4f508b6c97..f3013b518cc13 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonPlayerState.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonPlayerState.java @@ -24,7 +24,7 @@ public class JsonPlayerState { public @Nullable PlayerInfo playerInfo; - public class PlayerInfo { + public static class PlayerInfo { public @Nullable String state; public @Nullable InfoText infoText; public @Nullable InfoText miniInfoText; @@ -37,7 +37,7 @@ public class PlayerInfo { public @Nullable Progress progress; - public class InfoText { + public static class InfoText { public boolean multiLineMode; public @Nullable String subText1; public @Nullable String subText2; @@ -45,24 +45,24 @@ public class InfoText { } - public class Provider { + public static class Provider { public @Nullable String providerDisplayName; public @Nullable String providerName; } - public class Volume { + public static class Volume { public boolean muted; public int volume; } - public class MainArt { + public static class MainArt { public @Nullable String altText; public @Nullable String artType; public @Nullable String contentType; public @Nullable String url; } - public class Progress { + public static class Progress { public @Nullable Boolean allowScrubbing; public @Nullable Object locationInfo; public @Nullable Long mediaLength; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonPlaylists.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonPlaylists.java index 1e8b8bcdcdeee..d079c686df8c5 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonPlaylists.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonPlaylists.java @@ -27,7 +27,7 @@ public class JsonPlaylists { public @Nullable Map playlists; - public class PlayList { + public static class PlayList { public @Nullable String playlistId; public @Nullable String title; public int trackCount; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonRegisterAppRequest.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonRegisterAppRequest.java index 54b242a0cf0f1..8b2e2762a22d5 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonRegisterAppRequest.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonRegisterAppRequest.java @@ -38,7 +38,7 @@ public JsonRegisterAppRequest(String serial, String access_token, String frc, Js public UserContextMap user_context_map = new UserContextMap(); public String[] requested_token_type = { "bearer", "mac_dms", "website_cookies" }; - public class Cookies { + public static class Cookies { @Nullable public JsonWebSiteCookie @Nullable [] website_cookies; @Nullable @@ -46,7 +46,7 @@ public class Cookies { } - public class RegistrationData { + public static class RegistrationData { public String domain = "Device"; public String app_version = "2.2.223830.0"; public String device_type = "A2IVLV5VM2W81"; @@ -59,12 +59,12 @@ public class RegistrationData { public String software_version = "1"; } - public class AuthData { + public static class AuthData { @Nullable public String access_token; } - public class UserContextMap { + public static class UserContextMap { public String frc = ""; } } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonRegisterAppResponse.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonRegisterAppResponse.java index 9c6539c066aca..b2a22649f54ea 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonRegisterAppResponse.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonRegisterAppResponse.java @@ -29,19 +29,21 @@ public class JsonRegisterAppResponse { @Nullable public String request_id; - public class Response { + public static class Response { @Nullable public Success success; } - public class Success { + public static class Success { @Nullable public Extensions extensions; @Nullable public Tokens tokens; + @Nullable + public String customer_id; } - public class Extensions { + public static class Extensions { @Nullable public DeviceInfo device_info; @Nullable @@ -50,7 +52,7 @@ public class Extensions { public String customer_id; } - public class DeviceInfo { + public static class DeviceInfo { @Nullable public String device_name; @Nullable @@ -60,7 +62,7 @@ public class DeviceInfo { } - public class CustomerInfo { + public static class CustomerInfo { @Nullable public String account_pool; @Nullable @@ -73,7 +75,7 @@ public class CustomerInfo { public String given_name; } - public class Tokens { + public static class Tokens { @Nullable public Object website_cookies; @Nullable @@ -82,14 +84,14 @@ public class Tokens { public Bearer bearer; } - public class MacDms { + public static class MacDms { @Nullable public String device_private_key; @Nullable public String adp_token; } - public class Bearer { + public static class Bearer { @Nullable public String access_token; @Nullable diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonWakeWords.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonWakeWords.java index c8af33b41867c..c59a5bca171ab 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonWakeWords.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonWakeWords.java @@ -24,7 +24,7 @@ public class JsonWakeWords { public @Nullable WakeWord @Nullable [] wakeWords; - public class WakeWord { + public static class WakeWord { public @Nullable Boolean active; public @Nullable String deviceSerialNumber; public @Nullable String deviceType; From 28cf64d8efed1243da5af8f16aba56e28eea4cc5 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sat, 11 May 2019 17:33:44 +0200 Subject: [PATCH 02/20] [amazonechocontrol] Add announcement, Fix problem with bad request calls Signed-off-by: Michael Geramb (github: mgeramb) --- .../internal/AccountServlet.java | 48 +++++-- .../internal/BindingServlet.java | 3 +- .../internal/Connection.java | 127 +++++++++++++----- .../channelhandler/ChannelHandler.java | 60 +++++++++ .../ChannelHandlerAnnouncement.java | 81 +++++++++++ .../channelhandler/IAmazonThingHandler.java | 26 ++++ .../internal/handler/EchoHandler.java | 28 +++- .../internal/jsons/JsonBootstrapResult.java | 35 +++++ .../i18n/amazonechocontrol_de.properties | 3 + .../resources/ESH-INF/thing/thing-types.xml | 61 ++++++--- 10 files changed, 400 insertions(+), 72 deletions(-) create mode 100644 bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java create mode 100644 bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java create mode 100644 bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/IAmazonThingHandler.java create mode 100644 bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonBootstrapResult.java diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java index ad3ef7b7396f9..deda16d810781 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java @@ -301,9 +301,7 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp Device device = account.findDeviceJson(serialNumber); if (device != null) { Thing thing = account.findThingBySerialNumber(device.serialNumber); - if (thing != null) { - handleIds(resp, connection, device, thing); - } + handleIds(resp, connection, device, thing); return; } } @@ -374,6 +372,12 @@ private void handleDefaultPageResult(HttpServletResponse resp, String message, C html.append(" | "); html.append(StringEscapeUtils.escapeHtml("Logout and create new device id")); html.append(""); + // customer id + html.append("
Customer Id: "); + html.append(StringEscapeUtils.escapeHtml(connection.getCustomerId())); + // customer name + html.append("
Customer Name: "); + html.append(StringEscapeUtils.escapeHtml(connection.getCustomerName())); // device name html.append("
App name: "); html.append(StringEscapeUtils.escapeHtml(connection.getDeviceName())); @@ -393,7 +397,7 @@ private void handleDefaultPageResult(HttpServletResponse resp, String message, C // device list html.append( - ""); + "
DeviceSerial NumberStateThingFamilyType
"); for (Device device : this.account.getLastKnownDevices()) { html.append(""); + html.append(StringEscapeUtils.escapeHtml(nullReplacement(device.deviceOwnerCustomerId))); + html.append(""); + html.append(""); } html.append("
DeviceSerial NumberStateThingFamilyTypeCustomer Id
"); @@ -409,14 +413,18 @@ private void handleDefaultPageResult(HttpServletResponse resp, String message, C + URLEncoder.encode(device.serialNumber, "UTF8") + "'>" + StringEscapeUtils.escapeHtml(accountHandler.getLabel()) + ""); } else { - html.append("Not defined"); + html.append("" + + StringEscapeUtils.escapeHtml("Not defined") + ""); } html.append(""); html.append(StringEscapeUtils.escapeHtml(nullReplacement(device.deviceFamily))); html.append(""); html.append(StringEscapeUtils.escapeHtml(nullReplacement(device.deviceType))); html.append(""); - html.append("
"); createPageEndAndSent(resp, html); @@ -467,18 +475,36 @@ private void createPageEndAndSent(HttpServletResponse resp, StringBuilder html) } } - private void handleIds(HttpServletResponse resp, Connection connection, Device device, Thing thing) + private void handleIds(HttpServletResponse resp, Connection connection, Device device, @Nullable Thing thing) throws IOException, URISyntaxException { - StringBuilder html = createPageStart("Channel Options - " + thing.getLabel()); - + StringBuilder html; + if (thing != null) { + html = createPageStart("Channel Options - " + thing.getLabel()); + } else { + html = createPageStart("Device Information - No thing defined"); + } renderBluetoothMacChannel(connection, device, html); renderAmazonMusicPlaylistIdChannel(connection, device, html); renderPlayAlarmSoundChannel(connection, device, html); renderMusicProviderIdChannel(connection, html); - + renderCapabilities(connection, device, html); createPageEndAndSent(resp, html); } + private void renderCapabilities(Connection connection, Device device, StringBuilder html) { + html.append("

Capabilities

"); + html.append(""); + String[] capabilities = device.capabilities; + if (capabilities != null) { + for (String capability : capabilities) { + html.append(""); + } + } + html.append("
Name
"); + html.append(StringEscapeUtils.escapeHtml(capability)); + html.append("
"); + } + private void renderMusicProviderIdChannel(Connection connection, StringBuilder html) { html.append("

" + StringEscapeUtils.escapeHtml("Channel " + CHANNEL_MUSIC_PROVIDER_ID) + "

"); html.append(""); @@ -603,7 +629,7 @@ void handleProxyRequest(Connection connection, HttpServletResponse resp, String headers.put("Referer", referer); } - urlConnection = connection.makeRequest(verb, url, postData, json, false, headers); + urlConnection = connection.makeRequest(verb, url, postData, json, false, headers, false); if (urlConnection.getResponseCode() == 302) { { String location = urlConnection.getHeaderField("location"); diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java index bcefee5a83cde..7a8f77c1c768a 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java @@ -104,7 +104,7 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp StringBuilder html = new StringBuilder(); html.append("" + StringEscapeUtils.escapeHtml(BINDING_NAME) + ""); - html.append("

" + StringEscapeUtils.escapeHtml(BINDING_NAME) + "

"); + html.append("

" + StringEscapeUtils.escapeHtml(BINDING_NAME) + " Beta 8

"); synchronized (accountHandlers) { if (accountHandlers.isEmpty()) { @@ -126,5 +126,4 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp logger.warn("return html failed with uri syntax error {}", e); } } - } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index 166aecf8276b8..099cacf924fe6 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -58,6 +58,8 @@ import org.openhab.binding.amazonechocontrol.internal.jsons.JsonAutomation.Payload; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonAutomation.Trigger; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonBluetoothStates; +import org.openhab.binding.amazonechocontrol.internal.jsons.JsonBootstrapResult; +import org.openhab.binding.amazonechocontrol.internal.jsons.JsonBootstrapResult.Authentication; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonDeviceNotificationState; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonDeviceNotificationState.DeviceNotificationState; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonDevices; @@ -128,6 +130,7 @@ public class Connection { private long renewTime = 0; private @Nullable String deviceName; private @Nullable String accountCustomerId; + private @Nullable String customerName; private final Gson gson = new Gson(); private final Gson gsonWithNullSerialization; @@ -234,13 +237,29 @@ public String getDeviceName() { return deviceName; } + public String getCustomerId() { + String customerId = this.accountCustomerId; + if (customerId == null) { + return "Unknown"; + } + return customerId; + } + + public String getCustomerName() { + String customerName = this.customerName; + if (customerName == null) { + return "Unknown"; + } + return customerName; + } + public String serializeLoginData() { Date loginTime = this.loginTime; if (refreshToken == null || loginTime == null) { return ""; } StringBuilder builder = new StringBuilder(); - builder.append("6\n"); // version + builder.append("7\n"); // version builder.append(frc); builder.append("\n"); builder.append(serial); @@ -322,7 +341,7 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade Scanner scanner = new Scanner(data); String version = scanner.nextLine(); // check if serialize version - if (!version.equals("5") && !version.equals("6")) { + if (!version.equals("5") && !version.equals("6") && !version.equals("7")) { scanner.close(); return null; } @@ -344,8 +363,10 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade if (intVersion > 5) { String accountCustomerId = scanner.nextLine(); - if (!StringUtils.equals(accountCustomerId, "null")) { - this.accountCustomerId = accountCustomerId; + if (intVersion > 6) { + if (!StringUtils.equals(accountCustomerId, "null")) { + this.accountCustomerId = accountCustomerId; + } } } @@ -402,6 +423,24 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade return loginTime; } + private @Nullable Authentication tryGetBootstrap() throws IOException, URISyntaxException { + String bootstrapResultJson = makeRequestAndReturnString(alexaServer + "/api/bootstrap"); + boolean authenticated = bootstrapResultJson.contains("\"authenticated\":true"); + if (authenticated) { + JsonBootstrapResult result = parseJson(bootstrapResultJson, JsonBootstrapResult.class); + + Authentication authentication = result.authentication; + if (authentication != null) { + this.customerName = authentication.customerName; + if (this.accountCustomerId == null) { + this.accountCustomerId = authentication.customerId; + } + } + return authentication; + } + return null; + } + public String convertStream(HttpsURLConnection connection) throws IOException { InputStream input = connection.getInputStream(); if (input == null) { @@ -442,15 +481,19 @@ public String makeRequestAndReturnString(String url) throws IOException, URISynt public String makeRequestAndReturnString(String verb, String url, @Nullable String postData, boolean json, @Nullable Map customHeaders) throws IOException, URISyntaxException { - HttpsURLConnection connection = makeRequest(verb, url, postData, json, true, customHeaders); + HttpsURLConnection connection = makeRequest(verb, url, postData, json, true, customHeaders, false); return convertStream(connection); } public HttpsURLConnection makeRequest(String verb, String url, @Nullable String postData, boolean json, - boolean autoredirect, @Nullable Map customHeaders) throws IOException, URISyntaxException { + boolean autoredirect, @Nullable Map customHeaders, boolean repeatBadRequest) + throws IOException, URISyntaxException { String currentUrl = url; - for (int i = 0; i < 30; i++) // loop for handling redirect, using automatic redirect is not possible, because - // all response headers must be catched + int badRequestCounter = 0; + int redirectCounter = 0; + while (true) // loop for handling redirect and bad request, using automatic redirect is not possible, + // because + // all response headers must be catched { int code; HttpsURLConnection connection = null; @@ -558,18 +601,35 @@ public HttpsURLConnection makeRequest(String verb, String url, @Nullable String } } } + if (code == 400 && repeatBadRequest) { + badRequestCounter++; + if (badRequestCounter < 3) { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + } + continue; // repeat call + } + badRequestCounter += 0; + } if (code == 200) { logger.debug("Call to {} succeeded", url); return connection; } if (code == 302 && location != null) { logger.debug("Redirected to {}", location); + redirectCounter++; + if (redirectCounter > 30) { + throw new ConnectionException("Too many redirects"); + } currentUrl = location; if (autoredirect) { - continue; + continue; // repeat with new location } return connection; } + throw new HttpException(code, verb + " url '" + url + "' failed: " + connection.getResponseMessage()); + } catch (IOException e) { if (connection != null) { @@ -583,11 +643,7 @@ public HttpsURLConnection makeRequest(String verb, String url, @Nullable String } throw e; } - if (code != 200) { - throw new HttpException(code, verb + " url '" + url + "' failed: " + connection.getResponseMessage()); - } } - throw new ConnectionException("Too many redirects"); } public String registerConnectionAsApp(String oAutRedirectUrl) @@ -656,6 +712,7 @@ public String registerConnectionAsApp(String oAutRedirectUrl) setAmazonSite(host); try { exhangeToken(); + tryGetBootstrap(); } catch (Exception e) { logout(); throw e; @@ -769,15 +826,15 @@ public boolean verifyLogin() throws IOException, URISyntaxException { if (this.refreshToken == null) { return false; } - String response = makeRequestAndReturnString(alexaServer + "/api/bootstrap?version=0"); - Boolean result = response.contains("\"authenticated\":true"); - if (result) { + Authentication authentication = tryGetBootstrap(); + if (authentication != null && authentication.authenticated) { verifyTime = new Date(); if (loginTime == null) { loginTime = verifyTime; } + return true; } - return result; + return false; } public List getSessionCookies() { @@ -902,7 +959,7 @@ public JsonPlaylists getPlaylists(Device device) throws IOException, URISyntaxEx public void command(Device device, String command) throws IOException, URISyntaxException { String url = alexaServer + "/api/np/command?deviceSerialNumber=" + device.serialNumber + "&deviceType=" + device.deviceType; - makeRequest("POST", url, command, true, true, null); + makeRequest("POST", url, command, true, true, null, false); } public void notificationVolume(Device device, int volume) throws IOException, URISyntaxException { @@ -910,7 +967,7 @@ public void notificationVolume(Device device, int volume) throws IOException, UR + "/" + device.serialNumber; String command = "{\"deviceSerialNumber\":\"" + device.serialNumber + "\",\"deviceType\":\"" + device.deviceType + "\",\"softwareVersion\":\"" + device.softwareVersion + "\",\"volumeLevel\":" + volume + "}"; - makeRequest("PUT", url, command, true, true, null); + makeRequest("PUT", url, command, true, true, null, false); } public void ascendingAlarm(Device device, boolean ascendingAlarm) throws IOException, URISyntaxException { @@ -918,7 +975,7 @@ public void ascendingAlarm(Device device, boolean ascendingAlarm) throws IOExcep String command = "{\"ascendingAlarmEnabled\":" + (ascendingAlarm ? "true" : "false") + ",\"deviceSerialNumber\":\"" + device.serialNumber + "\",\"deviceType\":\"" + device.deviceType + "\",\"deviceAccountId\":null}"; - makeRequest("PUT", url, command, true, true, null); + makeRequest("PUT", url, command, true, true, null, false); } public DeviceNotificationState[] getDeviceNotificationStates() { @@ -956,11 +1013,11 @@ public void bluetooth(Device device, @Nullable String address) throws IOExceptio // disconnect makeRequest("POST", alexaServer + "/api/bluetooth/disconnect-sink/" + device.deviceType + "/" + device.serialNumber, "", - true, true, null); + true, true, null, false); } else { makeRequest("POST", alexaServer + "/api/bluetooth/pair-sink/" + device.deviceType + "/" + device.serialNumber, - "{\"bluetoothDeviceAddress\":\"" + address + "\"}", true, true, null); + "{\"bluetoothDeviceAddress\":\"" + address + "\"}", true, true, null, false); } } @@ -974,7 +1031,7 @@ public void playRadio(Device device, @Nullable String stationId) throws IOExcept + "&contentType=station&callSign=&mediaOwnerCustomerId=" + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId : this.accountCustomerId), - "", true, true, null); + "", true, true, null, false); } } @@ -989,7 +1046,7 @@ public void playAmazonMusicTrack(Device device, @Nullable String trackId) throws + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId : this.accountCustomerId) + "&shuffle=false", - command, true, true, null); + command, true, true, null, false); } } @@ -1005,7 +1062,7 @@ public void playAmazonMusicPlayList(Device device, @Nullable String playListId) + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId : this.accountCustomerId) + "&shuffle=false", - command, true, true, null); + command, true, true, null, false); } } @@ -1023,8 +1080,8 @@ public void sendNotificationToMobileApp(String customerId, String text, @Nullabl executeSequenceCommand(null, "Alexa.Notifications.SendMobilePush", parameters); } - public void sendAnnouncement(Device device, String text, @Nullable String title, int ttsVolume, int standardVolume) - throws IOException, URISyntaxException { + public void sendAnnouncement(Device device, String text, @Nullable String bodyText, @Nullable String title, + int ttsVolume, int standardVolume) throws IOException, URISyntaxException { Map parameters = new Hashtable(); parameters.put("expireAfter", "PT5S"); JsonAnnouncementContent[] contentArray = new JsonAnnouncementContent[1]; @@ -1069,7 +1126,7 @@ public void sendAnnouncement(Device device, String text, @Nullable String title, public void textToSpeech(Device device, String text, int ttsVolume, int standardVolume) throws IOException, URISyntaxException { - Map parameters = new Hashtable<>(); + Map parameters = new Hashtable(); parameters.put("textToSpeak", text); executeSequenceCommandWithVolume(device, "Alexa.Speak", parameters, ttsVolume, standardVolume); } @@ -1081,7 +1138,7 @@ private void executeSequenceCommandWithVolume(@Nullable Device device, String co JsonArray nodesToExecute = new JsonArray(); - Map volumeParameters = new Hashtable<>(); + Map volumeParameters = new Hashtable(); // add tts volume volumeParameters.clear(); volumeParameters.put("value", ttsVolume); @@ -1122,7 +1179,7 @@ private void executeSequenceNode(JsonObject nodeToExecute) throws IOException, U Map headers = new HashMap(); headers.put("Routines-Version", "1.1.218665"); - makeRequest("POST", alexaServer + "/api/behaviors/preview", json, true, true, null); + makeRequest("POST", alexaServer + "/api/behaviors/preview", json, true, true, null, true); } private void executeSequenceNodes(JsonArray nodesToExecute) throws IOException, URISyntaxException { @@ -1230,7 +1287,7 @@ public void startRoutine(Device device, String utterance) throws IOException, UR request.sequenceJson = sequenceJson; String requestJson = gson.toJson(request); - makeRequest("POST", alexaServer + "/api/behaviors/preview", requestJson, true, true, null); + makeRequest("POST", alexaServer + "/api/behaviors/preview", requestJson, true, true, null, true); } else { logger.warn("Routine {} not found", utterance); } @@ -1256,7 +1313,7 @@ public void setEnabledFlashBriefings(JsonFeed[] enabledFlashBriefing) throws IOE JsonEnabledFeeds enabled = new JsonEnabledFeeds(); enabled.enabledFeeds = enabledFlashBriefing; String json = gsonWithNullSerialization.toJson(enabled); - makeRequest("POST", alexaServer + "/api/content-skills/enabled-feeds", json, true, true, null); + makeRequest("POST", alexaServer + "/api/content-skills/enabled-feeds", json, true, true, null, false); } public JsonNotificationSound[] getNotificationSounds(Device device) throws IOException, URISyntaxException { @@ -1386,7 +1443,7 @@ public void playMusicVoiceCommand(Device device, String providerId, String voice startRoutineRequest.status = null; String postData = gson.toJson(startRoutineRequest); - makeRequest("POST", alexaServer + "/api/behaviors/preview", postData, true, true, null); + makeRequest("POST", alexaServer + "/api/behaviors/preview", postData, true, true, null, true); } public JsonEqualizer getEqualizer(Device device) throws IOException, URISyntaxException { @@ -1398,6 +1455,6 @@ public JsonEqualizer getEqualizer(Device device) throws IOException, URISyntaxEx public void SetEqualizer(Device device, JsonEqualizer settings) throws IOException, URISyntaxException { String postData = gson.toJson(settings); makeRequest("POST", alexaServer + "/api/equalizer/" + device.serialNumber + "/" + device.deviceType, postData, - true, true, null); + true, true, null, false); } -} +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java new file mode 100644 index 0000000000000..788bd08f408b6 --- /dev/null +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2010-2019 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.amazonechocontrol.internal.channelhandler; + +import java.io.IOException; +import java.net.URISyntaxException; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.types.Command; +import org.openhab.binding.amazonechocontrol.internal.Connection; +import org.openhab.binding.amazonechocontrol.internal.jsons.JsonDevices.Device; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; + +/** + * The {@link ChannelHandler} is the base class for all channel handlers + * + * @author Michael Geramb - Initial contribution + */ +public abstract class ChannelHandler { + public abstract boolean tryHandleCommand(Device device, Connection connection, String channelId, Command command) + throws IOException, URISyntaxException; + + protected final IAmazonThingHandler thingHandler; + protected final Gson gson = new Gson(); + private final Logger logger; + + protected ChannelHandler(IAmazonThingHandler thingHandler) { + this.logger = LoggerFactory.getLogger(this.getClass()); + this.thingHandler = thingHandler; + } + + protected @Nullable T tryParseJson(String json, Class type) { + try { + return gson.fromJson(json, type); + } catch (JsonSyntaxException e) { + logger.debug("Json parse error {}", e); + return null; + } + } + + protected @Nullable T parseJson(String json, Class type) throws JsonSyntaxException { + return gson.fromJson(json, type); + + } + +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java new file mode 100644 index 0000000000000..4947d8ce3b01d --- /dev/null +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2010-2019 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.amazonechocontrol.internal.channelhandler; + +import java.io.IOException; +import java.net.URISyntaxException; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.StringType; +import org.eclipse.smarthome.core.types.Command; +import org.openhab.binding.amazonechocontrol.internal.Connection; +import org.openhab.binding.amazonechocontrol.internal.jsons.JsonDevices.Device; + +import com.google.gson.JsonSyntaxException; + +/** + * The {@link ChannelHandlerAnnouncement} is responsible for the announcement channel + * + * @author Michael Geramb - Initial contribution + */ +public class ChannelHandlerAnnouncement extends ChannelHandler { + public static final String CHANNEL_NAME = "announcement"; + + public ChannelHandlerAnnouncement(IAmazonThingHandler thingHandler) { + super(thingHandler); + } + + @Override + public boolean tryHandleCommand(Device device, Connection connection, String channelId, Command command) + throws IOException, URISyntaxException { + if (channelId.equals(CHANNEL_NAME)) { + if (command instanceof StringType) { + String commandValue = ((StringType) command).toFullString(); + String body = commandValue; + String title = null; + String speak = " "; // blank generates a beep + if (commandValue.startsWith("{") && commandValue.endsWith("}")) { + try { + AnnouncementRequestJson request = parseJson(commandValue, AnnouncementRequestJson.class); + if (request != null) { + title = request.title; + body = request.body; + if (body == null) { + body = ""; + } + if (request.sound == false) { + speak = ""; + } + } + } catch (JsonSyntaxException e) { + body = e.getLocalizedMessage(); + } + } + connection.sendAnnouncement(device, speak, body, title, 0, 0); + } + RefreshChannel(); + } + return false; + } + + void RefreshChannel() { + thingHandler.updateChannelState(CHANNEL_NAME, new StringType("")); + } + + class AnnouncementRequestJson { + public @Nullable Boolean sound; + public @Nullable String title; + public @Nullable String body; + } + +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/IAmazonThingHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/IAmazonThingHandler.java new file mode 100644 index 0000000000000..ee9e3310d2843 --- /dev/null +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/IAmazonThingHandler.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2010-2019 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.amazonechocontrol.internal.channelhandler; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.types.State; + +/** + * The {@link IAmazonThingHandler} is used from ChannelHandlers to communicate with the thing + * + * @author Michael Geramb - Initial contribution + */ +@NonNullByDefault +public interface IAmazonThingHandler { + void updateChannelState(String channelId, State state); +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java index cdb008e223f72..1301f797d60a8 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java @@ -20,6 +20,7 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.HashSet; import java.util.Hashtable; import java.util.List; @@ -55,10 +56,14 @@ import org.eclipse.smarthome.core.thing.binding.BaseThingHandler; import org.eclipse.smarthome.core.types.Command; import org.eclipse.smarthome.core.types.RefreshType; +import org.eclipse.smarthome.core.types.State; import org.eclipse.smarthome.core.types.UnDefType; import org.openhab.binding.amazonechocontrol.internal.Connection; import org.openhab.binding.amazonechocontrol.internal.ConnectionException; import org.openhab.binding.amazonechocontrol.internal.HttpException; +import org.openhab.binding.amazonechocontrol.internal.channelhandler.ChannelHandler; +import org.openhab.binding.amazonechocontrol.internal.channelhandler.ChannelHandlerAnnouncement; +import org.openhab.binding.amazonechocontrol.internal.channelhandler.IAmazonThingHandler; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonActivities.Activity; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonActivities.Activity.Description; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonAscendingAlarm.AscendingAlarmModel; @@ -94,12 +99,12 @@ * @author Michael Geramb - Initial contribution */ @NonNullByDefault -public class EchoHandler extends BaseThingHandler { +public class EchoHandler extends BaseThingHandler implements IAmazonThingHandler { private final Logger logger = LoggerFactory.getLogger(EchoHandler.class); private Gson gson = new Gson(); private @Nullable Device device; - private Set capabilities = new HashSet<>(); + private Set capabilities = new HashSet(); private @Nullable AccountHandler account; private @Nullable ScheduledFuture updateStateJob; private @Nullable ScheduledFuture ignoreVolumeChange; @@ -128,6 +133,7 @@ public class EchoHandler extends BaseThingHandler { private @Nullable JsonPlaylists playLists; private @Nullable JsonNotificationSound @Nullable [] alarmSounds; private @Nullable List musicProviders; + private List channelHandlers = new ArrayList(); private @Nullable JsonNotificationResponse currentNotification; private @Nullable ScheduledFuture currentNotifcationUpdateTimer; @@ -138,6 +144,7 @@ public class EchoHandler extends BaseThingHandler { public EchoHandler(Thing thing) { super(thing); + channelHandlers.add(new ChannelHandlerAnnouncement(this)); } @Override @@ -263,8 +270,14 @@ public void handleCommand(ChannelUID channelUID, Command command) { return; } - // Player commands String channelId = channelUID.getId(); + for (ChannelHandler channelHandler : channelHandlers) { + if (channelHandler.tryHandleCommand(device, connection, channelId, command)) { + return; + } + } + + // Player commands if (channelId.equals(CHANNEL_PLAYER)) { if (command == PlayPauseType.PAUSE || command == OnOffType.OFF) { connection.command(device, "{\"type\":\"PauseCommand\"}"); @@ -725,7 +738,7 @@ private void startTextToSpeech(Connection connection, Device device, String text this.ignoreVolumeChange = scheduler.schedule(this::stopIgnoreVolumeChange, 2000, TimeUnit.MILLISECONDS); } if (text.startsWith("") && text.endsWith("")) { - connection.sendAnnouncement(device, text, null, textToSpeechVolume, lastKnownVolume); + connection.sendAnnouncement(device, text, null, null, textToSpeechVolume, lastKnownVolume); } else { connection.textToSpeech(device, text, textToSpeechVolume, lastKnownVolume); } @@ -1327,4 +1340,9 @@ public void updateNotifications(ZonedDateTime currentTime, ZonedDateTime now, nextMusicAlarm == null ? UnDefType.UNDEF : new DateTimeType(nextMusicAlarm)); updateState(CHANNEL_NEXT_TIMER, nextTimer == null ? UnDefType.UNDEF : new DateTimeType(nextTimer)); } -} + + @Override + public void updateChannelState(String channelId, State state) { + updateState(channelId, state); + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonBootstrapResult.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonBootstrapResult.java new file mode 100644 index 0000000000000..dffce100b83b8 --- /dev/null +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/jsons/JsonBootstrapResult.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2010-2019 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.amazonechocontrol.internal.jsons; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * The {@link JsonBluetoothStates} encapsulate the bootstrap result + * + * @author Michael Geramb - Initial contribution + */ +@NonNullByDefault +public class JsonBootstrapResult { + + 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; + } +} diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/i18n/amazonechocontrol_de.properties b/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/i18n/amazonechocontrol_de.properties index e3b6d0b14de0a..3c39840e2980e 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/i18n/amazonechocontrol_de.properties +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/i18n/amazonechocontrol_de.properties @@ -56,6 +56,9 @@ channel-type.amazonechocontrol.providerDisplayName.description = Name des Musika channel-type.amazonechocontrol.bluetoothMAC.label = Bluetooth Verbindung channel-type.amazonechocontrol.bluetoothMAC.description = MAC-Adresse des verbundenen Bluetoothgerätes +channel-type.amazonechocontrol.announcement.label = Ankündigung +channel-type.amazonechocontrol.announcement.description = Zeigt die Ankündungsnachricht am Display (Nur schreiben). In der Binding Beschreibung ist im Tutorials Abschnitt eine Erklärung wie der Title gesetzt und der Sound deaktiviert wird. + channel-type.amazonechocontrol.textToSpeech.label = Sprich channel-type.amazonechocontrol.textToSpeech.description = Spricht den Text (Nur schreiben). Es kann reiner Text oder SSML verwendet werden: e.g. Ich will dir ein Geheimnis erzählen.Ich bin nicht wirklich ein Mensch. diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/thing/thing-types.xml index 54b7acb0f7a42..8e4dcaa62826b 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/thing/thing-types.xml @@ -1,8 +1,9 @@ + xmlns:thing="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + bindingId="amazonechocontrol" + xsi:schemaLocation="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0 http://eclipse.org/smarthome/schemas/thing-description-1.0.0.xsd"> Amazon Account where the amazon echo devices are registered. @@ -27,14 +28,17 @@ - + - + - + @@ -47,7 +51,8 @@ - + @@ -80,15 +85,19 @@ - + - + - + + @@ -100,7 +109,8 @@ - + @@ -133,15 +143,19 @@ - + - + - + + @@ -153,7 +167,8 @@ - + @@ -182,11 +197,13 @@ - + - + serialNumber @@ -267,7 +284,8 @@ Amazon Music play list id (Write only, no current state) - + String Id of the playlist which was started with openHAB @@ -365,6 +383,11 @@ Voice command as text. E.g. 'Yesterday from the Beatles' (Write only) + + String + + Display the announcement message on the display (Write only). See in the tutorial section of the binding description to learn how it's possible to set the title and turn off the sound. + String @@ -450,4 +473,4 @@ Next timer - + \ No newline at end of file From b8f8eed063056e34b20a4ef806abb56257fbd3c5 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sat, 11 May 2019 17:36:17 +0200 Subject: [PATCH 03/20] [amazonechocontrol] Remove beta tag Signed-off-by: Michael Geramb (github: mgeramb) --- .../binding/amazonechocontrol/internal/BindingServlet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java index 7a8f77c1c768a..23adb93276a36 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java @@ -104,7 +104,7 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp StringBuilder html = new StringBuilder(); html.append("" + StringEscapeUtils.escapeHtml(BINDING_NAME) + ""); - html.append("

" + StringEscapeUtils.escapeHtml(BINDING_NAME) + " Beta 8

"); + html.append("

" + StringEscapeUtils.escapeHtml(BINDING_NAME) + "

"); synchronized (accountHandlers) { if (accountHandlers.isEmpty()) { From 7e6c78915c836a569ff8495b366961773df93a6a Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sat, 11 May 2019 17:40:42 +0200 Subject: [PATCH 04/20] [amazonechocontrol] Add apple music and iHeartRadio id Signed-off-by: Michael Geramb (github: mgeramb) --- .../amazonechocontrol/internal/handler/EchoHandler.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java index 1301f797d60a8..871bc7c872102 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java @@ -874,6 +874,13 @@ public void updateState(AccountHandler accountHandler, @Nullable Device device, if (StringUtils.startsWith(musicProviderId, "TUNEIN")) { musicProviderId = "TUNEIN"; } + if (StringUtils.startsWithIgnoreCase(musicProviderId, "iHeartRadio")) { + musicProviderId = "I_HEART_RADIO"; + } + if (StringUtils.containsIgnoreCase(musicProviderId, "Apple") + && StringUtils.containsIgnoreCase(musicProviderId, "Music")) { + musicProviderId = "APPLE_MUSIC"; + } } } progress = playerInfo.progress; From 35154c11a43fd0d49630d86f34bc36e1442b2559 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sun, 12 May 2019 08:19:52 +0200 Subject: [PATCH 05/20] [amazonechocontrol] Improve error handling Signed-off-by: Michael Geramb (github: mgeramb) --- .../openhab/binding/amazonechocontrol/internal/Connection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index 166aecf8276b8..cf60c7d83c646 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -809,7 +809,7 @@ public void logout() { private T parseJson(String json, Class type) throws JsonSyntaxException { try { return gson.fromJson(json, type); - } catch (JsonSyntaxException e) { + } catch (JsonSyntaxException | JsonParseException | IllegalStateException e) { logger.warn("Parsing json failed {}", e); logger.warn("Illegal json: {}", json); throw e; From e6638cce1685622bbb22094eca722fe09fc01849 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sun, 12 May 2019 10:25:38 +0200 Subject: [PATCH 06/20] [amazonechocontrol] Remove unused Exception Signed-off-by: Michael Geramb (github: mgeramb) Signed-off-by: Michael Geramb --- .../openhab/binding/amazonechocontrol/internal/Connection.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index 8131a9bafc1c0..8b71f9d3b5b6a 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -101,6 +101,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import com.google.gson.JsonSyntaxException; /** @@ -866,7 +867,7 @@ public void logout() { private T parseJson(String json, Class type) throws JsonSyntaxException { try { return gson.fromJson(json, type); - } catch (JsonSyntaxException | JsonParseException | IllegalStateException e) { + } catch (JsonParseException | IllegalStateException e) { logger.warn("Parsing json failed {}", e); logger.warn("Illegal json: {}", json); throw e; From 94494da65440dbe8ee1a48e3edfca2af736f63de Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sun, 12 May 2019 10:25:38 +0200 Subject: [PATCH 07/20] [amazonechocontrol] Remove unused Exception Signed-off-by: Michael Geramb (github: mgeramb) Signed-off-by: Michael Geramb --- .../openhab/binding/amazonechocontrol/internal/Connection.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index cf60c7d83c646..37a4c3eda30cf 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -99,6 +99,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import com.google.gson.JsonSyntaxException; /** @@ -809,7 +810,7 @@ public void logout() { private T parseJson(String json, Class type) throws JsonSyntaxException { try { return gson.fromJson(json, type); - } catch (JsonSyntaxException | JsonParseException | IllegalStateException e) { + } catch (JsonParseException | IllegalStateException e) { logger.warn("Parsing json failed {}", e); logger.warn("Illegal json: {}", json); throw e; From b427723b378213cc3c1f7e38dc86bc571f64c9ed Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sun, 12 May 2019 10:25:38 +0200 Subject: [PATCH 08/20] [amazonechocontrol] Improved Error Handling Signed-off-by: Michael Geramb (github: mgeramb) Signed-off-by: Michael Geramb --- .../openhab/binding/amazonechocontrol/internal/Connection.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index 099cacf924fe6..8b71f9d3b5b6a 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -101,6 +101,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import com.google.gson.JsonSyntaxException; /** @@ -866,7 +867,7 @@ public void logout() { private T parseJson(String json, Class type) throws JsonSyntaxException { try { return gson.fromJson(json, type); - } catch (JsonSyntaxException e) { + } catch (JsonParseException | IllegalStateException e) { logger.warn("Parsing json failed {}", e); logger.warn("Illegal json: {}", json); throw e; From 7410059e343e1d858c435604f590f3ccfa140bde Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sun, 12 May 2019 11:43:51 +0200 Subject: [PATCH 09/20] [amazonechocontrol] Add more debug info Signed-off-by: Michael Geramb (github: mgeramb) Signed-off-by: Michael Geramb --- .../binding/amazonechocontrol/internal/Connection.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index 8b71f9d3b5b6a..b8067d43df231 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -483,7 +483,9 @@ public String makeRequestAndReturnString(String url) throws IOException, URISynt public String makeRequestAndReturnString(String verb, String url, @Nullable String postData, boolean json, @Nullable Map customHeaders) throws IOException, URISyntaxException { HttpsURLConnection connection = makeRequest(verb, url, postData, json, true, customHeaders, false); - return convertStream(connection); + String result = convertStream(connection); + this.logger.debug("Result of {} {}:{}", verb, url, result); + return result; } public HttpsURLConnection makeRequest(String verb, String url, @Nullable String postData, boolean json, From f484f36803b3601f5e6690d42d48826df40273e0 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sun, 12 May 2019 11:43:51 +0200 Subject: [PATCH 10/20] [amazonechocontrol] Add more debug info Signed-off-by: Michael Geramb (github: mgeramb) Signed-off-by: Michael Geramb --- .../binding/amazonechocontrol/internal/Connection.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index 8b71f9d3b5b6a..b8067d43df231 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -483,7 +483,9 @@ public String makeRequestAndReturnString(String url) throws IOException, URISynt public String makeRequestAndReturnString(String verb, String url, @Nullable String postData, boolean json, @Nullable Map customHeaders) throws IOException, URISyntaxException { HttpsURLConnection connection = makeRequest(verb, url, postData, json, true, customHeaders, false); - return convertStream(connection); + String result = convertStream(connection); + this.logger.debug("Result of {} {}:{}", verb, url, result); + return result; } public HttpsURLConnection makeRequest(String verb, String url, @Nullable String postData, boolean json, From 254aad545fde5153a4ea93eba617eb59acaecea1 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Wed, 15 May 2019 18:10:00 +0200 Subject: [PATCH 11/20] [amazonechocontrol] Fix spoken text to multiple devices Signed-off-by: Michael Geramb --- .../amazonechocontrol/internal/handler/EchoHandler.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java index cdb008e223f72..2bb4e8fb3ad03 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java @@ -1201,6 +1201,9 @@ private void updateMediaProgress(boolean updateMediaLength) { } public void handlePushActivity(Activity pushActivity) { + if ("DISCARDED_NON_DEVICE_DIRECTED_INTENT".equals(pushActivity.activityStatus)) { + return; + } Description description = pushActivity.ParseDescription(); if (StringUtils.isEmpty(description.firstUtteranceId) || StringUtils.startsWithIgnoreCase(description.firstUtteranceId, "TextClient:")) { From 2454181a1209431bcec62f56859f96c7e8540050 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Mon, 20 May 2019 20:00:22 +0200 Subject: [PATCH 12/20] [amazonechocontrol] Use diamond operator Handle new line at the file end Fix string compare Add comment to version handling of deserialization Signed-off-by: Michael Geramb --- .../internal/AccountServlet.java | 4 +- .../AmazonEchoControlBindingConstants.java | 2 +- .../internal/BindingServlet.java | 2 +- .../internal/Connection.java | 69 +++++++++++-------- .../internal/WebSocketConnection.java | 2 +- .../channelhandler/ChannelHandler.java | 3 +- .../ChannelHandlerAnnouncement.java | 3 +- .../channelhandler/IAmazonThingHandler.java | 2 +- .../discovery/AmazonEchoDiscovery.java | 4 +- .../internal/handler/AccountHandler.java | 4 +- .../internal/handler/EchoHandler.java | 8 +-- .../resources/ESH-INF/thing/thing-types.xml | 2 +- 12 files changed, 56 insertions(+), 49 deletions(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java index deda16d810781..c21c4dd9833e2 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java @@ -329,7 +329,7 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp } public Map getQueryMap(@Nullable String query) { - Map map = new HashMap(); + Map map = new HashMap<>(); if (query != null) { String[] params = query.split("&"); for (String param : params) { @@ -625,7 +625,7 @@ void handleProxyRequest(Connection connection, HttpServletResponse resp, String try { Map headers = null; if (referer != null) { - headers = new HashMap(); + headers = new HashMap<>(); headers.put("Referer", referer); } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlBindingConstants.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlBindingConstants.java index 258e7ba07ba59..45675aadba7a1 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlBindingConstants.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlBindingConstants.java @@ -42,7 +42,7 @@ public class AmazonEchoControlBindingConstants { public static final ThingTypeUID THING_TYPE_FLASH_BRIEFING_PROFILE = new ThingTypeUID(BINDING_ID, "flashbriefingprofile"); - public static final Set SUPPORTED_THING_TYPES_UIDS = new HashSet( + public static final Set SUPPORTED_THING_TYPES_UIDS = new HashSet<>( Arrays.asList(THING_TYPE_ACCOUNT, THING_TYPE_ECHO, THING_TYPE_ECHO_SPOT, THING_TYPE_ECHO_SHOW, THING_TYPE_ECHO_WHA, THING_TYPE_FLASH_BRIEFING_PROFILE)); diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java index 7a8f77c1c768a..dd3dd0f4362bf 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/BindingServlet.java @@ -49,7 +49,7 @@ public class BindingServlet extends HttpServlet { String servletUrl; HttpService httpService; - List accountHandlers = new ArrayList(); + List accountHandlers = new ArrayList<>(); public BindingServlet(HttpService httpService) { this.httpService = httpService; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index b8067d43df231..de0f43723eee5 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -341,8 +341,8 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade } Scanner scanner = new Scanner(data); String version = scanner.nextLine(); - // check if serialize version - if (!version.equals("5") && !version.equals("6") && !version.equals("7")) { + // check if serialize version is supported + if (!"5".equals(version) && !"6".equals(version) && !"7".equals(version)) { scanner.close(); return null; } @@ -364,6 +364,8 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade if (intVersion > 5) { String accountCustomerId = scanner.nextLine(); + // Note: version 5 have wrong customer id serialized. + // Only use it, if it at least version 6 of serialization if (intVersion > 6) { if (!StringUtils.equals(accountCustomerId, "null")) { this.accountCustomerId = accountCustomerId; @@ -425,19 +427,26 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade } private @Nullable Authentication tryGetBootstrap() throws IOException, URISyntaxException { - String bootstrapResultJson = makeRequestAndReturnString(alexaServer + "/api/bootstrap"); - boolean authenticated = bootstrapResultJson.contains("\"authenticated\":true"); - if (authenticated) { - JsonBootstrapResult result = parseJson(bootstrapResultJson, JsonBootstrapResult.class); - - Authentication authentication = result.authentication; - if (authentication != null) { - this.customerName = authentication.customerName; - if (this.accountCustomerId == null) { - this.accountCustomerId = authentication.customerId; - } - } - return authentication; + String bootstrapResultJson = makeRequestAndReturnString(alexaServer + "/api/bootstrap").trim(); + boolean authenticationResult = bootstrapResultJson.contains("authenticated") && bootstrapResultJson.startsWith("{") && bootstrapResultJson.endsWith("}"); + if (authenticationResult) { + try + { + JsonBootstrapResult result = parseJson(bootstrapResultJson, JsonBootstrapResult.class); + Authentication authentication = result.authentication; + if (authentication != null && authentication.authenticated) { + this.customerName = authentication.customerName; + if (this.accountCustomerId == null) { + this.accountCustomerId = authentication.customerId; + } + return authentication; + } + } + catch (JsonSyntaxException | IllegalStateException e) + { + // We have not received a valid json + return null; + } } return null; } @@ -653,7 +662,7 @@ public String registerConnectionAsApp(String oAutRedirectUrl) throws ConnectionException, IOException, URISyntaxException { URI oAutRedirectUri = new URI(oAutRedirectUrl); - Map queryParameters = new LinkedHashMap(); + Map queryParameters = new LinkedHashMap<>(); String query = oAutRedirectUri.getQuery(); String[] pairs = query.split("&"); for (String pair : pairs) { @@ -663,9 +672,9 @@ public String registerConnectionAsApp(String oAutRedirectUrl) } String accessToken = queryParameters.get("openid.oa2.access_token"); - Map cookieMap = new HashMap(); + Map cookieMap = new HashMap<>(); - List webSiteCookies = new ArrayList(); + List webSiteCookies = new ArrayList<>(); for (HttpCookie cookie : getSessionCookies("https://www.amazon.com")) { cookieMap.put(cookie.getName(), cookie.getValue()); webSiteCookies.add(new JsonWebSiteCookie(cookie.getName(), cookie.getValue())); @@ -678,7 +687,7 @@ public String registerConnectionAsApp(String oAutRedirectUrl) webSiteCookiesArray); String registerAppRequestJson = gson.toJson(registerAppRequest); - HashMap registerHeaders = new HashMap(); + HashMap registerHeaders = new HashMap<>(); registerHeaders.put("x-amzn-identity-auth-domain", "api.amazon.com"); String registerAppResultJson = makeRequestAndReturnString("POST", "https://api.amazon.com/auth/register", @@ -746,7 +755,7 @@ private void exhangeToken() throws IOException, URISyntaxException { + "&requested_token_type=auth_cookies&source_token_type=refresh_token&di.hw.version=iPhone&di.sdk.version=6.10.0&cookies=" + cookiesBase64 + "&app_name=Amazon%20Alexa&di.os.version=11.4.1"; - HashMap exchangeTokenHeader = new HashMap(); + HashMap exchangeTokenHeader = new HashMap<>(); exchangeTokenHeader.put("Cookie", ""); String exchangeTokenJson = makeRequestAndReturnString("POST", @@ -844,7 +853,7 @@ public List getSessionCookies() { try { return cookieManager.getCookieStore().get(new URI(alexaServer)); } catch (URISyntaxException e) { - return new ArrayList(); + return new ArrayList<>(); } } @@ -852,7 +861,7 @@ public List getSessionCookies(String server) { try { return cookieManager.getCookieStore().get(new URI(server)); } catch (URISyntaxException e) { - return new ArrayList(); + return new ArrayList<>(); } } @@ -866,7 +875,7 @@ public void logout() { } // parser - private T parseJson(String json, Class type) throws JsonSyntaxException { + private T parseJson(String json, Class type) throws JsonSyntaxException, IllegalStateException { try { return gson.fromJson(json, type); } catch (JsonParseException | IllegalStateException e) { @@ -1071,7 +1080,7 @@ public void playAmazonMusicPlayList(Device device, @Nullable String playListId) public void sendNotificationToMobileApp(String customerId, String text, @Nullable String title) throws IOException, URISyntaxException { - Map parameters = new Hashtable(); + Map parameters = new Hashtable<>(); parameters.put("notificationMessage", text); parameters.put("alexaUrl", "#v2/behaviors"); if (title != null && !StringUtils.isEmpty(title)) { @@ -1085,7 +1094,7 @@ public void sendNotificationToMobileApp(String customerId, String text, @Nullabl public void sendAnnouncement(Device device, String text, @Nullable String bodyText, @Nullable String title, int ttsVolume, int standardVolume) throws IOException, URISyntaxException { - Map parameters = new Hashtable(); + Map parameters = new Hashtable<>(); parameters.put("expireAfter", "PT5S"); JsonAnnouncementContent[] contentArray = new JsonAnnouncementContent[1]; JsonAnnouncementContent content = new JsonAnnouncementContent(); @@ -1129,7 +1138,7 @@ public void sendAnnouncement(Device device, String text, @Nullable String bodyTe public void textToSpeech(Device device, String text, int ttsVolume, int standardVolume) throws IOException, URISyntaxException { - Map parameters = new Hashtable(); + Map parameters = new Hashtable<>(); parameters.put("textToSpeak", text); executeSequenceCommandWithVolume(device, "Alexa.Speak", parameters, ttsVolume, standardVolume); } @@ -1141,7 +1150,7 @@ private void executeSequenceCommandWithVolume(@Nullable Device device, String co JsonArray nodesToExecute = new JsonArray(); - Map volumeParameters = new Hashtable(); + Map volumeParameters = new Hashtable<>(); // add tts volume volumeParameters.clear(); volumeParameters.put("value", ttsVolume); @@ -1179,7 +1188,7 @@ private void executeSequenceNode(JsonObject nodeToExecute) throws IOException, U request.sequenceJson = gson.toJson(sequenceJson); String json = gson.toJson(request); - Map headers = new HashMap(); + Map headers = new HashMap<>(); headers.put("Routines-Version", "1.1.218665"); makeRequest("POST", alexaServer + "/api/behaviors/preview", json, true, true, null, true); @@ -1384,7 +1393,7 @@ public JsonNotificationResponse getNotificationState(JsonNotificationResponse no public List getMusicProviders() { String response; try { - Map headers = new HashMap(); + Map headers = new HashMap<>(); headers.put("Routines-Version", "1.1.218665"); response = makeRequestAndReturnString("GET", alexaServer + "/api/behaviors/entities?skillId=amzn1.ask.1p.music", null, true, headers); @@ -1460,4 +1469,4 @@ public void SetEqualizer(Device device, JsonEqualizer settings) throws IOExcepti makeRequest("POST", alexaServer + "/api/equalizer/" + device.serialNumber + "/" + device.deviceType, postData, true, true, null, false); } -} \ No newline at end of file +} diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/WebSocketConnection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/WebSocketConnection.java index 76656d246ea5d..302e7c90dcbaa 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/WebSocketConnection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/WebSocketConnection.java @@ -82,7 +82,7 @@ public WebSocketConnection(String amazonSite, List sessionCookies, } String deviceSerial = ""; - List cookiesForWs = new ArrayList(); + List cookiesForWs = new ArrayList<>(); for (HttpCookie cookie : sessionCookies) { if (cookie.getName().equals("ubid-acbde")) { deviceSerial = cookie.getValue(); diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java index 788bd08f408b6..5978f699235fc 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java @@ -56,5 +56,4 @@ protected ChannelHandler(IAmazonThingHandler thingHandler) { return gson.fromJson(json, type); } - -} \ No newline at end of file +} diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java index 4947d8ce3b01d..7c6a45e1920a0 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java @@ -77,5 +77,4 @@ class AnnouncementRequestJson { public @Nullable String title; public @Nullable String body; } - -} \ No newline at end of file +} diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/IAmazonThingHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/IAmazonThingHandler.java index ee9e3310d2843..f0e412c9879ed 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/IAmazonThingHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/IAmazonThingHandler.java @@ -23,4 +23,4 @@ @NonNullByDefault public interface IAmazonThingHandler { void updateChannelState(String channelId, State state); -} \ No newline at end of file +} diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java index 437961fb7890a..09edb6bd1a043 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java @@ -49,7 +49,7 @@ public class AmazonEchoDiscovery extends AbstractDiscoveryService implements Ext AccountHandler accountHandler; private final Logger logger = LoggerFactory.getLogger(AmazonEchoDiscovery.class); - private final HashSet discoverdFlashBriefings = new HashSet(); + private final HashSet discoverdFlashBriefings = new HashSet<>(); @Nullable ScheduledFuture startScanStateJob; @@ -68,7 +68,7 @@ public AmazonEchoDiscovery(AccountHandler accountHandler) { } public void activate() { - activate(new Hashtable()); + activate(new Hashtable<>()); } @Override diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java index 3a3db9cd87cc5..94f1a6dd018a8 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java @@ -558,7 +558,7 @@ public List updateDeviceList() { Connection currentConnection = connection; if (currentConnection == null) { - return new ArrayList(); + return new ArrayList<>(); } List devices = null; @@ -600,7 +600,7 @@ public List updateDeviceList() { if (devices != null) { return devices; } - return new ArrayList(); + return new ArrayList<>(); } public void setEnabledFlashBriefingsJson(String flashBriefingJson) { diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java index be21208ac23ee..e99b3d3e19917 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java @@ -104,7 +104,7 @@ public class EchoHandler extends BaseThingHandler implements IAmazonThingHandler private final Logger logger = LoggerFactory.getLogger(EchoHandler.class); private Gson gson = new Gson(); private @Nullable Device device; - private Set capabilities = new HashSet(); + private Set capabilities = new HashSet<>(); private @Nullable AccountHandler account; private @Nullable ScheduledFuture updateStateJob; private @Nullable ScheduledFuture ignoreVolumeChange; @@ -133,7 +133,7 @@ public class EchoHandler extends BaseThingHandler implements IAmazonThingHandler private @Nullable JsonPlaylists playLists; private @Nullable JsonNotificationSound @Nullable [] alarmSounds; private @Nullable List musicProviders; - private List channelHandlers = new ArrayList(); + private List channelHandlers = new ArrayList<>(); private @Nullable JsonNotificationResponse currentNotification; private @Nullable ScheduledFuture currentNotifcationUpdateTimer; @@ -388,7 +388,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { + ",\"contentFocusClientId\":\"Default\"}"); } else { - Map parameters = new Hashtable(); + Map parameters = new Hashtable<>(); parameters.put("value", volume); connection.executeSequenceCommand(device, "Alexa.DeviceControls.Volume", parameters); } @@ -1355,4 +1355,4 @@ public void updateNotifications(ZonedDateTime currentTime, ZonedDateTime now, public void updateChannelState(String channelId, State state) { updateState(channelId, state); } -} \ No newline at end of file +} diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/thing/thing-types.xml index 8e4dcaa62826b..f2447c3ec654f 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/resources/ESH-INF/thing/thing-types.xml @@ -473,4 +473,4 @@ Next timer - \ No newline at end of file + From 215862c6cb6a28b4a6d461962af47ace13eac36d Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Mon, 20 May 2019 20:18:03 +0200 Subject: [PATCH 13/20] [amazonechocontrol] Remove hashtable Signed-off-by: Michael Geramb (github: mgeramb) --- .../internal/AmazonEchoControlHandlerFactory.java | 2 +- .../binding/amazonechocontrol/internal/Connection.java | 9 ++++----- .../internal/discovery/AmazonEchoDiscovery.java | 4 ++-- .../amazonechocontrol/internal/handler/EchoHandler.java | 3 +-- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java index 4b7722e52ae07..f2fbe65d44bd7 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java @@ -124,7 +124,7 @@ private synchronized void registerDiscoveryService(AccountHandler bridgeHandler) AmazonEchoDiscovery discoveryService = new AmazonEchoDiscovery(bridgeHandler); discoveryService.activate(); this.discoveryServiceRegistrations.put(bridgeHandler.getThing().getUID(), bundleContext - .registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable())); + .registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>())); } @Override diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index de0f43723eee5..be8e242fd6bfb 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -31,7 +31,6 @@ import java.util.Base64; import java.util.Date; import java.util.HashMap; -import java.util.Hashtable; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -1080,7 +1079,7 @@ public void playAmazonMusicPlayList(Device device, @Nullable String playListId) public void sendNotificationToMobileApp(String customerId, String text, @Nullable String title) throws IOException, URISyntaxException { - Map parameters = new Hashtable<>(); + Map parameters = new HashMap<>(); parameters.put("notificationMessage", text); parameters.put("alexaUrl", "#v2/behaviors"); if (title != null && !StringUtils.isEmpty(title)) { @@ -1094,7 +1093,7 @@ public void sendNotificationToMobileApp(String customerId, String text, @Nullabl public void sendAnnouncement(Device device, String text, @Nullable String bodyText, @Nullable String title, int ttsVolume, int standardVolume) throws IOException, URISyntaxException { - Map parameters = new Hashtable<>(); + Map parameters = new HashMap<>(); parameters.put("expireAfter", "PT5S"); JsonAnnouncementContent[] contentArray = new JsonAnnouncementContent[1]; JsonAnnouncementContent content = new JsonAnnouncementContent(); @@ -1138,7 +1137,7 @@ public void sendAnnouncement(Device device, String text, @Nullable String bodyTe public void textToSpeech(Device device, String text, int ttsVolume, int standardVolume) throws IOException, URISyntaxException { - Map parameters = new Hashtable<>(); + Map parameters = new HashMap<>(); parameters.put("textToSpeak", text); executeSequenceCommandWithVolume(device, "Alexa.Speak", parameters, ttsVolume, standardVolume); } @@ -1150,7 +1149,7 @@ private void executeSequenceCommandWithVolume(@Nullable Device device, String co JsonArray nodesToExecute = new JsonArray(); - Map volumeParameters = new Hashtable<>(); + Map volumeParameters = new HashMap<>(); // add tts volume volumeParameters.clear(); volumeParameters.put("value", ttsVolume); diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java index 09edb6bd1a043..d5dd3ca0b46ca 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/discovery/AmazonEchoDiscovery.java @@ -15,8 +15,8 @@ import static org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.*; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; -import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.concurrent.ScheduledFuture; @@ -68,7 +68,7 @@ public AmazonEchoDiscovery(AccountHandler accountHandler) { } public void activate() { - activate(new Hashtable<>()); + activate(new HashMap<>()); } @Override diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java index e99b3d3e19917..257cf8812809d 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java @@ -22,7 +22,6 @@ import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.HashSet; -import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Objects; @@ -388,7 +387,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { + ",\"contentFocusClientId\":\"Default\"}"); } else { - Map parameters = new Hashtable<>(); + Map parameters = new HashMap<>(); parameters.put("value", volume); connection.executeSequenceCommand(device, "Alexa.DeviceControls.Volume", parameters); } From e16f4909a3dc4ce7c86c06c24be33ab8a2558c77 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Tue, 21 May 2019 20:26:29 +0200 Subject: [PATCH 14/20] [amazonechocontrol] Change tryGetBootstrap Signed-off-by: Michael Geramb (github: mgeramb) --- .../binding/amazonechocontrol/internal/Connection.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index be8e242fd6bfb..7af9584cb15c7 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -426,11 +426,12 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade } private @Nullable Authentication tryGetBootstrap() throws IOException, URISyntaxException { - String bootstrapResultJson = makeRequestAndReturnString(alexaServer + "/api/bootstrap").trim(); - boolean authenticationResult = bootstrapResultJson.contains("authenticated") && bootstrapResultJson.startsWith("{") && bootstrapResultJson.endsWith("}"); - if (authenticationResult) { + HttpsURLConnection connection = makeRequest("GET", alexaServer + "/api/bootstrap", null, false, false, null, false); + String contentType = connection.getContentType(); + if (connection.getResponseCode() == 200 && StringUtils.startsWithIgnoreCase(contentType, "application/json")) { try { + String bootstrapResultJson = convertStream(connection); JsonBootstrapResult result = parseJson(bootstrapResultJson, JsonBootstrapResult.class); Authentication authentication = result.authentication; if (authentication != null && authentication.authenticated) { @@ -446,7 +447,7 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade // We have not received a valid json return null; } - } + } return null; } From ffe59b3545a6ce7c364358ba01fd3ce56735051f Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Tue, 21 May 2019 21:18:33 +0200 Subject: [PATCH 15/20] [amazonechocontrol] Fix build error Signed-off-by: Michael Geramb (github: mgeramb) --- .../binding/amazonechocontrol/internal/handler/EchoHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java index 257cf8812809d..c9594b63ff5c3 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java @@ -21,6 +21,7 @@ import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; From 9f8d88a06563a3d60f46889d3e2b00bb059809c1 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Wed, 22 May 2019 06:56:43 +0200 Subject: [PATCH 16/20] [amazonechocontrol] Correct formatting Signed-off-by: Michael Geramb (github: mgeramb) --- .../internal/Connection.java | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index 7af9584cb15c7..10eb457847fad 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -426,28 +426,28 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade } private @Nullable Authentication tryGetBootstrap() throws IOException, URISyntaxException { - HttpsURLConnection connection = makeRequest("GET", alexaServer + "/api/bootstrap", null, false, false, null, false); - String contentType = connection.getContentType(); - if (connection.getResponseCode() == 200 && StringUtils.startsWithIgnoreCase(contentType, "application/json")) { - try - { - String bootstrapResultJson = convertStream(connection); - JsonBootstrapResult result = parseJson(bootstrapResultJson, JsonBootstrapResult.class); - Authentication authentication = result.authentication; - if (authentication != null && authentication.authenticated) { - this.customerName = authentication.customerName; - if (this.accountCustomerId == null) { - this.accountCustomerId = authentication.customerId; - } - return authentication; - } - } - catch (JsonSyntaxException | IllegalStateException e) - { - // We have not received a valid json - return null; - } - } + HttpsURLConnection connection = makeRequest("GET", alexaServer + "/api/bootstrap", null, false, false, null, false); + String contentType = connection.getContentType(); + if (connection.getResponseCode() == 200 && StringUtils.startsWithIgnoreCase(contentType, "application/json")) { + try + { + String bootstrapResultJson = convertStream(connection); + JsonBootstrapResult result = parseJson(bootstrapResultJson, JsonBootstrapResult.class); + Authentication authentication = result.authentication; + if (authentication != null && authentication.authenticated) { + this.customerName = authentication.customerName; + if (this.accountCustomerId == null) { + this.accountCustomerId = authentication.customerId; + } + return authentication; + } + } + catch (JsonSyntaxException | IllegalStateException e) + { + // We have not received a valid json + return null; + } + } return null; } @@ -499,13 +499,13 @@ public String makeRequestAndReturnString(String verb, String url, @Nullable Stri public HttpsURLConnection makeRequest(String verb, String url, @Nullable String postData, boolean json, boolean autoredirect, @Nullable Map customHeaders, boolean repeatBadRequest) - throws IOException, URISyntaxException { + throws IOException, URISyntaxException { String currentUrl = url; int badRequestCounter = 0; int redirectCounter = 0; while (true) // loop for handling redirect and bad request, using automatic redirect is not possible, - // because - // all response headers must be catched + // because + // all response headers must be catched { int code; HttpsURLConnection connection = null; @@ -751,9 +751,9 @@ private void exhangeToken() throws IOException, URISyntaxException { String cookiesBase64 = Base64.getEncoder().encodeToString(cookiesJson.getBytes()); String exchangePostData = "di.os.name=iOS&app_version=2.2.223830.0&domain=." + getAmazonSite() - + "&source_token=" + URLEncoder.encode(this.refreshToken, "UTF8") - + "&requested_token_type=auth_cookies&source_token_type=refresh_token&di.hw.version=iPhone&di.sdk.version=6.10.0&cookies=" - + cookiesBase64 + "&app_name=Amazon%20Alexa&di.os.version=11.4.1"; + + "&source_token=" + URLEncoder.encode(this.refreshToken, "UTF8") + + "&requested_token_type=auth_cookies&source_token_type=refresh_token&di.hw.version=iPhone&di.sdk.version=6.10.0&cookies=" + + cookiesBase64 + "&app_name=Amazon%20Alexa&di.os.version=11.4.1"; HashMap exchangeTokenHeader = new HashMap<>(); exchangeTokenHeader.put("Cookie", ""); @@ -1039,10 +1039,10 @@ public void playRadio(Device device, @Nullable String stationId) throws IOExcept } else { makeRequest("POST", alexaServer + "/api/tunein/queue-and-play?deviceSerialNumber=" + device.serialNumber - + "&deviceType=" + device.deviceType + "&guideId=" + stationId - + "&contentType=station&callSign=&mediaOwnerCustomerId=" - + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId - : this.accountCustomerId), + + "&deviceType=" + device.deviceType + "&guideId=" + stationId + + "&contentType=station&callSign=&mediaOwnerCustomerId=" + + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId + : this.accountCustomerId), "", true, true, null, false); } } @@ -1054,10 +1054,10 @@ public void playAmazonMusicTrack(Device device, @Nullable String trackId) throws String command = "{\"trackId\":\"" + trackId + "\",\"playQueuePrime\":true}"; makeRequest("POST", alexaServer + "/api/cloudplayer/queue-and-play?deviceSerialNumber=" + device.serialNumber - + "&deviceType=" + device.deviceType + "&mediaOwnerCustomerId=" - + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId - : this.accountCustomerId) - + "&shuffle=false", + + "&deviceType=" + device.deviceType + "&mediaOwnerCustomerId=" + + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId + : this.accountCustomerId) + + "&shuffle=false", command, true, true, null, false); } } @@ -1070,10 +1070,10 @@ public void playAmazonMusicPlayList(Device device, @Nullable String playListId) String command = "{\"playlistId\":\"" + playListId + "\",\"playQueuePrime\":true}"; makeRequest("POST", alexaServer + "/api/cloudplayer/queue-and-play?deviceSerialNumber=" + device.serialNumber - + "&deviceType=" + device.deviceType + "&mediaOwnerCustomerId=" - + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId - : this.accountCustomerId) - + "&shuffle=false", + + "&deviceType=" + device.deviceType + "&mediaOwnerCustomerId=" + + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId + : this.accountCustomerId) + + "&shuffle=false", command, true, true, null, false); } } @@ -1145,7 +1145,7 @@ public void textToSpeech(Device device, String text, int ttsVolume, int standard private void executeSequenceCommandWithVolume(@Nullable Device device, String command, @Nullable Map parameters, int ttsVolume, int standardVolume) - throws IOException, URISyntaxException { + throws IOException, URISyntaxException { if (ttsVolume != 0) { JsonArray nodesToExecute = new JsonArray(); @@ -1355,7 +1355,7 @@ public JsonNotificationResponse notification(Device device, String type, @Nullab Date date = new Date(new Date().getTime()); long createdDate = date.getTime(); Date alarm = new Date(createdDate + 5000); // add 5 seconds, because amazon does not except calls for times in - // the past (compared with the server time) + // the past (compared with the server time) long alarmTime = alarm.getTime(); JsonNotificationRequest request = new JsonNotificationRequest(); @@ -1468,5 +1468,5 @@ public void SetEqualizer(Device device, JsonEqualizer settings) throws IOExcepti String postData = gson.toJson(settings); makeRequest("POST", alexaServer + "/api/equalizer/" + device.serialNumber + "/" + device.deviceType, postData, true, true, null, false); - } + } } From 88fba7ea9bfe60f12e69e716cb7e9a7899c42e6f Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Thu, 20 Jun 2019 08:02:56 +0200 Subject: [PATCH 17/20] [amazonechocontrol] Sleep removed Signed-off-by: Michael Geramb (github: mgeramb) --- .../internal/AccountServlet.java | 2 +- .../internal/Connection.java | 61 +++++++++++-------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java index c21c4dd9833e2..5a4ec0b6cc85d 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java @@ -629,7 +629,7 @@ void handleProxyRequest(Connection connection, HttpServletResponse resp, String headers.put("Referer", referer); } - urlConnection = connection.makeRequest(verb, url, postData, json, false, headers, false); + urlConnection = connection.makeRequest(verb, url, postData, json, false, headers, 0); if (urlConnection.getResponseCode() == 302) { { String location = urlConnection.getHeaderField("location"); diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index 10eb457847fad..b09f23b718d73 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -36,6 +36,8 @@ import java.util.Map; import java.util.Random; import java.util.Scanner; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; @@ -45,6 +47,7 @@ import org.apache.commons.lang.StringUtils; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.common.ThreadPoolManager; import org.eclipse.smarthome.core.util.HexUtils; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonActivities; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonActivities.Activity; @@ -111,9 +114,15 @@ */ @NonNullByDefault public class Connection { + + private static final String THING_THREADPOOL_NAME = "thingHandler"; + + protected final ScheduledExecutorService scheduler = ThreadPoolManager + .getScheduledPool(THING_THREADPOOL_NAME); + private static final long expiresIn = 432000; // five days private static final Pattern charsetPattern = Pattern.compile("(?i)\\bcharset=\\s*\"?([^\\s;\"]*)"); - + private final Logger logger = LoggerFactory.getLogger(Connection.class); private final CookieManager cookieManager = new CookieManager(); @@ -426,7 +435,7 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade } private @Nullable Authentication tryGetBootstrap() throws IOException, URISyntaxException { - HttpsURLConnection connection = makeRequest("GET", alexaServer + "/api/bootstrap", null, false, false, null, false); + HttpsURLConnection connection = makeRequest("GET", alexaServer + "/api/bootstrap", null, false, false, null, 0); String contentType = connection.getContentType(); if (connection.getResponseCode() == 200 && StringUtils.startsWithIgnoreCase(contentType, "application/json")) { try @@ -491,17 +500,16 @@ public String makeRequestAndReturnString(String url) throws IOException, URISynt public String makeRequestAndReturnString(String verb, String url, @Nullable String postData, boolean json, @Nullable Map customHeaders) throws IOException, URISyntaxException { - HttpsURLConnection connection = makeRequest(verb, url, postData, json, true, customHeaders, false); + HttpsURLConnection connection = makeRequest(verb, url, postData, json, true, customHeaders, 0); String result = convertStream(connection); this.logger.debug("Result of {} {}:{}", verb, url, result); return result; } public HttpsURLConnection makeRequest(String verb, String url, @Nullable String postData, boolean json, - boolean autoredirect, @Nullable Map customHeaders, boolean repeatBadRequest) + boolean autoredirect, @Nullable Map customHeaders, int badRequestRepeats) throws IOException, URISyntaxException { String currentUrl = url; - int badRequestCounter = 0; int redirectCounter = 0; while (true) // loop for handling redirect and bad request, using automatic redirect is not possible, // because @@ -613,16 +621,17 @@ public HttpsURLConnection makeRequest(String verb, String url, @Nullable String } } } - if (code == 400 && repeatBadRequest) { - badRequestCounter++; - if (badRequestCounter < 3) { + if (code == 400 && badRequestRepeats > 0) { + scheduler.schedule(() -> { + logger.debug("Retry call to {}", url); try { - Thread.sleep(500); - } catch (InterruptedException e) { + makeRequest(verb, url, postData, json, + autoredirect, customHeaders, badRequestRepeats - 1); + } catch (IOException | URISyntaxException e) { + logger.debug("Repeat fails {}", e); } - continue; // repeat call - } - badRequestCounter += 0; + }, 500, TimeUnit.MILLISECONDS); + return connection; } if (code == 200) { logger.debug("Call to {} succeeded", url); @@ -971,7 +980,7 @@ public JsonPlaylists getPlaylists(Device device) throws IOException, URISyntaxEx public void command(Device device, String command) throws IOException, URISyntaxException { String url = alexaServer + "/api/np/command?deviceSerialNumber=" + device.serialNumber + "&deviceType=" + device.deviceType; - makeRequest("POST", url, command, true, true, null, false); + makeRequest("POST", url, command, true, true, null, 0); } public void notificationVolume(Device device, int volume) throws IOException, URISyntaxException { @@ -979,7 +988,7 @@ public void notificationVolume(Device device, int volume) throws IOException, UR + "/" + device.serialNumber; String command = "{\"deviceSerialNumber\":\"" + device.serialNumber + "\",\"deviceType\":\"" + device.deviceType + "\",\"softwareVersion\":\"" + device.softwareVersion + "\",\"volumeLevel\":" + volume + "}"; - makeRequest("PUT", url, command, true, true, null, false); + makeRequest("PUT", url, command, true, true, null, 0); } public void ascendingAlarm(Device device, boolean ascendingAlarm) throws IOException, URISyntaxException { @@ -987,7 +996,7 @@ public void ascendingAlarm(Device device, boolean ascendingAlarm) throws IOExcep String command = "{\"ascendingAlarmEnabled\":" + (ascendingAlarm ? "true" : "false") + ",\"deviceSerialNumber\":\"" + device.serialNumber + "\",\"deviceType\":\"" + device.deviceType + "\",\"deviceAccountId\":null}"; - makeRequest("PUT", url, command, true, true, null, false); + makeRequest("PUT", url, command, true, true, null, 0); } public DeviceNotificationState[] getDeviceNotificationStates() { @@ -1025,11 +1034,11 @@ public void bluetooth(Device device, @Nullable String address) throws IOExceptio // disconnect makeRequest("POST", alexaServer + "/api/bluetooth/disconnect-sink/" + device.deviceType + "/" + device.serialNumber, "", - true, true, null, false); + true, true, null, 0); } else { makeRequest("POST", alexaServer + "/api/bluetooth/pair-sink/" + device.deviceType + "/" + device.serialNumber, - "{\"bluetoothDeviceAddress\":\"" + address + "\"}", true, true, null, false); + "{\"bluetoothDeviceAddress\":\"" + address + "\"}", true, true, null, 0); } } @@ -1043,7 +1052,7 @@ public void playRadio(Device device, @Nullable String stationId) throws IOExcept + "&contentType=station&callSign=&mediaOwnerCustomerId=" + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId : this.accountCustomerId), - "", true, true, null, false); + "", true, true, null, 0); } } @@ -1058,7 +1067,7 @@ public void playAmazonMusicTrack(Device device, @Nullable String trackId) throws + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId : this.accountCustomerId) + "&shuffle=false", - command, true, true, null, false); + command, true, true, null, 0); } } @@ -1074,7 +1083,7 @@ public void playAmazonMusicPlayList(Device device, @Nullable String playListId) + (StringUtils.isEmpty(this.accountCustomerId) ? device.deviceOwnerCustomerId : this.accountCustomerId) + "&shuffle=false", - command, true, true, null, false); + command, true, true, null, 0); } } @@ -1191,7 +1200,7 @@ private void executeSequenceNode(JsonObject nodeToExecute) throws IOException, U Map headers = new HashMap<>(); headers.put("Routines-Version", "1.1.218665"); - makeRequest("POST", alexaServer + "/api/behaviors/preview", json, true, true, null, true); + makeRequest("POST", alexaServer + "/api/behaviors/preview", json, true, true, null, 3); } private void executeSequenceNodes(JsonArray nodesToExecute) throws IOException, URISyntaxException { @@ -1299,7 +1308,7 @@ public void startRoutine(Device device, String utterance) throws IOException, UR request.sequenceJson = sequenceJson; String requestJson = gson.toJson(request); - makeRequest("POST", alexaServer + "/api/behaviors/preview", requestJson, true, true, null, true); + makeRequest("POST", alexaServer + "/api/behaviors/preview", requestJson, true, true, null, 3); } else { logger.warn("Routine {} not found", utterance); } @@ -1325,7 +1334,7 @@ public void setEnabledFlashBriefings(JsonFeed[] enabledFlashBriefing) throws IOE JsonEnabledFeeds enabled = new JsonEnabledFeeds(); enabled.enabledFeeds = enabledFlashBriefing; String json = gsonWithNullSerialization.toJson(enabled); - makeRequest("POST", alexaServer + "/api/content-skills/enabled-feeds", json, true, true, null, false); + makeRequest("POST", alexaServer + "/api/content-skills/enabled-feeds", json, true, true, null, 0); } public JsonNotificationSound[] getNotificationSounds(Device device) throws IOException, URISyntaxException { @@ -1455,7 +1464,7 @@ public void playMusicVoiceCommand(Device device, String providerId, String voice startRoutineRequest.status = null; String postData = gson.toJson(startRoutineRequest); - makeRequest("POST", alexaServer + "/api/behaviors/preview", postData, true, true, null, true); + makeRequest("POST", alexaServer + "/api/behaviors/preview", postData, true, true, null, 3); } public JsonEqualizer getEqualizer(Device device) throws IOException, URISyntaxException { @@ -1467,6 +1476,6 @@ public JsonEqualizer getEqualizer(Device device) throws IOException, URISyntaxEx public void SetEqualizer(Device device, JsonEqualizer settings) throws IOException, URISyntaxException { String postData = gson.toJson(settings); makeRequest("POST", alexaServer + "/api/equalizer/" + device.serialNumber + "/" + device.deviceType, postData, - true, true, null, false); + true, true, null, 0); } } From f89296a759b3d00bb783aaddc4ec9e8792ad7c31 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sun, 23 Jun 2019 13:02:50 +0200 Subject: [PATCH 18/20] [amazonechocontrol] Single Gson instance Signed-off-by: Michael Geramb (github: mgeramb) --- .../internal/AccountServlet.java | 11 ++++++----- .../AmazonEchoControlHandlerFactory.java | 16 +++++++++++++--- .../amazonechocontrol/internal/Connection.java | 5 +++-- .../internal/channelhandler/ChannelHandler.java | 5 +++-- .../ChannelHandlerAnnouncement.java | 5 +++-- .../internal/handler/AccountHandler.java | 9 +++++---- .../internal/handler/EchoHandler.java | 7 ++++--- 7 files changed, 37 insertions(+), 21 deletions(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java index 5a4ec0b6cc85d..fa4d71bcb41e0 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java @@ -83,12 +83,13 @@ public class AccountServlet extends HttpServlet { String id; @Nullable Connection connectionToInitialize; - Gson gson = new Gson(); + Gson gson; - public AccountServlet(HttpService httpService, String id, AccountHandler account) { + public AccountServlet(HttpService httpService, String id, AccountHandler account, Gson gson) { this.httpService = httpService; this.account = account; this.id = id; + this.gson = gson; try { servletUrlWithoutRoot = "amazonechocontrol/" + URLEncoder.encode(id, "UTF8"); } catch (UnsupportedEncodingException e) { @@ -112,7 +113,7 @@ private Connection reCreateConnection() { if (oldConnection == null) { oldConnection = account.findConnection(); } - return new Connection(oldConnection); + return new Connection(oldConnection, this.gson); } public void dispose() { @@ -157,7 +158,7 @@ void doVerb(String verb, @Nullable HttpServletRequest req, @Nullable HttpServlet Map map = req.getParameterMap(); String domain = map.get("domain")[0]; String loginData = connection.serializeLoginData(); - Connection newConnection = new Connection(null); + Connection newConnection = new Connection(null, this.gson); if (newConnection.tryRestoreLogin(loginData, domain)) { account.setConnection(newConnection); } @@ -282,7 +283,7 @@ protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResp } // handle commands if (baseUrl.equals("/newdevice") || baseUrl.equals("/newdevice/")) { - this.connectionToInitialize = new Connection(null); + this.connectionToInitialize = new Connection(null, this.gson); this.account.setConnection(null); resp.sendRedirect(this.servletUrl); return; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java index f2fbe65d44bd7..f0cf1faf5e142 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AmazonEchoControlHandlerFactory.java @@ -42,6 +42,8 @@ import org.osgi.service.component.annotations.ReferencePolicy; import org.osgi.service.http.HttpService; +import com.google.gson.Gson; + /** * The {@link AmazonEchoControlHandlerFactory} is responsible for creating things and thing * handlers. @@ -60,7 +62,9 @@ public class AmazonEchoControlHandlerFactory extends BaseThingHandlerFactory { StorageService storageService; @Nullable BindingServlet bindingServlet; - + @Nullable + Gson gson; + @Override public boolean supportsThingType(ThingTypeUID thingTypeUID) { return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); @@ -97,11 +101,17 @@ protected void deactivate(ComponentContext componentContext) { if (storageService == null) { return null; } + Gson gson = this.gson; + if (gson == null) + { + gson = new Gson(); + this.gson = gson; + } if (thingTypeUID.equals(THING_TYPE_ACCOUNT)) { Storage storage = storageService.getStorage(thing.getUID().toString(), String.class.getClassLoader()); - AccountHandler bridgeHandler = new AccountHandler((Bridge) thing, httpService, storage); + AccountHandler bridgeHandler = new AccountHandler((Bridge) thing, httpService, storage, gson); registerDiscoveryService(bridgeHandler); BindingServlet bindingServlet = this.bindingServlet; if (bindingServlet != null) { @@ -115,7 +125,7 @@ protected void deactivate(ComponentContext componentContext) { return new FlashBriefingProfileHandler(thing, storage); } if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) { - return new EchoHandler(thing); + return new EchoHandler(thing, gson); } return null; } diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index b09f23b718d73..9d30aa4d05f02 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -141,10 +141,11 @@ public class Connection { private @Nullable String accountCustomerId; private @Nullable String customerName; - private final Gson gson = new Gson(); + private final Gson gson; private final Gson gsonWithNullSerialization; - public Connection(@Nullable Connection oldConnection) { + public Connection(@Nullable Connection oldConnection, Gson gson) { + this.gson = gson; String frc = null; String serial = null; String deviceId = null; diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java index 5978f699235fc..cd288e6dc3d46 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandler.java @@ -35,12 +35,13 @@ public abstract boolean tryHandleCommand(Device device, Connection connection, S throws IOException, URISyntaxException; protected final IAmazonThingHandler thingHandler; - protected final Gson gson = new Gson(); + protected final Gson gson; private final Logger logger; - protected ChannelHandler(IAmazonThingHandler thingHandler) { + protected ChannelHandler(IAmazonThingHandler thingHandler, Gson gson) { this.logger = LoggerFactory.getLogger(this.getClass()); this.thingHandler = thingHandler; + this.gson = gson; } protected @Nullable T tryParseJson(String json, Class type) { diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java index 7c6a45e1920a0..26425b44b21aa 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/channelhandler/ChannelHandlerAnnouncement.java @@ -21,6 +21,7 @@ import org.openhab.binding.amazonechocontrol.internal.Connection; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonDevices.Device; +import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; /** @@ -31,8 +32,8 @@ public class ChannelHandlerAnnouncement extends ChannelHandler { public static final String CHANNEL_NAME = "announcement"; - public ChannelHandlerAnnouncement(IAmazonThingHandler thingHandler) { - super(thingHandler); + public ChannelHandlerAnnouncement(IAmazonThingHandler thingHandler, Gson gson) { + super(thingHandler, gson); } @Override diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java index 94f1a6dd018a8..871c56798e13b 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/AccountHandler.java @@ -95,11 +95,12 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma private String currentFlashBriefingJson = ""; private final HttpService httpService; private @Nullable AccountServlet accountServlet; - private final Gson gson = new Gson(); + private final Gson gson; int checkDataCounter; - public AccountHandler(Bridge bridge, HttpService httpService, Storage stateStorage) { + public AccountHandler(Bridge bridge, HttpService httpService, Storage stateStorage, Gson gson) { super(bridge); + this.gson = gson; this.httpService = httpService; this.stateStorage = stateStorage; } @@ -111,11 +112,11 @@ public void initialize() { synchronized (synchronizeConnection) { Connection connection = this.connection; if (connection == null) { - this.connection = new Connection(null); + this.connection = new Connection(null, gson); } } if (this.accountServlet == null) { - this.accountServlet = new AccountServlet(httpService, this.getThing().getUID().getId(), this); + this.accountServlet = new AccountServlet(httpService, this.getThing().getUID().getId(), this, gson); } updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING, "Wait for login"); diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java index c9594b63ff5c3..42c0084d26994 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/handler/EchoHandler.java @@ -102,7 +102,7 @@ public class EchoHandler extends BaseThingHandler implements IAmazonThingHandler { private final Logger logger = LoggerFactory.getLogger(EchoHandler.class); - private Gson gson = new Gson(); + private Gson gson; private @Nullable Device device; private Set capabilities = new HashSet<>(); private @Nullable AccountHandler account; @@ -142,9 +142,10 @@ public class EchoHandler extends BaseThingHandler implements IAmazonThingHandler long mediaStartMs; String lastSpokenText = ""; - public EchoHandler(Thing thing) { + public EchoHandler(Thing thing, Gson gson) { super(thing); - channelHandlers.add(new ChannelHandlerAnnouncement(this)); + this.gson = gson; + channelHandlers.add(new ChannelHandlerAnnouncement(this, this.gson)); } @Override From b71d8f8429ff710f1fefb5915dd2fccc038782ed Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sun, 23 Jun 2019 13:04:18 +0200 Subject: [PATCH 19/20] [amazonechocontrol] Add final Signed-off-by: Michael Geramb (github: mgeramb) --- .../binding/amazonechocontrol/internal/AccountServlet.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java index fa4d71bcb41e0..a4c32e59db2ab 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/AccountServlet.java @@ -76,14 +76,14 @@ public class AccountServlet extends HttpServlet { private final Logger logger = LoggerFactory.getLogger(AccountServlet.class); - HttpService httpService; + final HttpService httpService; String servletUrlWithoutRoot; - String servletUrl; + final String servletUrl; AccountHandler account; String id; @Nullable Connection connectionToInitialize; - Gson gson; + final Gson gson; public AccountServlet(HttpService httpService, String id, AccountHandler account, Gson gson) { this.httpService = httpService; From 56924a44395ef390400a0dbe3b8576cbeb97965f Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sun, 23 Jun 2019 13:09:48 +0200 Subject: [PATCH 20/20] [amazonechocontrol] Fix formatting and add trace Signed-off-by: Michael Geramb (github: mgeramb) --- .../binding/amazonechocontrol/internal/Connection.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java index 9d30aa4d05f02..1b9b20d2ee80d 100755 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/Connection.java @@ -439,8 +439,7 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade HttpsURLConnection connection = makeRequest("GET", alexaServer + "/api/bootstrap", null, false, false, null, 0); String contentType = connection.getContentType(); if (connection.getResponseCode() == 200 && StringUtils.startsWithIgnoreCase(contentType, "application/json")) { - try - { + try { String bootstrapResultJson = convertStream(connection); JsonBootstrapResult result = parseJson(bootstrapResultJson, JsonBootstrapResult.class); Authentication authentication = result.authentication; @@ -452,9 +451,8 @@ public boolean tryRestoreLogin(@Nullable String data, @Nullable String overloade return authentication; } } - catch (JsonSyntaxException | IllegalStateException e) - { - // We have not received a valid json + catch (JsonSyntaxException | IllegalStateException e) { + logger.info("No valid json received {}", e); return null; } }
NameValue