diff --git a/bundles/org.openhab.binding.oppo/README.md b/bundles/org.openhab.binding.oppo/README.md index f3a36a167892d..a55bfff477953 100644 --- a/bundles/org.openhab.binding.oppo/README.md +++ b/bundles/org.openhab.binding.oppo/README.md @@ -44,7 +44,7 @@ The thing has the following configuration parameters: | Address | host | Host name or IP address of the Oppo player or serial over IP device. | host name or ip | | Port | port | Communication port for using serial over IP. Leave blank if using direct IP connection to the player. | ip port number | | Serial Port | serialPort | Serial port to use for directly connecting to the Oppo player | a comm port name | -| Verbose Mode | verboseMode | (Optional) If true, the player will send time updates every second. If set false, the binding polls the player every 15 seconds. | Boolean; default false | +| Verbose Mode | verboseMode | (Optional) If true, the player will send time updates every second. If set false, the binding polls the player every 10 seconds. | Boolean; default false | Some notes: @@ -54,9 +54,10 @@ Some notes: * The UDP-20x series should be fully functional over direct IP connection but this was not able to be tested by the developer. * As previously noted, when using verbose mode, the player will send time code messages once per second while playback is ongoing. * Be aware that this could cause performance impacts to your openHAB system. -* In non-verbose (the default), the binding will poll the player every 15 seconds to update play time, track and chapter information instead. +* In non-verbose (the default), the binding will poll the player every 10 seconds to update play time, track and chapter information instead. * In order for the direct IP connection to work while the player is turned off, the Standby Mode setting must be set to "Quick Start" in the Device Setup menu. * Likewise if the player is turned off, it may not be discoverable by the Binding's discovery scan. +* If the player is switched off when the binding first starts up or if power to the player is ever interrupted, up to 30 seconds may elapse before the binding begins to update when the player is switched on. * If you experience any issues using the binding, first ensure that the player's firmware is up to date with the latest available version (especially on the older models). * For the older models, some of the features in the control API were added after the players were shipped. * Available HDMI modes for BDP-83 & BDP-9x: AUTO, SRC, 1080P, 1080I, 720P, SDP, SDI diff --git a/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/communication/OppoConnector.java b/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/communication/OppoConnector.java index 8055763283351..0ec5691a106d7 100644 --- a/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/communication/OppoConnector.java +++ b/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/communication/OppoConnector.java @@ -12,6 +12,8 @@ */ package org.openhab.binding.oppo.internal.communication; +import static org.openhab.binding.oppo.internal.OppoBindingConstants.*; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -38,6 +40,8 @@ public abstract class OppoConnector { private static final Pattern QRY_PATTERN = Pattern.compile("^@(Q[A-Z0-9]{2}|VUP|VDN) OK (.*)$"); private static final Pattern STUS_PATTERN = Pattern.compile("^@(U[A-Z0-9]{2}) (.*)$"); + private static final String OK_ON = "@OK ON"; + private static final String OK_OFF = "@OK OFF"; private static final String NOP_OK = "@NOP OK"; private static final String NOP = "NOP"; private static final String OK = "OK"; @@ -249,6 +253,17 @@ public void handleIncomingMessage(byte[] incomingMessage) { return; } + // Before verbose mode 2 & 3 get set, these are the responses to QPW + if (OK_ON.equals(message)) { + dispatchKeyValue(QPW, ON); + return; + } + + if (OK_OFF.equals(message)) { + dispatchKeyValue(QPW, OFF); + return; + } + // Player sent an OK response to a query: @QDT OK DVD-VIDEO or a volume update @VUP OK 100 Matcher matcher = QRY_PATTERN.matcher(message); if (matcher.find()) { diff --git a/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/discovery/OppoDiscoveryService.java b/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/discovery/OppoDiscoveryService.java index 947c477e575b7..878aa03f9ed4f 100644 --- a/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/discovery/OppoDiscoveryService.java +++ b/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/discovery/OppoDiscoveryService.java @@ -148,7 +148,7 @@ protected void startScan() { multiSocket.receive(receivePacket); String message = new String(receivePacket.getData(), StandardCharsets.US_ASCII).trim(); - if (message != null && message.length() > 0) { + if (message.length() > 0) { messageReceive(message); } } catch (SocketTimeoutException e) { @@ -158,7 +158,7 @@ protected void startScan() { multiSocket.close(); } catch (IOException e) { - if (!e.getMessage().contains("No IP addresses bound to interface")) { + if (e.getMessage() != null && !e.getMessage().contains("No IP addresses bound to interface")) { logger.debug("OppoDiscoveryService IOException: {}", e.getMessage(), e); } } diff --git a/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/handler/OppoHandler.java b/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/handler/OppoHandler.java index 3a1c862897436..c85182ec610a6 100644 --- a/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/handler/OppoHandler.java +++ b/bundles/org.openhab.binding.oppo/src/main/java/org/openhab/binding/oppo/internal/handler/OppoHandler.java @@ -69,8 +69,8 @@ @NonNullByDefault public class OppoHandler extends BaseThingHandler implements OppoMessageEventListener { private static final long RECON_POLLING_INTERVAL_SEC = 60; - private static final long POLLING_INTERVAL_SEC = 15; - private static final long INITIAL_POLLING_DELAY_SEC = 10; + private static final long POLLING_INTERVAL_SEC = 10; + private static final long INITIAL_POLLING_DELAY_SEC = 5; private static final long SLEEP_BETWEEN_CMD_MS = 100; private static final Pattern TIME_CODE_PATTERN = Pattern @@ -221,7 +221,7 @@ public void dispose() { * * @param channelUID the channel sending the command * @param command the command received - * + * */ @Override public void handleCommand(ChannelUID channelUID, Command command) { @@ -615,6 +615,8 @@ private void scheduleReconnectJob() { closeConnection(); } else { updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE); + isInitialQuery = false; + isVbModeSet = false; } } } @@ -647,19 +649,21 @@ private void schedulePollingJob() { synchronized (sequenceLock) { try { - // the verbose mode must be set while the player is on - if (isPowerOn && !isVbModeSet && !isBdpIP) { - connector.sendCommand(OppoCommand.SET_VERBOSE_MODE, this.verboseMode); - isVbModeSet = true; - Thread.sleep(SLEEP_BETWEEN_CMD_MS); + // Verbose mode 2 & 3 only do once until power comes on OR always for BDP direct IP + if ((!isPowerOn && !isInitialQuery) || isBdpIP) { + connector.sendCommand(OppoCommand.QUERY_POWER_STATUS); } - // If using direct serial connection, the query is done once after the player is turned on - // - OR - if using direct IP connection on the 83/9x/10x, no unsolicited updates are sent - // so we must query everything to know what changed. - if ((isPowerOn && !isInitialQuery) || isBdpIP) { - connector.sendCommand(OppoCommand.QUERY_POWER_STATUS); - if (isPowerOn) { + if (isPowerOn) { + // the verbose mode must be set while the player is on + if (!isVbModeSet && !isBdpIP) { + connector.sendCommand(OppoCommand.SET_VERBOSE_MODE, this.verboseMode); + isVbModeSet = true; + Thread.sleep(SLEEP_BETWEEN_CMD_MS); + } + + // Verbose mode 2 & 3 only do once OR always for BDP direct IP + if (!isInitialQuery || isBdpIP) { isInitialQuery = true; OppoCommand.QUERY_COMMANDS.forEach(cmd -> { try { @@ -670,34 +674,34 @@ private void schedulePollingJob() { } }); } - } - // for Verbose mode 2 get the current play back time if we are playing, otherwise just do NO_OP - if ((VERBOSE_2.equals(this.verboseMode) && PLAY.equals(currentPlayMode)) - || (isBdpIP && isPowerOn)) { - switch (currentTimeMode) { - case T: - connector.sendCommand(OppoCommand.QUERY_TITLE_ELAPSED); - break; - case X: - connector.sendCommand(OppoCommand.QUERY_TITLE_REMAIN); - break; - case C: - connector.sendCommand(OppoCommand.QUERY_CHAPTER_ELAPSED); - break; - case K: - connector.sendCommand(OppoCommand.QUERY_CHAPTER_REMAIN); - break; - } - Thread.sleep(SLEEP_BETWEEN_CMD_MS); + // for Verbose mode 2 get the current play back time if we are playing, otherwise just do + // NO_OP + if ((VERBOSE_2.equals(this.verboseMode) && PLAY.equals(currentPlayMode)) || isBdpIP) { + switch (currentTimeMode) { + case T: + connector.sendCommand(OppoCommand.QUERY_TITLE_ELAPSED); + break; + case X: + connector.sendCommand(OppoCommand.QUERY_TITLE_REMAIN); + break; + case C: + connector.sendCommand(OppoCommand.QUERY_CHAPTER_ELAPSED); + break; + case K: + connector.sendCommand(OppoCommand.QUERY_CHAPTER_REMAIN); + break; + } + Thread.sleep(SLEEP_BETWEEN_CMD_MS); - // make queries to refresh total number of titles/tracks & chapters - connector.sendCommand(OppoCommand.QUERY_TITLE_TRACK); - Thread.sleep(SLEEP_BETWEEN_CMD_MS); - connector.sendCommand(OppoCommand.QUERY_CHAPTER); - } else if (!isBdpIP) { - // verbose mode 3 - connector.sendCommand(OppoCommand.NO_OP); + // make queries to refresh total number of titles/tracks & chapters + connector.sendCommand(OppoCommand.QUERY_TITLE_TRACK); + Thread.sleep(SLEEP_BETWEEN_CMD_MS); + connector.sendCommand(OppoCommand.QUERY_CHAPTER); + } else if (!isBdpIP) { + // verbose mode 3 + connector.sendCommand(OppoCommand.NO_OP); + } } } catch (OppoException | InterruptedException e) {