[amazonechocontrol] improvements and bug fixes (#9057)
* fixed: InterrupedException * changed: single and group queues to device queue added: standard volume to speak request * changed: log from info to debug * fix compile warnings * remove dependency on StringUtils * more improvements * fix HandlerPowerController * attempt to solve stopping tts * logging powercontroller * fix smarthome devices not updating * finalize smarthome device update fix * additional device information logging for discovery * fix color channel for smarthome devices Signed-off-by: Jan N. Klug <jan.n.klug@rub.de> Co-authored-by: Tom Blum <trinitus01@googlemail.com> Co-authored-by: Connor Petty <mistercpp2000@gmail.com>pull/9134/head
parent
62523e135a
commit
1b588bc4fa
|
@ -13,10 +13,10 @@
|
|||
package org.openhab.binding.amazonechocontrol.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.amazonechocontrol.internal.handler.AccountHandler;
|
||||
|
||||
/**
|
||||
* The {@link AccountHandlerConfig} holds the configuration for the {@link AccountHandler}
|
||||
* The {@link AccountHandlerConfig} holds the configuration for the
|
||||
* {@link org.openhab.binding.amazonechocontrol.internal.handler.AccountHandler}
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
|
|
|
@ -32,7 +32,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.amazonechocontrol.internal.handler.AccountHandler;
|
||||
|
@ -128,15 +127,18 @@ public class AccountServlet extends HttpServlet {
|
|||
doVerb("POST", req, resp);
|
||||
}
|
||||
|
||||
void doVerb(String verb, @Nullable HttpServletRequest req, @Nullable HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
void doVerb(String verb, @Nullable HttpServletRequest req, @Nullable HttpServletResponse resp) throws IOException {
|
||||
if (req == null) {
|
||||
return;
|
||||
}
|
||||
if (resp == null) {
|
||||
return;
|
||||
}
|
||||
String baseUrl = req.getRequestURI().substring(servletUrl.length());
|
||||
String requestUri = req.getRequestURI();
|
||||
if (requestUri == null) {
|
||||
return;
|
||||
}
|
||||
String baseUrl = requestUri.substring(servletUrl.length());
|
||||
String uri = baseUrl;
|
||||
String queryString = req.getQueryString();
|
||||
if (queryString != null && queryString.length() > 0) {
|
||||
|
@ -146,7 +148,12 @@ public class AccountServlet extends HttpServlet {
|
|||
Connection connection = this.account.findConnection();
|
||||
if (connection != null && uri.equals("/changedomain")) {
|
||||
Map<String, String[]> map = req.getParameterMap();
|
||||
String domain = map.get("domain")[0];
|
||||
String[] domainArray = map.get("domain");
|
||||
if (domainArray == null) {
|
||||
logger.warn("Could not determine domain");
|
||||
return;
|
||||
}
|
||||
String domain = domainArray[0];
|
||||
String loginData = connection.serializeLoginData();
|
||||
Connection newConnection = new Connection(null, this.gson);
|
||||
if (newConnection.tryRestoreLogin(loginData, domain)) {
|
||||
|
@ -192,15 +199,20 @@ public class AccountServlet extends HttpServlet {
|
|||
|
||||
postDataBuilder.append(name);
|
||||
postDataBuilder.append('=');
|
||||
String value = map.get(name)[0];
|
||||
String value = "";
|
||||
if (name.equals("failedSignInCount")) {
|
||||
value = "ape:AA==";
|
||||
} else {
|
||||
String[] strings = map.get(name);
|
||||
if (strings != null && strings.length > 0 && strings[0] != null) {
|
||||
value = strings[0];
|
||||
}
|
||||
}
|
||||
postDataBuilder.append(URLEncoder.encode(value, StandardCharsets.UTF_8.name()));
|
||||
}
|
||||
|
||||
uri = req.getRequestURI();
|
||||
if (!uri.startsWith(servletUrl)) {
|
||||
if (uri == null || !uri.startsWith(servletUrl)) {
|
||||
returnError(resp, "Invalid request uri '" + uri + "'");
|
||||
return;
|
||||
}
|
||||
|
@ -221,15 +233,18 @@ public class AccountServlet extends HttpServlet {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
protected void doGet(@Nullable HttpServletRequest req, @Nullable HttpServletResponse resp) throws IOException {
|
||||
if (req == null) {
|
||||
return;
|
||||
}
|
||||
if (resp == null) {
|
||||
return;
|
||||
}
|
||||
String baseUrl = req.getRequestURI().substring(servletUrl.length());
|
||||
String requestUri = req.getRequestURI();
|
||||
if (requestUri == null) {
|
||||
return;
|
||||
}
|
||||
String baseUrl = requestUri.substring(servletUrl.length());
|
||||
String uri = baseUrl;
|
||||
String queryString = req.getQueryString();
|
||||
if (queryString != null && queryString.length() > 0) {
|
||||
|
@ -312,7 +327,7 @@ public class AccountServlet extends HttpServlet {
|
|||
|
||||
String html = connection.getLoginPage();
|
||||
returnHtml(connection, resp, html, "amazon.com");
|
||||
} catch (URISyntaxException e) {
|
||||
} catch (URISyntaxException | InterruptedException e) {
|
||||
logger.warn("get failed with uri syntax error", e);
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +434,8 @@ public class AccountServlet extends HttpServlet {
|
|||
createPageEndAndSent(resp, html);
|
||||
}
|
||||
|
||||
private void handleDevices(HttpServletResponse resp, Connection connection) throws IOException, URISyntaxException {
|
||||
private void handleDevices(HttpServletResponse resp, Connection connection)
|
||||
throws IOException, URISyntaxException, InterruptedException {
|
||||
returnHtml(connection, resp,
|
||||
"<html>" + StringEscapeUtils.escapeHtml(connection.getDeviceListJson()) + "</html>");
|
||||
}
|
||||
|
@ -435,13 +451,13 @@ public class AccountServlet extends HttpServlet {
|
|||
StringBuilder html = new StringBuilder();
|
||||
html.append("<html><head><title>"
|
||||
+ StringEscapeUtils.escapeHtml(BINDING_NAME + " - " + this.account.getThing().getLabel()));
|
||||
if (StringUtils.isNotEmpty(title)) {
|
||||
if (!title.isEmpty()) {
|
||||
html.append(" - ");
|
||||
html.append(StringEscapeUtils.escapeHtml(title));
|
||||
}
|
||||
html.append("</title><head><body>");
|
||||
html.append("<h1>" + StringEscapeUtils.escapeHtml(BINDING_NAME + " - " + this.account.getThing().getLabel()));
|
||||
if (StringUtils.isNotEmpty(title)) {
|
||||
if (!title.isEmpty()) {
|
||||
html.append(" - ");
|
||||
html.append(StringEscapeUtils.escapeHtml(title));
|
||||
}
|
||||
|
@ -502,9 +518,9 @@ public class AccountServlet extends HttpServlet {
|
|||
List<String> properties = musicProvider.supportedProperties;
|
||||
String providerId = musicProvider.id;
|
||||
String displayName = musicProvider.displayName;
|
||||
if (properties != null && properties.contains("Alexa.Music.PlaySearchPhrase")
|
||||
&& StringUtils.isNotEmpty(providerId) && StringUtils.equals(musicProvider.availability, "AVAILABLE")
|
||||
&& StringUtils.isNotEmpty(displayName)) {
|
||||
if (properties != null && properties.contains("Alexa.Music.PlaySearchPhrase") && providerId != null
|
||||
&& !providerId.isEmpty() && "AVAILABLE".equals(musicProvider.availability) && displayName != null
|
||||
&& !displayName.isEmpty()) {
|
||||
html.append("<tr><td>");
|
||||
html.append(StringEscapeUtils.escapeHtml(displayName));
|
||||
html.append("</td><td>");
|
||||
|
@ -521,7 +537,8 @@ public class AccountServlet extends HttpServlet {
|
|||
String errorMessage = "No notifications sounds found";
|
||||
try {
|
||||
notificationSounds = connection.getNotificationSounds(device);
|
||||
} catch (IOException | HttpException | URISyntaxException | JsonSyntaxException | ConnectionException e) {
|
||||
} catch (IOException | HttpException | URISyntaxException | JsonSyntaxException | ConnectionException
|
||||
| InterruptedException e) {
|
||||
errorMessage = e.getLocalizedMessage();
|
||||
}
|
||||
if (notificationSounds != null) {
|
||||
|
@ -551,7 +568,8 @@ public class AccountServlet extends HttpServlet {
|
|||
String errorMessage = "No playlists found";
|
||||
try {
|
||||
playLists = connection.getPlaylists(device);
|
||||
} catch (IOException | HttpException | URISyntaxException | JsonSyntaxException | ConnectionException e) {
|
||||
} catch (IOException | HttpException | URISyntaxException | JsonSyntaxException | ConnectionException
|
||||
| InterruptedException e) {
|
||||
errorMessage = e.getLocalizedMessage();
|
||||
}
|
||||
|
||||
|
@ -595,8 +613,9 @@ public class AccountServlet extends HttpServlet {
|
|||
if (state == null) {
|
||||
continue;
|
||||
}
|
||||
if ((state.deviceSerialNumber == null && device.serialNumber == null)
|
||||
|| (state.deviceSerialNumber != null && state.deviceSerialNumber.equals(device.serialNumber))) {
|
||||
String stateDeviceSerialNumber = state.deviceSerialNumber;
|
||||
if ((stateDeviceSerialNumber == null && device.serialNumber == null)
|
||||
|| (stateDeviceSerialNumber != null && stateDeviceSerialNumber.equals(device.serialNumber))) {
|
||||
PairedDevice[] pairedDeviceList = state.pairedDeviceList;
|
||||
if (pairedDeviceList != null && pairedDeviceList.length > 0) {
|
||||
html.append("<table><tr><th align='left'>Name</th><th align='left'>Value</th></tr>");
|
||||
|
@ -666,7 +685,7 @@ public class AccountServlet extends HttpServlet {
|
|||
return;
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException | ConnectionException e) {
|
||||
} catch (URISyntaxException | ConnectionException | InterruptedException e) {
|
||||
returnError(resp, e.getLocalizedMessage());
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -14,13 +14,7 @@ package org.openhab.binding.amazonechocontrol.internal;
|
|||
|
||||
import static org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
@ -117,8 +111,8 @@ public class AmazonEchoControlHandlerFactory extends BaseThingHandlerFactory {
|
|||
}
|
||||
|
||||
private synchronized void registerDiscoveryService(AccountHandler bridgeHandler) {
|
||||
List<ServiceRegistration<?>> discoveryServiceRegistration = discoveryServiceRegistrations
|
||||
.computeIfAbsent(bridgeHandler.getThing().getUID(), k -> new ArrayList<>());
|
||||
List<ServiceRegistration<?>> discoveryServiceRegistration = Objects.requireNonNull(discoveryServiceRegistrations
|
||||
.computeIfAbsent(bridgeHandler.getThing().getUID(), k -> new ArrayList<>()));
|
||||
SmartHomeDevicesDiscovery smartHomeDevicesDiscovery = new SmartHomeDevicesDiscovery(bridgeHandler);
|
||||
smartHomeDevicesDiscovery.activate();
|
||||
discoveryServiceRegistration.add(bundleContext.registerService(DiscoveryService.class.getName(),
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.amazonechocontrol.internal.handler.AccountHandler;
|
||||
|
@ -220,10 +219,9 @@ public class AmazonEchoDynamicStateDescriptionProvider implements DynamicStateDe
|
|||
List<String> properties = musicProvider.supportedProperties;
|
||||
String providerId = musicProvider.id;
|
||||
String displayName = musicProvider.displayName;
|
||||
if (properties != null && properties.contains("Alexa.Music.PlaySearchPhrase")
|
||||
&& StringUtils.isNotEmpty(providerId)
|
||||
&& StringUtils.equals(musicProvider.availability, "AVAILABLE")
|
||||
&& StringUtils.isNotEmpty(displayName) && providerId != null) {
|
||||
if (properties != null && properties.contains("Alexa.Music.PlaySearchPhrase") && providerId != null
|
||||
&& !providerId.isEmpty() && "AVAILABLE".equals(musicProvider.availability)
|
||||
&& displayName != null && !displayName.isEmpty()) {
|
||||
options.add(new StateOption(providerId, displayName));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.slf4j.LoggerFactory;
|
|||
*/
|
||||
@NonNullByDefault
|
||||
public class BindingServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = -1453738923337413163L;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(BindingServlet.class);
|
||||
|
@ -87,7 +86,11 @@ public class BindingServlet extends HttpServlet {
|
|||
if (resp == null) {
|
||||
return;
|
||||
}
|
||||
String uri = req.getRequestURI().substring(servletUrl.length());
|
||||
String requestUri = req.getRequestURI();
|
||||
if (requestUri == null) {
|
||||
return;
|
||||
}
|
||||
String uri = requestUri.substring(servletUrl.length());
|
||||
String queryString = req.getQueryString();
|
||||
if (queryString != null && queryString.length() > 0) {
|
||||
uri += "?" + queryString;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,7 +28,6 @@ import java.util.UUID;
|
|||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
@ -79,7 +78,7 @@ public class WebSocketConnection {
|
|||
webSocketClient = new WebSocketClient(sslContextFactory);
|
||||
try {
|
||||
String host;
|
||||
if (StringUtils.equalsIgnoreCase(amazonSite, "amazon.com")) {
|
||||
if (amazonSite.equalsIgnoreCase("amazon.com")) {
|
||||
host = "dp-gw-na-js." + amazonSite;
|
||||
} else {
|
||||
host = "dp-gw-na." + amazonSite;
|
||||
|
@ -196,7 +195,6 @@ public class WebSocketConnection {
|
|||
}
|
||||
|
||||
@WebSocket(maxTextMessageSize = 64 * 1024, maxBinaryMessageSize = 64 * 1024)
|
||||
@SuppressWarnings("unused")
|
||||
public class AmazonEchoControlWebSocket {
|
||||
int msgCounter = -1;
|
||||
int messageId;
|
||||
|
@ -349,19 +347,17 @@ public class WebSocketConnection {
|
|||
if (idDataElements.length == 2) {
|
||||
payload = idDataElements[1];
|
||||
}
|
||||
if (message.content.payload == null) {
|
||||
if (payload == null) {
|
||||
payload = readString(data, idx, data.length - 4 - idx);
|
||||
}
|
||||
message.content.payload = payload;
|
||||
if (StringUtils.isNotEmpty(payload)) {
|
||||
if (!payload.isEmpty()) {
|
||||
try {
|
||||
message.content.pushCommand = gson.fromJson(message.content.payload,
|
||||
JsonPushCommand.class);
|
||||
message.content.pushCommand = gson.fromJson(payload, JsonPushCommand.class);
|
||||
} catch (JsonSyntaxException e) {
|
||||
logger.info("Parsing json failed", e);
|
||||
logger.info("Illegal json: {}", payload);
|
||||
logger.info("Parsing json failed, illegal JSON: {}", payload, e);
|
||||
}
|
||||
}
|
||||
message.content.payload = payload;
|
||||
}
|
||||
}
|
||||
} else if (message.channel == 0x65) { // CHANNEL_FOR_HEARTBEAT
|
||||
|
|
|
@ -35,7 +35,7 @@ import com.google.gson.JsonSyntaxException;
|
|||
public abstract class ChannelHandler {
|
||||
|
||||
public abstract boolean tryHandleCommand(Device device, Connection connection, String channelId, Command command)
|
||||
throws IOException, URISyntaxException;
|
||||
throws IOException, URISyntaxException, InterruptedException;
|
||||
|
||||
protected final IAmazonThingHandler thingHandler;
|
||||
protected final Gson gson;
|
||||
|
|
|
@ -44,7 +44,7 @@ public class ChannelHandlerSendMessage extends ChannelHandler {
|
|||
|
||||
@Override
|
||||
public boolean tryHandleCommand(Device device, Connection connection, String channelId, Command command)
|
||||
throws IOException, URISyntaxException {
|
||||
throws IOException, URISyntaxException, InterruptedException {
|
||||
if (channelId.equals(CHANNEL_NAME)) {
|
||||
if (command instanceof StringType) {
|
||||
String commandValue = ((StringType) command).toFullString();
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.openhab.binding.amazonechocontrol.internal.Connection;
|
|||
import org.openhab.binding.amazonechocontrol.internal.handler.AccountHandler;
|
||||
import org.openhab.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeCapabilities;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDeviceAlias;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.DriverIdentity;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.SmartHomeDevice;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeGroups.SmartHomeGroup;
|
||||
|
@ -145,6 +146,7 @@ public class SmartHomeDevicesDiscovery extends AbstractDiscoveryService {
|
|||
|
||||
if (smartHomeDevice instanceof SmartHomeDevice) {
|
||||
SmartHomeDevice shd = (SmartHomeDevice) smartHomeDevice;
|
||||
logger.trace("Found SmartHome device: {}", shd);
|
||||
|
||||
String entityId = shd.entityId;
|
||||
if (entityId == null) {
|
||||
|
@ -178,23 +180,24 @@ public class SmartHomeDevicesDiscovery extends AbstractDiscoveryService {
|
|||
|
||||
thingUID = new ThingUID(THING_TYPE_SMART_HOME_DEVICE, bridgeThingUID, entityId.replace(".", "-"));
|
||||
|
||||
JsonSmartHomeDeviceAlias[] aliases = shd.aliases;
|
||||
if ("Amazon".equals(shd.manufacturerName) && driverIdentity != null
|
||||
&& "SonarCloudService".equals(driverIdentity.identifier)) {
|
||||
deviceName = "Alexa Guard on " + shd.friendlyName;
|
||||
} else if ("Amazon".equals(shd.manufacturerName) && driverIdentity != null
|
||||
&& "OnGuardSmartHomeBridgeService".equals(driverIdentity.identifier)) {
|
||||
deviceName = "Alexa Guard";
|
||||
} else if (shd.aliases != null && shd.aliases.length > 0 && shd.aliases[0] != null
|
||||
&& shd.aliases[0].friendlyName != null) {
|
||||
deviceName = shd.aliases[0].friendlyName;
|
||||
} else if (aliases != null && aliases.length > 0 && aliases[0] != null
|
||||
&& aliases[0].friendlyName != null) {
|
||||
deviceName = aliases[0].friendlyName;
|
||||
} else {
|
||||
deviceName = shd.friendlyName;
|
||||
}
|
||||
props.put(DEVICE_PROPERTY_ID, id);
|
||||
}
|
||||
|
||||
if (smartHomeDevice instanceof SmartHomeGroup) {
|
||||
} else if (smartHomeDevice instanceof SmartHomeGroup) {
|
||||
SmartHomeGroup shg = (SmartHomeGroup) smartHomeDevice;
|
||||
logger.trace("Found SmartHome device: {}", shg);
|
||||
|
||||
String id = shg.findId();
|
||||
if (id == null) {
|
||||
// No id
|
||||
|
|
|
@ -104,7 +104,6 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
private final Object synchronizeConnection = new Object();
|
||||
private Map<String, Device> jsonSerialNumberDeviceMapping = new HashMap<>();
|
||||
private Map<String, SmartHomeBaseDevice> jsonIdSmartHomeDeviceMapping = new HashMap<>();
|
||||
private Map<String, SmartHomeDevice> jsonSerialNumberSmartHomeDeviceMapping = new HashMap<>();
|
||||
|
||||
private @Nullable ScheduledFuture<?> checkDataJob;
|
||||
private @Nullable ScheduledFuture<?> checkLoginJob;
|
||||
|
@ -193,7 +192,7 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
if (command instanceof RefreshType) {
|
||||
refreshData();
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
logger.info("handleCommand fails", e);
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +478,7 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
ZonedDateTime timeStamp = ZonedDateTime.now();
|
||||
try {
|
||||
notifications = currentConnection.notifications();
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
logger.debug("refreshNotifications failed", e);
|
||||
return;
|
||||
}
|
||||
|
@ -632,7 +631,7 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
if (currentConnection.getIsLoggedIn()) {
|
||||
devices = currentConnection.getDeviceList();
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getLocalizedMessage());
|
||||
}
|
||||
if (devices != null) {
|
||||
|
@ -655,7 +654,7 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
String deviceWakeWord = null;
|
||||
for (WakeWord wakeWord : wakeWords) {
|
||||
if (wakeWord != null) {
|
||||
if (serialNumber != null && serialNumber.equals(wakeWord.deviceSerialNumber)) {
|
||||
if (serialNumber.equals(wakeWord.deviceSerialNumber)) {
|
||||
deviceWakeWord = wakeWord.wakeWord;
|
||||
break;
|
||||
}
|
||||
|
@ -676,7 +675,7 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
if (currentConnection != null && feeds != null) {
|
||||
try {
|
||||
currentConnection.setEnabledFlashBriefings(feeds);
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
logger.warn("Set flashbriefing profile failed", e);
|
||||
}
|
||||
}
|
||||
|
@ -736,7 +735,8 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
forSerializer[i] = copy;
|
||||
}
|
||||
this.currentFlashBriefingJson = gson.toJson(forSerializer);
|
||||
} catch (HttpException | JsonSyntaxException | IOException | URISyntaxException | ConnectionException e) {
|
||||
} catch (HttpException | JsonSyntaxException | IOException | URISyntaxException | ConnectionException
|
||||
| InterruptedException e) {
|
||||
logger.warn("get flash briefing profiles fails", e);
|
||||
}
|
||||
}
|
||||
|
@ -780,8 +780,8 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
default:
|
||||
String payload = pushCommand.payload;
|
||||
if (payload != null && payload.startsWith("{") && payload.endsWith("}")) {
|
||||
JsonCommandPayloadPushDevice devicePayload = gson.fromJson(payload,
|
||||
JsonCommandPayloadPushDevice.class);
|
||||
JsonCommandPayloadPushDevice devicePayload = Objects
|
||||
.requireNonNull(gson.fromJson(payload, JsonCommandPayloadPushDevice.class));
|
||||
DopplerId dopplerId = devicePayload.dopplerId;
|
||||
if (dopplerId != null) {
|
||||
handlePushDeviceCommand(dopplerId, command, payload);
|
||||
|
@ -800,7 +800,11 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
}
|
||||
|
||||
private void handlePushActivity(@Nullable String payload) {
|
||||
JsonCommandPayloadPushActivity pushActivity = gson.fromJson(payload, JsonCommandPayloadPushActivity.class);
|
||||
if (payload == null) {
|
||||
return;
|
||||
}
|
||||
JsonCommandPayloadPushActivity pushActivity = Objects
|
||||
.requireNonNull(gson.fromJson(payload, JsonCommandPayloadPushActivity.class));
|
||||
|
||||
Key key = pushActivity.key;
|
||||
if (key == null) {
|
||||
|
@ -820,8 +824,8 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
if (sourceDeviceIds != null) {
|
||||
Arrays.stream(sourceDeviceIds).filter(Objects::nonNull)
|
||||
.map(sourceDeviceId -> findEchoHandlerBySerialNumber(sourceDeviceId.serialNumber))
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(echoHandler -> echoHandler.handlePushActivity(currentActivity));
|
||||
.filter(Objects::nonNull).forEach(echoHandler -> Objects.requireNonNull(echoHandler)
|
||||
.handlePushActivity(currentActivity));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -857,7 +861,7 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
if (currentConnection.getIsLoggedIn()) {
|
||||
smartHomeDevices = currentConnection.getSmarthomeDeviceList();
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getLocalizedMessage());
|
||||
}
|
||||
if (smartHomeDevices != null) {
|
||||
|
@ -878,19 +882,6 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
smartHomeDeviceHandlers
|
||||
.forEach(child -> child.setDeviceAndUpdateThingState(this, findSmartDeviceHomeJson(child)));
|
||||
|
||||
if (smartHomeDevices != null) {
|
||||
Map<String, SmartHomeDevice> newJsonSerialNumberSmartHomeDeviceMapping = new HashMap<>();
|
||||
for (Object smartDevice : smartHomeDevices) {
|
||||
if (smartDevice instanceof SmartHomeDevice) {
|
||||
SmartHomeDevice shd = (SmartHomeDevice) smartDevice;
|
||||
String entityId = shd.entityId;
|
||||
if (entityId != null) {
|
||||
newJsonSerialNumberSmartHomeDeviceMapping.put(entityId, shd);
|
||||
}
|
||||
}
|
||||
}
|
||||
jsonSerialNumberSmartHomeDeviceMapping = newJsonSerialNumberSmartHomeDeviceMapping;
|
||||
}
|
||||
if (smartHomeDevices != null) {
|
||||
return smartHomeDevices;
|
||||
}
|
||||
|
@ -932,7 +923,7 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
|
||||
private synchronized void updateSmartHomeState(@Nullable String deviceFilterId) {
|
||||
try {
|
||||
logger.debug("updateSmartHomeState started");
|
||||
logger.debug("updateSmartHomeState started with deviceFilterId={}", deviceFilterId);
|
||||
Connection connection = this.connection;
|
||||
if (connection == null || !connection.getIsLoggedIn()) {
|
||||
return;
|
||||
|
@ -976,8 +967,10 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
|
|||
logger.debug("Device update {} suspended", id);
|
||||
continue;
|
||||
}
|
||||
if (id.equals(deviceFilterId)) {
|
||||
if (deviceFilterId == null || id.equals(deviceFilterId)) {
|
||||
smartHomeDeviceHandler.updateChannelStates(allDevices, applianceIdToCapabilityStates);
|
||||
} else {
|
||||
logger.trace("Id {} not matching filter {}", id, deviceFilterId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,17 +20,12 @@ import java.time.Instant;
|
|||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.amazonechocontrol.internal.Connection;
|
||||
|
@ -96,7 +91,6 @@ import com.google.gson.Gson;
|
|||
*/
|
||||
@NonNullByDefault
|
||||
public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(EchoHandler.class);
|
||||
private Gson gson;
|
||||
private @Nullable Device device;
|
||||
|
@ -376,7 +370,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
}
|
||||
}
|
||||
if (volume != null) {
|
||||
if (StringUtils.equals(device.deviceFamily, "WHA")) {
|
||||
if ("WHA".equals(device.deviceFamily)) {
|
||||
connection.command(device, "{\"type\":\"VolumeLevelCommand\",\"volumeLevel\":" + volume
|
||||
+ ",\"contentFocusClientId\":\"Default\"}");
|
||||
} else {
|
||||
|
@ -409,8 +403,8 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
if (channelId.equals(CHANNEL_MUSIC_PROVIDER_ID)) {
|
||||
if (command instanceof StringType) {
|
||||
waitForUpdate = 0;
|
||||
String musicProviderId = ((StringType) command).toFullString();
|
||||
if (!StringUtils.equals(musicProviderId, this.musicProviderId)) {
|
||||
String musicProviderId = command.toFullString();
|
||||
if (!musicProviderId.equals(this.musicProviderId)) {
|
||||
this.musicProviderId = musicProviderId;
|
||||
if (this.isPlaying) {
|
||||
connection.playMusicVoiceCommand(device, this.musicProviderId, "!");
|
||||
|
@ -421,7 +415,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
}
|
||||
if (channelId.equals(CHANNEL_PLAY_MUSIC_VOICE_COMMAND)) {
|
||||
if (command instanceof StringType) {
|
||||
String voiceCommand = ((StringType) command).toFullString();
|
||||
String voiceCommand = command.toFullString();
|
||||
if (!this.musicProviderId.isEmpty()) {
|
||||
connection.playMusicVoiceCommand(device, this.musicProviderId, voiceCommand);
|
||||
waitForUpdate = 3000;
|
||||
|
@ -447,21 +441,22 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
waitForUpdate = 4000;
|
||||
String bluetoothId = lastKnownBluetoothMAC;
|
||||
BluetoothState state = bluetoothState;
|
||||
if (state != null && (StringUtils.isEmpty(bluetoothId))) {
|
||||
if (state != null && (bluetoothId == null || bluetoothId.isEmpty())) {
|
||||
PairedDevice[] pairedDeviceList = state.pairedDeviceList;
|
||||
if (pairedDeviceList != null) {
|
||||
for (PairedDevice paired : pairedDeviceList) {
|
||||
if (paired == null) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.isNotEmpty(paired.address)) {
|
||||
lastKnownBluetoothMAC = paired.address;
|
||||
String pairedAddress = paired.address;
|
||||
if (pairedAddress != null && !pairedAddress.isEmpty()) {
|
||||
lastKnownBluetoothMAC = pairedAddress;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotEmpty(lastKnownBluetoothMAC)) {
|
||||
if (lastKnownBluetoothMAC != null && !lastKnownBluetoothMAC.isEmpty()) {
|
||||
connection.bluetooth(device, lastKnownBluetoothMAC);
|
||||
}
|
||||
} else if (command == OnOffType.OFF) {
|
||||
|
@ -474,8 +469,8 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
// amazon music commands
|
||||
if (channelId.equals(CHANNEL_AMAZON_MUSIC_TRACK_ID)) {
|
||||
if (command instanceof StringType) {
|
||||
String trackId = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(trackId)) {
|
||||
String trackId = command.toFullString();
|
||||
if (!trackId.isEmpty()) {
|
||||
waitForUpdate = 3000;
|
||||
}
|
||||
connection.playAmazonMusicTrack(device, trackId);
|
||||
|
@ -483,8 +478,8 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
}
|
||||
if (channelId.equals(CHANNEL_AMAZON_MUSIC_PLAY_LIST_ID)) {
|
||||
if (command instanceof StringType) {
|
||||
String playListId = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(playListId)) {
|
||||
String playListId = command.toFullString();
|
||||
if (!playListId.isEmpty()) {
|
||||
waitForUpdate = 3000;
|
||||
}
|
||||
connection.playAmazonMusicPlayList(device, playListId);
|
||||
|
@ -493,7 +488,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
if (channelId.equals(CHANNEL_AMAZON_MUSIC)) {
|
||||
if (command == OnOffType.ON) {
|
||||
String lastKnownAmazonMusicId = this.lastKnownAmazonMusicId;
|
||||
if (StringUtils.isNotEmpty(lastKnownAmazonMusicId)) {
|
||||
if (lastKnownAmazonMusicId != null && !lastKnownAmazonMusicId.isEmpty()) {
|
||||
waitForUpdate = 3000;
|
||||
}
|
||||
connection.playAmazonMusicTrack(device, lastKnownAmazonMusicId);
|
||||
|
@ -505,8 +500,8 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
// radio commands
|
||||
if (channelId.equals(CHANNEL_RADIO_STATION_ID)) {
|
||||
if (command instanceof StringType) {
|
||||
String stationId = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(stationId)) {
|
||||
String stationId = command.toFullString();
|
||||
if (!stationId.isEmpty()) {
|
||||
waitForUpdate = 3000;
|
||||
}
|
||||
connection.playRadio(device, stationId);
|
||||
|
@ -515,7 +510,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
if (channelId.equals(CHANNEL_RADIO)) {
|
||||
if (command == OnOffType.ON) {
|
||||
String lastKnownRadioStationId = this.lastKnownRadioStationId;
|
||||
if (StringUtils.isNotEmpty(lastKnownRadioStationId)) {
|
||||
if (lastKnownRadioStationId != null && !lastKnownRadioStationId.isEmpty()) {
|
||||
waitForUpdate = 3000;
|
||||
}
|
||||
connection.playRadio(device, lastKnownRadioStationId);
|
||||
|
@ -528,8 +523,8 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
if (channelId.equals(CHANNEL_REMIND)) {
|
||||
if (command instanceof StringType) {
|
||||
stopCurrentNotification();
|
||||
String reminder = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(reminder)) {
|
||||
String reminder = command.toFullString();
|
||||
if (!reminder.isEmpty()) {
|
||||
waitForUpdate = 3000;
|
||||
updateRemind = true;
|
||||
currentNotification = connection.notification(device, "Reminder", reminder, null);
|
||||
|
@ -542,8 +537,8 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
if (channelId.equals(CHANNEL_PLAY_ALARM_SOUND)) {
|
||||
if (command instanceof StringType) {
|
||||
stopCurrentNotification();
|
||||
String alarmSound = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(alarmSound)) {
|
||||
String alarmSound = command.toFullString();
|
||||
if (!alarmSound.isEmpty()) {
|
||||
waitForUpdate = 3000;
|
||||
updateAlarm = true;
|
||||
String[] parts = alarmSound.split(":", 2);
|
||||
|
@ -566,8 +561,8 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
// routine commands
|
||||
if (channelId.equals(CHANNEL_TEXT_TO_SPEECH)) {
|
||||
if (command instanceof StringType) {
|
||||
String text = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(text)) {
|
||||
String text = command.toFullString();
|
||||
if (!text.isEmpty()) {
|
||||
waitForUpdate = 1000;
|
||||
updateTextToSpeech = true;
|
||||
startTextToSpeech(connection, device, text);
|
||||
|
@ -595,8 +590,8 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
}
|
||||
if (channelId.equals(CHANNEL_LAST_VOICE_COMMAND)) {
|
||||
if (command instanceof StringType) {
|
||||
String text = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(text)) {
|
||||
String text = command.toFullString();
|
||||
if (!text.isEmpty()) {
|
||||
waitForUpdate = -1;
|
||||
startTextToSpeech(connection, device, text);
|
||||
}
|
||||
|
@ -604,18 +599,18 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
}
|
||||
if (channelId.equals(CHANNEL_START_COMMAND)) {
|
||||
if (command instanceof StringType) {
|
||||
String commandText = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(commandText)) {
|
||||
String commandText = command.toFullString();
|
||||
if (!commandText.isEmpty()) {
|
||||
updateStartCommand = true;
|
||||
if (commandText.startsWith(FLASH_BRIEFING_COMMAND_PREFIX)) {
|
||||
// Handle custom flashbriefings commands
|
||||
String flashbriefing = commandText.substring(FLASH_BRIEFING_COMMAND_PREFIX.length());
|
||||
|
||||
for (FlashBriefingProfileHandler flashBriefing : account
|
||||
String flashBriefingId = commandText.substring(FLASH_BRIEFING_COMMAND_PREFIX.length());
|
||||
for (FlashBriefingProfileHandler flashBriefingHandler : account
|
||||
.getFlashBriefingProfileHandlers()) {
|
||||
ThingUID flashBriefingId = flashBriefing.getThing().getUID();
|
||||
if (StringUtils.equals(flashBriefing.getThing().getUID().getId(), flashbriefing)) {
|
||||
flashBriefing.handleCommand(new ChannelUID(flashBriefingId, CHANNEL_PLAY_ON_DEVICE),
|
||||
ThingUID flashBriefingUid = flashBriefingHandler.getThing().getUID();
|
||||
if (flashBriefingId.equals(flashBriefingHandler.getThing().getUID().getId())) {
|
||||
flashBriefingHandler.handleCommand(
|
||||
new ChannelUID(flashBriefingUid, CHANNEL_PLAY_ON_DEVICE),
|
||||
new StringType(device.serialNumber));
|
||||
break;
|
||||
}
|
||||
|
@ -626,15 +621,15 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
commandText = "Alexa." + commandText + ".Play";
|
||||
}
|
||||
waitForUpdate = 1000;
|
||||
connection.executeSequenceCommand(device, commandText, null);
|
||||
connection.executeSequenceCommand(device, commandText, Map.of());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (channelId.equals(CHANNEL_START_ROUTINE)) {
|
||||
if (command instanceof StringType) {
|
||||
String utterance = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(utterance)) {
|
||||
String utterance = command.toFullString();
|
||||
if (!utterance.isEmpty()) {
|
||||
waitForUpdate = 1000;
|
||||
updateRoutine = true;
|
||||
connection.startRoutine(device, utterance);
|
||||
|
@ -669,7 +664,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
} else {
|
||||
this.updateStateJob = scheduler.schedule(doRefresh, waitForUpdate, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
logger.info("handleCommand fails", e);
|
||||
}
|
||||
}
|
||||
|
@ -699,7 +694,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
try {
|
||||
connection.setEqualizer(device, newEqualizerSetting);
|
||||
return true;
|
||||
} catch (HttpException | IOException | ConnectionException e) {
|
||||
} catch (HttpException | IOException | ConnectionException | InterruptedException e) {
|
||||
logger.debug("Update equalizer failed", e);
|
||||
this.lastKnownEqualizer = null;
|
||||
}
|
||||
|
@ -746,7 +741,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
if (currentConnection != null) {
|
||||
try {
|
||||
currentConnection.stopNotification(currentNotification);
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
logger.warn("Stop notification failed", e);
|
||||
}
|
||||
}
|
||||
|
@ -766,7 +761,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
logger.warn("update notification state fails", e);
|
||||
}
|
||||
if (stopCurrentNotification) {
|
||||
|
@ -855,20 +850,19 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
if (musicProviderId != null) {
|
||||
musicProviderId = musicProviderId.toUpperCase();
|
||||
|
||||
if (StringUtils.equals(musicProviderId, "AMAZON MUSIC")) {
|
||||
if (musicProviderId.equals("AMAZON MUSIC")) {
|
||||
musicProviderId = "AMAZON_MUSIC";
|
||||
}
|
||||
if (StringUtils.equals(musicProviderId, "CLOUD_PLAYER")) {
|
||||
if (musicProviderId.equals("CLOUD_PLAYER")) {
|
||||
musicProviderId = "AMAZON_MUSIC";
|
||||
}
|
||||
if (StringUtils.startsWith(musicProviderId, "TUNEIN")) {
|
||||
if (musicProviderId.startsWith("TUNEIN")) {
|
||||
musicProviderId = "TUNEIN";
|
||||
}
|
||||
if (StringUtils.startsWithIgnoreCase(musicProviderId, "iHeartRadio")) {
|
||||
if (musicProviderId.startsWith("IHEARTRADIO")) {
|
||||
musicProviderId = "I_HEART_RADIO";
|
||||
}
|
||||
if (StringUtils.containsIgnoreCase(musicProviderId, "Apple")
|
||||
&& StringUtils.containsIgnoreCase(musicProviderId, "Music")) {
|
||||
if (musicProviderId.equals("APPLE") && musicProviderId.contains("MUSIC")) {
|
||||
musicProviderId = "APPLE_MUSIC";
|
||||
}
|
||||
}
|
||||
|
@ -880,13 +874,13 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
if (e.getCode() != 400) {
|
||||
logger.info("getPlayer fails", e);
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
logger.info("getPlayer fails", e);
|
||||
}
|
||||
// check playing
|
||||
isPlaying = (playerInfo != null && StringUtils.equals(playerInfo.state, "PLAYING"));
|
||||
isPlaying = (playerInfo != null && "PLAYING".equals(playerInfo.state));
|
||||
|
||||
isPaused = (playerInfo != null && StringUtils.equals(playerInfo.state, "PAUSED"));
|
||||
isPaused = (playerInfo != null && "PAUSED".equals(playerInfo.state));
|
||||
synchronized (progressLock) {
|
||||
Boolean showTime = null;
|
||||
Long mediaLength = null;
|
||||
|
@ -919,8 +913,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
|
||||
JsonMediaState mediaState = null;
|
||||
try {
|
||||
if (StringUtils.equalsIgnoreCase(musicProviderId, "AMAZON_MUSIC")
|
||||
|| StringUtils.equalsIgnoreCase(musicProviderId, "TUNEIN")) {
|
||||
if ("AMAZON_MUSIC".equalsIgnoreCase(musicProviderId) || "TUNEIN".equalsIgnoreCase(musicProviderId)) {
|
||||
mediaState = connection.getMediaState(device);
|
||||
}
|
||||
} catch (HttpException e) {
|
||||
|
@ -929,7 +922,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
} else {
|
||||
logger.info("getMediaState fails", e);
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
logger.info("getMediaState fails", e);
|
||||
}
|
||||
|
||||
|
@ -944,11 +937,14 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
String amazonMusicTrackId = "";
|
||||
String amazonMusicPlayListId = "";
|
||||
boolean amazonMusic = false;
|
||||
if (mediaState != null && isPlaying && StringUtils.equals(mediaState.providerId, "CLOUD_PLAYER")
|
||||
&& StringUtils.isNotEmpty(mediaState.contentId)) {
|
||||
amazonMusicTrackId = mediaState.contentId;
|
||||
lastKnownAmazonMusicId = amazonMusicTrackId;
|
||||
amazonMusic = true;
|
||||
if (mediaState != null) {
|
||||
String contentId = mediaState.contentId;
|
||||
if (isPlaying && "CLOUD_PLAYER".equals(mediaState.providerId) && contentId != null
|
||||
&& !contentId.isEmpty()) {
|
||||
amazonMusicTrackId = contentId;
|
||||
lastKnownAmazonMusicId = amazonMusicTrackId;
|
||||
amazonMusic = true;
|
||||
}
|
||||
}
|
||||
|
||||
// handle bluetooth
|
||||
|
@ -963,34 +959,37 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
if (paired == null) {
|
||||
continue;
|
||||
}
|
||||
if (paired.connected && paired.address != null) {
|
||||
String pairedAddress = paired.address;
|
||||
if (paired.connected && pairedAddress != null) {
|
||||
bluetoothIsConnected = true;
|
||||
bluetoothMAC = paired.address;
|
||||
bluetoothMAC = pairedAddress;
|
||||
bluetoothDeviceName = paired.friendlyName;
|
||||
if (StringUtils.isEmpty(bluetoothDeviceName)) {
|
||||
bluetoothDeviceName = paired.address;
|
||||
if (bluetoothDeviceName == null || bluetoothDeviceName.isEmpty()) {
|
||||
bluetoothDeviceName = pairedAddress;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotEmpty(bluetoothMAC)) {
|
||||
if (!bluetoothMAC.isEmpty()) {
|
||||
lastKnownBluetoothMAC = bluetoothMAC;
|
||||
}
|
||||
|
||||
// handle radio
|
||||
boolean isRadio = false;
|
||||
if (mediaState != null && StringUtils.isNotEmpty(mediaState.radioStationId)) {
|
||||
lastKnownRadioStationId = mediaState.radioStationId;
|
||||
if (StringUtils.equalsIgnoreCase(musicProviderId, "TUNEIN")) {
|
||||
isRadio = true;
|
||||
}
|
||||
}
|
||||
String radioStationId = "";
|
||||
if (isRadio && mediaState != null && StringUtils.equals(mediaState.currentState, "PLAYING")
|
||||
&& mediaState.radioStationId != null) {
|
||||
radioStationId = mediaState.radioStationId;
|
||||
if (mediaState != null) {
|
||||
radioStationId = Objects.requireNonNullElse(mediaState.radioStationId, "");
|
||||
if (!radioStationId.isEmpty()) {
|
||||
lastKnownRadioStationId = radioStationId;
|
||||
if ("TUNEIN".equalsIgnoreCase(musicProviderId)) {
|
||||
isRadio = true;
|
||||
if (!"PLAYING".equals(mediaState.currentState)) {
|
||||
radioStationId = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle title, subtitle, imageUrl
|
||||
|
@ -1021,13 +1020,13 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
QueueEntry entry = queueEntries[0];
|
||||
if (entry != null) {
|
||||
if (isRadio) {
|
||||
if (StringUtils.isEmpty(imageUrl) && entry.imageURL != null) {
|
||||
if ((imageUrl == null || imageUrl.isEmpty()) && entry.imageURL != null) {
|
||||
imageUrl = entry.imageURL;
|
||||
}
|
||||
if (StringUtils.isEmpty(subTitle1) && entry.radioStationSlogan != null) {
|
||||
if ((subTitle1 == null || subTitle1.isEmpty()) && entry.radioStationSlogan != null) {
|
||||
subTitle1 = entry.radioStationSlogan;
|
||||
}
|
||||
if (StringUtils.isEmpty(subTitle2) && entry.radioStationLocation != null) {
|
||||
if ((subTitle2 == null || subTitle2.isEmpty()) && entry.radioStationLocation != null) {
|
||||
subTitle2 = entry.radioStationLocation;
|
||||
}
|
||||
}
|
||||
|
@ -1039,9 +1038,10 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
String providerDisplayName = "";
|
||||
if (provider != null) {
|
||||
if (provider.providerDisplayName != null) {
|
||||
providerDisplayName = provider.providerDisplayName;
|
||||
providerDisplayName = Objects.requireNonNullElse(provider.providerDisplayName, providerDisplayName);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(provider.providerName) && StringUtils.isEmpty(providerDisplayName)) {
|
||||
String providerName = provider.providerName;
|
||||
if (providerName != null && !providerName.isEmpty() && providerDisplayName.isEmpty()) {
|
||||
providerDisplayName = provider.providerName;
|
||||
}
|
||||
}
|
||||
|
@ -1153,7 +1153,7 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
treble = equalizer.treble;
|
||||
}
|
||||
this.lastKnownEqualizer = equalizer;
|
||||
} catch (IOException | URISyntaxException | HttpException | ConnectionException e) {
|
||||
} catch (IOException | URISyntaxException | HttpException | ConnectionException | InterruptedException e) {
|
||||
logger.debug("Get equalizer failes", e);
|
||||
return;
|
||||
}
|
||||
|
@ -1204,20 +1204,22 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
return;
|
||||
}
|
||||
Description description = pushActivity.parseDescription();
|
||||
if (StringUtils.isEmpty(description.firstUtteranceId)
|
||||
|| StringUtils.startsWithIgnoreCase(description.firstUtteranceId, "TextClient:")) {
|
||||
String firstUtteranceId = description.firstUtteranceId;
|
||||
if (firstUtteranceId == null || firstUtteranceId.isEmpty()
|
||||
|| firstUtteranceId.toLowerCase().startsWith("textclient:")) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isEmpty(description.firstStreamId)) {
|
||||
String firstStreamId = description.firstStreamId;
|
||||
if (firstStreamId == null || firstStreamId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String spokenText = description.summary;
|
||||
if (spokenText != null && StringUtils.isNotEmpty(spokenText)) {
|
||||
if (spokenText != null && !spokenText.isEmpty()) {
|
||||
// remove wake word
|
||||
String wakeWordPrefix = this.wakeWord;
|
||||
if (wakeWordPrefix != null) {
|
||||
wakeWordPrefix += " ";
|
||||
if (StringUtils.startsWithIgnoreCase(spokenText, wakeWordPrefix)) {
|
||||
if (spokenText.toLowerCase().startsWith(wakeWordPrefix.toLowerCase())) {
|
||||
spokenText = spokenText.substring(wakeWordPrefix.length());
|
||||
}
|
||||
}
|
||||
|
@ -1234,12 +1236,10 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
this.logger.debug("Handle push command {}", command);
|
||||
switch (command) {
|
||||
case "PUSH_VOLUME_CHANGE":
|
||||
JsonCommandPayloadPushVolumeChange volumeChange = gson.fromJson(payload,
|
||||
JsonCommandPayloadPushVolumeChange.class);
|
||||
JsonCommandPayloadPushVolumeChange volumeChange = Objects
|
||||
.requireNonNull(gson.fromJson(payload, JsonCommandPayloadPushVolumeChange.class));
|
||||
Connection connection = this.findConnection();
|
||||
@Nullable
|
||||
Integer volumeSetting = volumeChange.volumeSetting;
|
||||
@Nullable
|
||||
Boolean muted = volumeChange.isMuted;
|
||||
if (muted != null && muted) {
|
||||
updateState(CHANNEL_VOLUME, new PercentType(0));
|
||||
|
@ -1274,14 +1274,15 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
ZonedDateTime nextMusicAlarm = null;
|
||||
ZonedDateTime nextTimer = null;
|
||||
for (JsonNotificationResponse notification : notifications) {
|
||||
if (StringUtils.equals(notification.deviceSerialNumber, device.serialNumber)) {
|
||||
if (Objects.equals(notification.deviceSerialNumber, device.serialNumber)) {
|
||||
// notification for this device
|
||||
if (StringUtils.equals(notification.status, "ON")) {
|
||||
if ("ON".equals(notification.status)) {
|
||||
if ("Reminder".equals(notification.type)) {
|
||||
String offset = ZoneId.systemDefault().getRules().getOffset(Instant.now()).toString();
|
||||
ZonedDateTime alarmTime = ZonedDateTime
|
||||
.parse(notification.originalDate + "T" + notification.originalTime + offset);
|
||||
if (StringUtils.isNotBlank(notification.recurringPattern) && alarmTime.isBefore(now)) {
|
||||
String recurringPattern = notification.recurringPattern;
|
||||
if (recurringPattern != null && !recurringPattern.isBlank() && alarmTime.isBefore(now)) {
|
||||
continue; // Ignore recurring entry if alarm time is before now
|
||||
}
|
||||
if (nextReminder == null || alarmTime.isBefore(nextReminder)) {
|
||||
|
@ -1297,7 +1298,8 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
String offset = ZoneId.systemDefault().getRules().getOffset(Instant.now()).toString();
|
||||
ZonedDateTime alarmTime = ZonedDateTime
|
||||
.parse(notification.originalDate + "T" + notification.originalTime + offset);
|
||||
if (StringUtils.isNotBlank(notification.recurringPattern) && alarmTime.isBefore(now)) {
|
||||
String recurringPattern = notification.recurringPattern;
|
||||
if (recurringPattern != null && !recurringPattern.isBlank() && alarmTime.isBefore(now)) {
|
||||
continue; // Ignore recurring entry if alarm time is before now
|
||||
}
|
||||
if (nextAlarm == null || alarmTime.isBefore(nextAlarm)) {
|
||||
|
@ -1307,7 +1309,8 @@ public class EchoHandler extends BaseThingHandler implements IEchoThingHandler {
|
|||
String offset = ZoneId.systemDefault().getRules().getOffset(Instant.now()).toString();
|
||||
ZonedDateTime alarmTime = ZonedDateTime
|
||||
.parse(notification.originalDate + "T" + notification.originalTime + offset);
|
||||
if (StringUtils.isNotBlank(notification.recurringPattern) && alarmTime.isBefore(now)) {
|
||||
String recurringPattern = notification.recurringPattern;
|
||||
if (recurringPattern != null && !recurringPattern.isBlank() && alarmTime.isBefore(now)) {
|
||||
continue; // Ignore recurring entry if alarm time is before now
|
||||
}
|
||||
if (nextMusicAlarm == null || alarmTime.isBefore(nextMusicAlarm)) {
|
||||
|
|
|
@ -14,12 +14,10 @@ package org.openhab.binding.amazonechocontrol.internal.handler;
|
|||
|
||||
import static org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.amazonechocontrol.internal.Connection;
|
||||
|
@ -104,59 +102,54 @@ public class FlashBriefingProfileHandler extends BaseThingHandler {
|
|||
if (updateStateJob != null) {
|
||||
updateStateJob.cancel(false);
|
||||
}
|
||||
try {
|
||||
String channelId = channelUID.getId();
|
||||
if (command instanceof RefreshType) {
|
||||
waitForUpdate = 0;
|
||||
String channelId = channelUID.getId();
|
||||
if (command instanceof RefreshType) {
|
||||
waitForUpdate = 0;
|
||||
}
|
||||
if (channelId.equals(CHANNEL_SAVE)) {
|
||||
if (command.equals(OnOffType.ON)) {
|
||||
saveCurrentProfile(accountHandler);
|
||||
waitForUpdate = 500;
|
||||
}
|
||||
if (channelId.equals(CHANNEL_SAVE)) {
|
||||
if (command.equals(OnOffType.ON)) {
|
||||
saveCurrentProfile(accountHandler);
|
||||
}
|
||||
if (channelId.equals(CHANNEL_ACTIVE)) {
|
||||
if (command.equals(OnOffType.ON)) {
|
||||
String currentConfigurationJson = this.currentConfigurationJson;
|
||||
if (!currentConfigurationJson.isEmpty()) {
|
||||
accountHandler.setEnabledFlashBriefingsJson(currentConfigurationJson);
|
||||
updateState(CHANNEL_ACTIVE, OnOffType.ON);
|
||||
waitForUpdate = 500;
|
||||
}
|
||||
}
|
||||
if (channelId.equals(CHANNEL_ACTIVE)) {
|
||||
if (command.equals(OnOffType.ON)) {
|
||||
String currentConfigurationJson = this.currentConfigurationJson;
|
||||
if (!currentConfigurationJson.isEmpty()) {
|
||||
accountHandler.setEnabledFlashBriefingsJson(currentConfigurationJson);
|
||||
updateState(CHANNEL_ACTIVE, OnOffType.ON);
|
||||
waitForUpdate = 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (channelId.equals(CHANNEL_PLAY_ON_DEVICE)) {
|
||||
if (command instanceof StringType) {
|
||||
String deviceSerialOrName = ((StringType) command).toFullString();
|
||||
String currentConfigurationJson = this.currentConfigurationJson;
|
||||
if (!currentConfigurationJson.isEmpty()) {
|
||||
String old = accountHandler.getEnabledFlashBriefingsJson();
|
||||
accountHandler.setEnabledFlashBriefingsJson(currentConfigurationJson);
|
||||
Device device = accountHandler.findDeviceJsonBySerialOrName(deviceSerialOrName);
|
||||
if (device == null) {
|
||||
logger.warn("Device '{}' not found", deviceSerialOrName);
|
||||
}
|
||||
if (channelId.equals(CHANNEL_PLAY_ON_DEVICE)) {
|
||||
if (command instanceof StringType) {
|
||||
String deviceSerialOrName = command.toFullString();
|
||||
String currentConfigurationJson = this.currentConfigurationJson;
|
||||
if (!currentConfigurationJson.isEmpty()) {
|
||||
String old = accountHandler.getEnabledFlashBriefingsJson();
|
||||
accountHandler.setEnabledFlashBriefingsJson(currentConfigurationJson);
|
||||
Device device = accountHandler.findDeviceJsonBySerialOrName(deviceSerialOrName);
|
||||
if (device == null) {
|
||||
logger.warn("Device '{}' not found", deviceSerialOrName);
|
||||
} else {
|
||||
@Nullable
|
||||
Connection connection = accountHandler.findConnection();
|
||||
if (connection == null) {
|
||||
logger.warn("Connection for '{}' not found", accountHandler.getThing().getUID().getId());
|
||||
} else {
|
||||
@Nullable
|
||||
Connection connection = accountHandler.findConnection();
|
||||
if (connection == null) {
|
||||
logger.warn("Connection for '{}' not found",
|
||||
accountHandler.getThing().getUID().getId());
|
||||
} else {
|
||||
connection.executeSequenceCommand(device, "Alexa.FlashBriefing.Play", null);
|
||||
connection.executeSequenceCommand(device, "Alexa.FlashBriefing.Play", Map.of());
|
||||
|
||||
scheduler.schedule(() -> accountHandler.setEnabledFlashBriefingsJson(old), 1000,
|
||||
TimeUnit.MILLISECONDS);
|
||||
scheduler.schedule(() -> accountHandler.setEnabledFlashBriefingsJson(old), 1000,
|
||||
TimeUnit.MILLISECONDS);
|
||||
|
||||
updateState(CHANNEL_ACTIVE, OnOffType.ON);
|
||||
}
|
||||
updateState(CHANNEL_ACTIVE, OnOffType.ON);
|
||||
}
|
||||
updatePlayOnDevice = true;
|
||||
waitForUpdate = 1000;
|
||||
}
|
||||
updatePlayOnDevice = true;
|
||||
waitForUpdate = 1000;
|
||||
}
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
logger.warn("Handle command failed", e);
|
||||
}
|
||||
if (waitForUpdate >= 0) {
|
||||
this.updateStateJob = scheduler.schedule(() -> accountHandler.updateFlashBriefingHandlers(), waitForUpdate,
|
||||
|
@ -189,7 +182,7 @@ public class FlashBriefingProfileHandler extends BaseThingHandler {
|
|||
} else {
|
||||
updateState(CHANNEL_ACTIVE, OnOffType.OFF);
|
||||
}
|
||||
return StringUtils.equals(this.currentConfigurationJson, currentConfigurationJson);
|
||||
return this.currentConfigurationJson.equals(currentConfigurationJson);
|
||||
}
|
||||
|
||||
private String saveCurrentProfile(AccountHandler connection) {
|
||||
|
|
|
@ -15,16 +15,7 @@ package org.openhab.binding.amazonechocontrol.internal.handler;
|
|||
import static org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.DEVICE_PROPERTY_ID;
|
||||
import static org.openhab.binding.amazonechocontrol.internal.smarthome.Constants.SUPPORTED_INTERFACES;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
@ -32,7 +23,10 @@ import org.eclipse.jdt.annotation.Nullable;
|
|||
import org.openhab.binding.amazonechocontrol.internal.Connection;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeCapabilities.SmartHomeCapability;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.SmartHomeDevice;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeGroupIdentifiers;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeGroupIdentity;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeGroups.SmartHomeGroup;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeTags;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.SmartHomeBaseDevice;
|
||||
import org.openhab.binding.amazonechocontrol.internal.smarthome.Constants;
|
||||
import org.openhab.binding.amazonechocontrol.internal.smarthome.HandlerBase;
|
||||
|
@ -56,10 +50,7 @@ import org.openhab.core.types.StateDescription;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.*;
|
||||
|
||||
/**
|
||||
* @author Lukas Knoeller - Initial contribution
|
||||
|
@ -176,6 +167,7 @@ public class SmartHomeDeviceHandler extends BaseThingHandler {
|
|||
|
||||
public void updateChannelStates(List<SmartHomeBaseDevice> allDevices,
|
||||
Map<String, JsonArray> applianceIdToCapabilityStates) {
|
||||
logger.trace("Updating {} with {}", allDevices, applianceIdToCapabilityStates);
|
||||
AccountHandler accountHandler = getAccountHandler();
|
||||
SmartHomeBaseDevice smartHomeBaseDevice = this.smartHomeBaseDevice;
|
||||
if (smartHomeBaseDevice == null) {
|
||||
|
@ -187,11 +179,11 @@ public class SmartHomeDeviceHandler extends BaseThingHandler {
|
|||
Map<String, List<JsonObject>> mapInterfaceToStates = new HashMap<>();
|
||||
SmartHomeDevice firstDevice = null;
|
||||
for (SmartHomeDevice shd : getSupportedSmartHomeDevices(smartHomeBaseDevice, allDevices)) {
|
||||
JsonArray states = applianceIdToCapabilityStates.get(shd.applianceId);
|
||||
String applianceId = shd.applianceId;
|
||||
if (applianceId == null) {
|
||||
continue;
|
||||
}
|
||||
JsonArray states = applianceIdToCapabilityStates.get(applianceId);
|
||||
if (states != null) {
|
||||
stateFound = true;
|
||||
if (smartHomeBaseDevice.isGroup()) {
|
||||
|
@ -210,26 +202,28 @@ public class SmartHomeDeviceHandler extends BaseThingHandler {
|
|||
for (JsonElement stateElement : states) {
|
||||
String stateJson = stateElement.getAsString();
|
||||
if (stateJson.startsWith("{") && stateJson.endsWith("}")) {
|
||||
JsonObject state = gson.fromJson(stateJson, JsonObject.class);
|
||||
String interfaceName = state.get("namespace").getAsString();
|
||||
mapInterfaceToStates.computeIfAbsent(interfaceName, k -> new ArrayList<>()).add(state);
|
||||
JsonObject state = Objects.requireNonNull(gson.fromJson(stateJson, JsonObject.class));
|
||||
String interfaceName = Objects.requireNonNullElse(state.get("namespace"), JsonNull.INSTANCE)
|
||||
.getAsString();
|
||||
Objects.requireNonNull(mapInterfaceToStates.computeIfAbsent(interfaceName, k -> new ArrayList<>()))
|
||||
.add(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (HandlerBase handlerBase : handlers.values()) {
|
||||
if (handlerBase == null) {
|
||||
continue;
|
||||
}
|
||||
UpdateChannelResult result = new UpdateChannelResult();
|
||||
|
||||
for (HandlerBase handlerBase : handlers.values()) {
|
||||
UpdateChannelResult result = new UpdateChannelResult();
|
||||
for (String interfaceName : handlerBase.getSupportedInterface()) {
|
||||
List<JsonObject> stateList = mapInterfaceToStates.getOrDefault(interfaceName, Collections.emptyList());
|
||||
try {
|
||||
handlerBase.updateChannels(interfaceName, stateList, result);
|
||||
} catch (Exception e) {
|
||||
// We catch all exceptions, otherwise all other things are not updated!
|
||||
logger.debug("Updating states failed", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getLocalizedMessage());
|
||||
List<JsonObject> stateList = mapInterfaceToStates.get(interfaceName);
|
||||
if (stateList != null) {
|
||||
try {
|
||||
handlerBase.updateChannels(interfaceName, stateList, result);
|
||||
} catch (Exception e) {
|
||||
// We catch all exceptions, otherwise all other things are not updated!
|
||||
logger.debug("Updating states failed", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,7 +319,8 @@ public class SmartHomeDeviceHandler extends BaseThingHandler {
|
|||
for (SmartHomeCapability capability : capabilities) {
|
||||
String interfaceName = capability.interfaceName;
|
||||
if (interfaceName != null) {
|
||||
result.computeIfAbsent(interfaceName, name -> new ArrayList<>()).add(capability);
|
||||
Objects.requireNonNull(result.computeIfAbsent(interfaceName, name -> new ArrayList<>()))
|
||||
.add(capability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -357,16 +352,20 @@ public class SmartHomeDeviceHandler extends BaseThingHandler {
|
|||
for (SmartHomeBaseDevice device : allDevices) {
|
||||
if (device instanceof SmartHomeDevice) {
|
||||
SmartHomeDevice shd = (SmartHomeDevice) device;
|
||||
if (shd.tags != null && shd.tags.tagNameToValueSetMap != null
|
||||
&& shd.tags.tagNameToValueSetMap.groupIdentity != null
|
||||
&& shg.applianceGroupIdentifier != null && shg.applianceGroupIdentifier.value != null
|
||||
&& Arrays.asList(shd.tags.tagNameToValueSetMap.groupIdentity)
|
||||
.contains(shg.applianceGroupIdentifier.value)) {
|
||||
SmartHomeCapability[] capabilities = shd.capabilities;
|
||||
if (capabilities != null) {
|
||||
if (Arrays.stream(capabilities).map(capability -> capability.interfaceName)
|
||||
.anyMatch(SUPPORTED_INTERFACES::contains)) {
|
||||
result.add(shd);
|
||||
JsonSmartHomeTags.JsonSmartHomeTag tags = shd.tags;
|
||||
if (tags != null) {
|
||||
JsonSmartHomeGroupIdentity.SmartHomeGroupIdentity tagNameToValueSetMap = tags.tagNameToValueSetMap;
|
||||
JsonSmartHomeGroupIdentifiers.SmartHomeGroupIdentifier applianceGroupIdentifier = shg.applianceGroupIdentifier;
|
||||
if (tagNameToValueSetMap != null && tagNameToValueSetMap.groupIdentity != null
|
||||
&& applianceGroupIdentifier != null && applianceGroupIdentifier.value != null
|
||||
&& Arrays.asList(tagNameToValueSetMap.groupIdentity)
|
||||
.contains(applianceGroupIdentifier.value)) {
|
||||
SmartHomeCapability[] capabilities = shd.capabilities;
|
||||
if (capabilities != null) {
|
||||
if (Arrays.stream(capabilities).map(capability -> capability.interfaceName)
|
||||
.anyMatch(SUPPORTED_INTERFACES::contains)) {
|
||||
result.add(shd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +379,7 @@ public class SmartHomeDeviceHandler extends BaseThingHandler {
|
|||
@Nullable Locale locale) {
|
||||
String channelId = channel.getUID().getId();
|
||||
for (HandlerBase handler : handlers.values()) {
|
||||
if (handler != null && handler.hasChannel(channelId)) {
|
||||
if (handler.hasChannel(channelId)) {
|
||||
return handler.findStateDescription(channelId, originalStateDescription, locale);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
*/
|
||||
package org.openhab.binding.amazonechocontrol.internal.jsons;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonDevices.Device;
|
||||
|
@ -35,7 +36,7 @@ public class JsonBluetoothStates {
|
|||
return null;
|
||||
}
|
||||
for (BluetoothState state : bluetoothStates) {
|
||||
if (state != null && StringUtils.equals(state.deviceSerialNumber, device.serialNumber)) {
|
||||
if (state != null && Objects.equals(state.deviceSerialNumber, device.serialNumber)) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
*/
|
||||
package org.openhab.binding.amazonechocontrol.internal.jsons;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeCapabilities.SmartHomeCapability;
|
||||
|
@ -24,7 +26,6 @@ import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeTags.Js
|
|||
@NonNullByDefault
|
||||
public class JsonSmartHomeDevices {
|
||||
public static class SmartHomeDevice implements SmartHomeBaseDevice {
|
||||
|
||||
public @Nullable Integer updateIntervalInSeconds;
|
||||
|
||||
@Override
|
||||
|
@ -52,11 +53,29 @@ public class JsonSmartHomeDevices {
|
|||
public @Nullable SmartHomeDevice @Nullable [] groupDevices;
|
||||
public @Nullable String connectedVia;
|
||||
public @Nullable DriverIdentity driverIdentity;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SmartHomeDevice{" + "updateIntervalInSeconds=" + updateIntervalInSeconds + ", applianceId='"
|
||||
+ applianceId + '\'' + ", manufacturerName='" + manufacturerName + '\'' + ", friendlyDescription='"
|
||||
+ friendlyDescription + '\'' + ", modelName='" + modelName + '\'' + ", friendlyName='"
|
||||
+ friendlyName + '\'' + ", reachability='" + reachability + '\'' + ", entityId='" + entityId + '\''
|
||||
+ ", applianceNetworkState=" + applianceNetworkState + ", capabilities="
|
||||
+ Arrays.toString(capabilities) + ", tags=" + tags + ", applianceTypes="
|
||||
+ Arrays.toString(applianceTypes) + ", aliases=" + Arrays.toString(aliases) + ", groupDevices="
|
||||
+ Arrays.toString(groupDevices) + ", connectedVia='" + connectedVia + '\'' + ", driverIdentity="
|
||||
+ driverIdentity + '}';
|
||||
}
|
||||
}
|
||||
|
||||
public static class DriverIdentity {
|
||||
public @Nullable String namespace;
|
||||
public @Nullable String identifier;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DriverIdentity{" + "namespace='" + namespace + '\'' + ", identifier='" + identifier + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable SmartHomeDevice @Nullable [] smarthomeDevices;
|
||||
|
|
|
@ -46,6 +46,12 @@ public class JsonSmartHomeGroups {
|
|||
public @Nullable Boolean isSpace;
|
||||
public @Nullable Boolean space;
|
||||
public @Nullable SmartHomeGroupIdentifier applianceGroupIdentifier;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SmartHomeGroup{" + "applianceGroupName='" + applianceGroupName + '\'' + ", isSpace=" + isSpace
|
||||
+ ", space=" + space + ", applianceGroupIdentifier=" + applianceGroupIdentifier + '}';
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable SmartHomeGroup @Nullable [] groups;
|
||||
|
|
|
@ -47,7 +47,8 @@ public abstract class HandlerBase {
|
|||
public abstract void updateChannels(String interfaceName, List<JsonObject> stateList, UpdateChannelResult result);
|
||||
|
||||
public abstract boolean handleCommand(Connection connection, SmartHomeDevice shd, String entityId,
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command) throws IOException;
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command)
|
||||
throws IOException, InterruptedException;
|
||||
|
||||
public abstract @Nullable StateDescription findStateDescription(String channelId,
|
||||
StateDescription originalStateDescription, @Nullable Locale locale);
|
||||
|
|
|
@ -91,7 +91,8 @@ public class HandlerBrightnessController extends HandlerBase {
|
|||
|
||||
@Override
|
||||
public boolean handleCommand(Connection connection, SmartHomeDevice shd, String entityId,
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command) throws IOException {
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command)
|
||||
throws IOException, InterruptedException {
|
||||
if (channelId.equals(BRIGHTNESS.channelId)) {
|
||||
if (containsCapabilityProperty(capabilties, BRIGHTNESS.propertyName)) {
|
||||
if (command.equals(IncreaseDecreaseType.INCREASE)) {
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants;
|
||||
|
@ -113,11 +112,10 @@ public class HandlerColorController extends HandlerBase {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (lastColorName == null) {
|
||||
lastColorName = colorNameValue;
|
||||
} else if (colorNameValue == null && lastColorName != null) {
|
||||
if (colorNameValue == null && lastColorName != null) {
|
||||
colorNameValue = lastColorName;
|
||||
}
|
||||
lastColorName = colorNameValue;
|
||||
updateState(COLOR_PROPERTIES.channelId,
|
||||
lastColorName == null ? UnDefType.UNDEF : new StringType(lastColorName));
|
||||
}
|
||||
|
@ -125,7 +123,8 @@ public class HandlerColorController extends HandlerBase {
|
|||
|
||||
@Override
|
||||
public boolean handleCommand(Connection connection, SmartHomeDevice shd, String entityId,
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command) throws IOException {
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command)
|
||||
throws IOException, InterruptedException {
|
||||
if (channelId.equals(COLOR.channelId)) {
|
||||
if (containsCapabilityProperty(capabilties, COLOR.propertyName)) {
|
||||
if (command instanceof HSBType) {
|
||||
|
@ -134,15 +133,15 @@ public class HandlerColorController extends HandlerBase {
|
|||
colorObject.addProperty("hue", color.getHue());
|
||||
colorObject.addProperty("saturation", color.getSaturation().floatValue() / 100);
|
||||
colorObject.addProperty("brightness", color.getBrightness().floatValue() / 100);
|
||||
connection.smartHomeCommand(entityId, "setColor", "color", colorObject);
|
||||
connection.smartHomeCommand(entityId, "setColor", "value", colorObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (channelId.equals(COLOR_PROPERTIES.channelId)) {
|
||||
if (containsCapabilityProperty(capabilties, COLOR.propertyName)) {
|
||||
if (command instanceof StringType) {
|
||||
String colorName = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(colorName)) {
|
||||
String colorName = command.toFullString();
|
||||
if (!colorName.isEmpty()) {
|
||||
lastColorName = colorName;
|
||||
connection.smartHomeCommand(entityId, "setColor", "colorName", colorName);
|
||||
return true;
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants;
|
||||
|
@ -121,7 +120,8 @@ public class HandlerColorTemperatureController extends HandlerBase {
|
|||
|
||||
@Override
|
||||
public boolean handleCommand(Connection connection, SmartHomeDevice shd, String entityId,
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command) throws IOException {
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command)
|
||||
throws IOException, InterruptedException {
|
||||
if (channelId.equals(COLOR_TEMPERATURE_IN_KELVIN.channelId)) {
|
||||
// WRITING TO THIS CHANNEL DOES CURRENTLY NOT WORK, BUT WE LEAVE THE CODE FOR FUTURE USE!
|
||||
if (containsCapabilityProperty(capabilties, COLOR_TEMPERATURE_IN_KELVIN.propertyName)) {
|
||||
|
@ -141,8 +141,8 @@ public class HandlerColorTemperatureController extends HandlerBase {
|
|||
if (channelId.equals(COLOR_TEMPERATURE_NAME.channelId)) {
|
||||
if (containsCapabilityProperty(capabilties, COLOR_TEMPERATURE_IN_KELVIN.propertyName)) {
|
||||
if (command instanceof StringType) {
|
||||
String colorTemperatureName = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(colorTemperatureName)) {
|
||||
String colorTemperatureName = command.toFullString();
|
||||
if (!colorTemperatureName.isEmpty()) {
|
||||
lastColorName = colorTemperatureName;
|
||||
connection.smartHomeCommand(entityId, "setColorTemperature", "colorTemperatureName",
|
||||
colorTemperatureName);
|
||||
|
|
|
@ -91,7 +91,8 @@ public class HandlerPercentageController extends HandlerBase {
|
|||
|
||||
@Override
|
||||
public boolean handleCommand(Connection connection, SmartHomeDevice shd, String entityId,
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command) throws IOException {
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command)
|
||||
throws IOException, InterruptedException {
|
||||
if (channelId.equals(PERCENTAGE.channelId)) {
|
||||
if (containsCapabilityProperty(capabilties, PERCENTAGE.propertyName)) {
|
||||
if (command.equals(IncreaseDecreaseType.INCREASE)) {
|
||||
|
|
|
@ -29,6 +29,8 @@ import org.openhab.core.thing.type.ChannelTypeUID;
|
|||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.StateDescription;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
|
@ -40,6 +42,8 @@ import com.google.gson.JsonObject;
|
|||
*/
|
||||
@NonNullByDefault
|
||||
public class HandlerPowerController extends HandlerBase {
|
||||
private final Logger logger = LoggerFactory.getLogger(HandlerPowerController.class);
|
||||
|
||||
// Interface
|
||||
public static final String INTERFACE = "Alexa.PowerController";
|
||||
|
||||
|
@ -67,6 +71,7 @@ public class HandlerPowerController extends HandlerBase {
|
|||
|
||||
@Override
|
||||
public void updateChannels(String interfaceName, List<JsonObject> stateList, UpdateChannelResult result) {
|
||||
logger.trace("{} received {}", this.smartHomeDeviceHandler.getId(), stateList);
|
||||
Boolean powerStateValue = null;
|
||||
for (JsonObject state : stateList) {
|
||||
if (POWER_STATE.propertyName.equals(state.get("name").getAsString())) {
|
||||
|
@ -74,19 +79,20 @@ public class HandlerPowerController extends HandlerBase {
|
|||
// For groups take true if all true
|
||||
if ("ON".equals(value)) {
|
||||
powerStateValue = true;
|
||||
} else if (powerStateValue == null) {
|
||||
} else {
|
||||
powerStateValue = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
updateState(POWER_STATE.channelId,
|
||||
powerStateValue == null ? UnDefType.UNDEF : (powerStateValue ? OnOffType.ON : OnOffType.OFF));
|
||||
logger.trace("{} final state {}", this.smartHomeDeviceHandler.getId(), powerStateValue);
|
||||
updateState(POWER_STATE.channelId, powerStateValue == null ? UnDefType.UNDEF : OnOffType.from(powerStateValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleCommand(Connection connection, SmartHomeDevice shd, String entityId,
|
||||
SmartHomeCapability[] capabilities, String channelId, Command command) throws IOException {
|
||||
SmartHomeCapability[] capabilities, String channelId, Command command)
|
||||
throws IOException, InterruptedException {
|
||||
if (channelId.equals(POWER_STATE.channelId)) {
|
||||
if (containsCapabilityProperty(capabilities, POWER_STATE.propertyName)) {
|
||||
if (command.equals(OnOffType.ON)) {
|
||||
|
|
|
@ -92,7 +92,8 @@ public class HandlerPowerLevelController extends HandlerBase {
|
|||
|
||||
@Override
|
||||
public boolean handleCommand(Connection connection, SmartHomeDevice shd, String entityId,
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command) throws IOException {
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command)
|
||||
throws IOException, InterruptedException {
|
||||
if (channelId.equals(POWER_LEVEL.channelId)) {
|
||||
if (containsCapabilityProperty(capabilties, POWER_LEVEL.propertyName)) {
|
||||
if (command.equals(IncreaseDecreaseType.INCREASE)) {
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants;
|
||||
|
@ -147,12 +146,13 @@ public class HandlerSecurityPanelController extends HandlerBase {
|
|||
|
||||
@Override
|
||||
public boolean handleCommand(Connection connection, SmartHomeDevice shd, String entityId,
|
||||
SmartHomeCapability[] capabilties, String channelId, Command command) throws IOException {
|
||||
SmartHomeCapability[] capabilities, String channelId, Command command)
|
||||
throws IOException, InterruptedException {
|
||||
if (channelId.equals(ARM_STATE.channelId)) {
|
||||
if (containsCapabilityProperty(capabilties, ARM_STATE.propertyName)) {
|
||||
if (containsCapabilityProperty(capabilities, ARM_STATE.propertyName)) {
|
||||
if (command instanceof StringType) {
|
||||
String armStateValue = ((StringType) command).toFullString();
|
||||
if (StringUtils.isNotEmpty(armStateValue)) {
|
||||
String armStateValue = command.toFullString();
|
||||
if (!armStateValue.isEmpty()) {
|
||||
connection.smartHomeCommand(entityId, "controlSecurityPanel", ARM_STATE.propertyName,
|
||||
armStateValue);
|
||||
return true;
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeCapabilities.SmartHomeCapability;
|
||||
import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.DriverIdentity;
|
||||
|
@ -75,8 +74,9 @@ public class SmartHomeDeviceStateGroupUpdateCalculator {
|
|||
}
|
||||
}
|
||||
if (updateIntervalInSeconds == null) {
|
||||
if ("openHAB".equalsIgnoreCase(shd.manufacturerName)
|
||||
|| StringUtils.startsWithIgnoreCase(shd.manufacturerName, "ioBroker")) {
|
||||
String manufacturerName = shd.manufacturerName;
|
||||
if (manufacturerName != null && ("openHAB".equalsIgnoreCase(manufacturerName)
|
||||
|| manufacturerName.toLowerCase().startsWith("iobroker"))) {
|
||||
// OpenHAB or ioBroker skill
|
||||
if (logger.isTraceEnabled()) {
|
||||
updateIntervalInSeconds = UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS_TRACE;
|
||||
|
|
Loading…
Reference in New Issue