mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 07:02:02 +01:00
[roku] Check for ECP Limited Mode (#17925)
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
This commit is contained in:
parent
254f2f5886
commit
5d40a719f4
@ -3,6 +3,10 @@
|
||||
This binding connects Roku streaming media players and Roku TVs to openHAB.
|
||||
The Roku device must support the Roku ECP protocol REST API.
|
||||
|
||||
In order for the binding to control the Roku, the following setting:
|
||||
**Settings-> System-> Advanced system settings-> Control by mobile apps**
|
||||
must be configured as `Enabled` or `Permissive`.
|
||||
|
||||
## Supported Things
|
||||
|
||||
There are two supported thing types, which represent either a standalone Roku device or a Roku TV.
|
||||
|
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.roku.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link RokuLimitedModeException} extends RokuHttpException
|
||||
*
|
||||
* @author Michael Lobstein - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RokuLimitedModeException extends RokuHttpException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public RokuLimitedModeException(String errorMessage, Throwable t) {
|
||||
super(errorMessage, t);
|
||||
}
|
||||
|
||||
public RokuLimitedModeException(String errorMessage) {
|
||||
super(errorMessage);
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.openhab.binding.roku.internal.RokuHttpException;
|
||||
import org.openhab.binding.roku.internal.RokuLimitedModeException;
|
||||
import org.openhab.binding.roku.internal.dto.ActiveApp;
|
||||
import org.openhab.binding.roku.internal.dto.Apps;
|
||||
import org.openhab.binding.roku.internal.dto.Apps.App;
|
||||
@ -47,6 +48,7 @@ import org.slf4j.LoggerFactory;
|
||||
@NonNullByDefault
|
||||
public class RokuCommunicator {
|
||||
private static final int REQUEST_TIMEOUT = 5000;
|
||||
private static final String LIMITED_MODE_RESPONSE = "ECP command not allowed";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(RokuCommunicator.class);
|
||||
private final HttpClient httpClient;
|
||||
@ -283,8 +285,12 @@ public class RokuCommunicator {
|
||||
*/
|
||||
private String getCommand(String url) throws RokuHttpException {
|
||||
try {
|
||||
return httpClient.newRequest(url).method(HttpMethod.GET).timeout(REQUEST_TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.send().getContentAsString();
|
||||
final String response = httpClient.newRequest(url).method(HttpMethod.GET)
|
||||
.timeout(REQUEST_TIMEOUT, TimeUnit.MILLISECONDS).send().getContentAsString();
|
||||
if (response != null && response.contains(LIMITED_MODE_RESPONSE)) {
|
||||
throw new RokuLimitedModeException(url + ": " + response);
|
||||
}
|
||||
return response != null ? response : "";
|
||||
} catch (TimeoutException | ExecutionException e) {
|
||||
throw new RokuHttpException("Error executing GET command for URL: " + url, e);
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -26,6 +26,7 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.roku.internal.RokuConfiguration;
|
||||
import org.openhab.binding.roku.internal.RokuHttpException;
|
||||
import org.openhab.binding.roku.internal.RokuLimitedModeException;
|
||||
import org.openhab.binding.roku.internal.RokuStateDescriptionOptionProvider;
|
||||
import org.openhab.binding.roku.internal.communication.RokuCommunicator;
|
||||
import org.openhab.binding.roku.internal.dto.Apps.App;
|
||||
@ -73,6 +74,7 @@ public class RokuHandler extends BaseThingHandler {
|
||||
private DeviceInfo deviceInfo = new DeviceInfo();
|
||||
private int refreshInterval = DEFAULT_REFRESH_PERIOD_SEC;
|
||||
private boolean tvActive = false;
|
||||
private int limitedMode = -1;
|
||||
private Map<String, String> appMap = new HashMap<>();
|
||||
|
||||
private Object sequenceLock = new Object();
|
||||
@ -175,18 +177,20 @@ public class RokuHandler extends BaseThingHandler {
|
||||
}
|
||||
tvActive = false;
|
||||
}
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} catch (RokuHttpException e) {
|
||||
logger.debug("Unable to retrieve Roku active-app info. Exception: {}", e.getMessage(), e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// On the home app and when using the TV or TV inputs, do not update the play mode or time channels
|
||||
if (!ROKU_HOME_ID.equals(activeAppId) && !activeAppId.contains(TV_INPUT)) {
|
||||
// if in limitedMode, keep checking getPlayerInfo to see if the error goes away
|
||||
if ((!ROKU_HOME_ID.equals(activeAppId) && !activeAppId.contains(TV_INPUT)) || limitedMode != 0) {
|
||||
try {
|
||||
Player playerInfo = communicator.getPlayerInfo();
|
||||
limitedMode = 0;
|
||||
// When nothing playing, 'close' is reported, replace with 'stop'
|
||||
updateState(PLAY_MODE, new StringType(playerInfo.getState().replaceAll(CLOSE, STOP)));
|
||||
updateState(PLAY_MODE, new StringType(playerInfo.getState().replace(CLOSE, STOP)));
|
||||
updateState(CONTROL,
|
||||
PLAY.equalsIgnoreCase(playerInfo.getState()) ? PlayPauseType.PLAY : PlayPauseType.PAUSE);
|
||||
|
||||
@ -208,9 +212,13 @@ public class RokuHandler extends BaseThingHandler {
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
logger.debug("Unable to parse playerInfo integer value. Exception: {}", e.getMessage());
|
||||
} catch (RokuLimitedModeException e) {
|
||||
logger.debug("RokuLimitedModeException: {}", e.getMessage());
|
||||
limitedMode = 1;
|
||||
} catch (RokuHttpException e) {
|
||||
logger.debug("Unable to retrieve Roku media-player info. Exception: {}", e.getMessage(), e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
updateState(PLAY_MODE, UnDefType.UNDEF);
|
||||
@ -221,6 +229,7 @@ public class RokuHandler extends BaseThingHandler {
|
||||
if (thingTypeUID.equals(THING_TYPE_ROKU_TV) && tvActive) {
|
||||
try {
|
||||
TvChannel tvChannel = communicator.getActiveTvChannel();
|
||||
limitedMode = 0;
|
||||
updateState(ACTIVE_CHANNEL, new StringType(tvChannel.getChannel().getNumber()));
|
||||
updateState(SIGNAL_MODE, new StringType(tvChannel.getChannel().getSignalMode()));
|
||||
updateState(SIGNAL_QUALITY,
|
||||
@ -229,10 +238,21 @@ public class RokuHandler extends BaseThingHandler {
|
||||
updateState(PROGRAM_TITLE, new StringType(tvChannel.getChannel().getProgramTitle()));
|
||||
updateState(PROGRAM_DESCRIPTION, new StringType(tvChannel.getChannel().getProgramDescription()));
|
||||
updateState(PROGRAM_RATING, new StringType(tvChannel.getChannel().getProgramRatings()));
|
||||
} catch (RokuLimitedModeException e) {
|
||||
logger.debug("RokuLimitedModeException: {}", e.getMessage());
|
||||
limitedMode = 1;
|
||||
} catch (RokuHttpException e) {
|
||||
logger.debug("Unable to retrieve Roku tv-active-channel info. Exception: {}", e.getMessage(), e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (limitedMode < 1) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "@text/error.limited");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,3 +101,7 @@ channel-type.roku.timeElapsed.label = Playback Time
|
||||
channel-type.roku.timeElapsed.description = The Current Playback Time Elapsed
|
||||
channel-type.roku.timeTotal.label = Total Time
|
||||
channel-type.roku.timeTotal.description = The Total Length of the Current Title
|
||||
|
||||
# error status descriptions
|
||||
|
||||
error.limited = Roku device is configured incorrectly - see README
|
||||
|
Loading…
Reference in New Issue
Block a user