Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 99 additions & 93 deletions bundles/org.openhab.binding.oppo/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,18 @@ public class OppoBindingConstants {

// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_PLAYER = new ThingTypeUID(BINDING_ID, "player");
public static final ThingTypeUID THING_TYPE_BDP83 = new ThingTypeUID(BINDING_ID, "bdp-83");
public static final ThingTypeUID THING_TYPE_BDP93 = new ThingTypeUID(BINDING_ID, "bdp-93");
public static final ThingTypeUID THING_TYPE_BDP103 = new ThingTypeUID(BINDING_ID, "bdp-103");
public static final ThingTypeUID THING_TYPE_BDP105 = new ThingTypeUID(BINDING_ID, "bdp-105");
public static final ThingTypeUID THING_TYPE_UDP203 = new ThingTypeUID(BINDING_ID, "udp-203");
public static final ThingTypeUID THING_TYPE_UDP205 = new ThingTypeUID(BINDING_ID, "udp-205");

public static final Unit<Time> API_SECONDS_UNIT = Units.SECOND;
public static final Unit<Dimensionless> API_PERCENT_UNIT = Units.PERCENT;

public static final int MODEL83 = 83;
public static final int MODEL93 = 93;
public static final int MODEL103 = 103;
public static final int MODEL105 = 105;
public static final int MODEL203 = 203;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
@NonNullByDefault
@Component(configurationPid = "binding.oppo", service = ThingHandlerFactory.class)
public class OppoHandlerFactory extends BaseThingHandlerFactory {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_PLAYER);
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_BDP83, THING_TYPE_BDP93,
THING_TYPE_BDP103, THING_TYPE_BDP105, THING_TYPE_UDP203, THING_TYPE_UDP205, THING_TYPE_PLAYER);

private final SerialPortManager serialPortManager;
private final TranslationProvider translationProvider;
Expand All @@ -65,9 +66,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {

@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
if (SUPPORTED_THING_TYPES_UIDS.contains(thing.getThingTypeUID())) {
return new OppoHandler(thing, stateDescriptionProvider, serialPortManager, translationProvider,
localeProvider);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,18 @@ public enum OppoCommand {

private final String value;

public static final Set<OppoCommand> QUERY_COMMANDS = Set.of(QUERY_PLAYBACK_STATUS, QUERY_INPUT_SOURCE,
QUERY_VOLUME, QUERY_HDMI_RESOLUTION, QUERY_DISC_TYPE, QUERY_AUDIO_TYPE, QUERY_SUBTITLE_SHIFT,
QUERY_OSD_POSITION, QUERY_REPEAT_MODE, QUERY_ZOOM_MODE, QUERY_3D_STATUS, QUERY_HDR_SETTING);
public static final Set<OppoCommand> QUERY_COMMANDS_83 = Set.of(QUERY_PLAYBACK_STATUS, QUERY_VOLUME,
QUERY_HDMI_RESOLUTION, QUERY_DISC_TYPE, QUERY_AUDIO_TYPE, QUERY_SUBTITLE_TYPE, QUERY_SUBTITLE_SHIFT,
QUERY_OSD_POSITION, QUERY_REPEAT_MODE, QUERY_ZOOM_MODE);

public static final Set<OppoCommand> QUERY_COMMANDS_10X = Set.of(QUERY_PLAYBACK_STATUS, QUERY_VOLUME,
QUERY_HDMI_RESOLUTION, QUERY_DISC_TYPE, QUERY_AUDIO_TYPE, QUERY_SUBTITLE_TYPE, QUERY_SUBTITLE_SHIFT,
QUERY_OSD_POSITION, QUERY_REPEAT_MODE, QUERY_ZOOM_MODE, QUERY_3D_STATUS, QUERY_INPUT_SOURCE);

public static final Set<OppoCommand> QUERY_COMMANDS_20X = Set.of(QUERY_PLAYBACK_STATUS, QUERY_VOLUME,
QUERY_HDMI_RESOLUTION, QUERY_DISC_TYPE, QUERY_AUDIO_TYPE, QUERY_SUBTITLE_TYPE, QUERY_SUBTITLE_SHIFT,
QUERY_OSD_POSITION, QUERY_REPEAT_MODE, QUERY_ZOOM_MODE, QUERY_3D_STATUS, QUERY_INPUT_SOURCE,
QUERY_HDR_SETTING);

OppoCommand(String value) {
this.value = value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@

/**
* Discovery class for the Oppo Blu-ray Player line.
* The player sends SDDP packets continuously for us to discover.
* The player sends what it calls SDDP packets continuously for us to discover.
* The format is not compatible with OH core SDDP discovery (Control4 SDDP packets).
*
* @author Tim Roberts - Initial contribution
* @author Michael Lobstein - Adapted for the Oppo binding
Expand All @@ -54,7 +55,8 @@
@NonNullByDefault
@Component(service = DiscoveryService.class, configurationPid = "discovery.oppo")
public class OppoDiscoveryService extends AbstractDiscoveryService {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_PLAYER);
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_BDP83, THING_TYPE_BDP93,
THING_TYPE_BDP103, THING_TYPE_BDP105, THING_TYPE_UDP203, THING_TYPE_UDP205);

private final Logger logger = LoggerFactory.getLogger(OppoDiscoveryService.class);

Expand Down Expand Up @@ -88,7 +90,8 @@ public class OppoDiscoveryService extends AbstractDiscoveryService {
*/
private @Nullable ExecutorService executorService;

private static final String DISPLAY_NAME_83 = "OPPO BDP-83/93/95";
private static final String DISPLAY_NAME_83 = "OPPO BDP-83";
private static final String DISPLAY_NAME_93 = "OPPO BDP-93/95";
private static final String DISPLAY_NAME_103 = "OPPO BDP-103";
private static final String DISPLAY_NAME_105 = "OPPO BDP-105";

Expand All @@ -112,10 +115,8 @@ public Set<ThingTypeUID> getSupportedThingTypes() {
* <li>Request all the network interfaces</li>
* <li>For each network interface, create a listening thread using {@link #executorService}</li>
* <li>Each listening thread will open up a {@link MulticastSocket} using {@link #SDDP_ADDR} and {@link #SDDP_PORT}
* and
* will receive any {@link DatagramPacket} that comes in</li>
* <li>The {@link DatagramPacket} is then investigated to see if is a SDDP packet and will create a new thing from
* it</li>
* and will receive any {@link DatagramPacket} that comes in</li>
* <li>If the {@link DatagramPacket} is a Oppo SDDP packet, a new thing will be created from it</li>
* </ul>
* The process will continue until {@link #stopScan()} is called.
*/
Expand All @@ -138,18 +139,18 @@ protected void startScan() {

service.execute(() -> {
try {
MulticastSocket multiSocket = new MulticastSocket(SDDP_PORT);
InetSocketAddress inetSocketAddress = new InetSocketAddress(addr, SDDP_PORT);
final MulticastSocket multiSocket = new MulticastSocket(SDDP_PORT);
final InetSocketAddress inetSocketAddress = new InetSocketAddress(addr, SDDP_PORT);
multiSocket.setSoTimeout(TIMEOUT_MS);
multiSocket.setNetworkInterface(netint);
multiSocket.joinGroup(inetSocketAddress, null);

while (scanning) {
DatagramPacket receivePacket = new DatagramPacket(new byte[BUFFER_SIZE], BUFFER_SIZE);
final DatagramPacket packet = new DatagramPacket(new byte[BUFFER_SIZE], BUFFER_SIZE);
try {
multiSocket.receive(receivePacket);
multiSocket.receive(packet);

String message = new String(receivePacket.getData(), StandardCharsets.US_ASCII).trim();
final String message = new String(packet.getData(), StandardCharsets.US_ASCII).trim();
Comment thread
mlobstein marked this conversation as resolved.
Outdated
if (message.length() > 0) {
messageReceive(message);
}
Expand Down Expand Up @@ -185,20 +186,16 @@ protected void startScan() {
* </pre>
*
*
* @param message possibly null, possibly empty SDDP message
* @param message the SDDP message from the Oppo player
*/
private void messageReceive(String message) {
if (message.trim().length() == 0) {
return;
}

ThingTypeUID thingTypeUID = null;
String host = null;
String port = null;
Integer model = null;
String displayName = null;

for (String msg : message.split("\n")) {
String[] line = msg.split(":");
for (final String msg : message.split("\n")) {
final String[] line = msg.split(":");
Comment thread
mlobstein marked this conversation as resolved.
Outdated

if (line.length == 2) {
if (line[0].contains("Server IP")) {
Expand All @@ -222,50 +219,50 @@ private void messageReceive(String message) {
// by looking at the port number we can mostly determine what the model number is
if (host != null && port != null) {
if (BDP83_PORT.toString().equals(port)) {
model = MODEL83;
thingTypeUID = THING_TYPE_BDP83;
displayName = DISPLAY_NAME_83;
} else if (BDP10X_PORT.toString().equals(port)) {
// The older models do not have the "Server Name" in the discovery packet
// for the 10x we need to get the DLNA service list page and find modelNumber there
// in order to determine if this is a BDP-103 or BDP-105
// It is not known if the BDP-9x has this page so a failure to will default to THING_TYPE_BDP93
Comment thread
mlobstein marked this conversation as resolved.
Outdated
try {
String result = HttpUtil.executeUrl("GET", "http://" + host + ":2870/dmr.xml", 5000);
final String result = HttpUtil.executeUrl("GET", "http://" + host + ":2870/dmr.xml", 5000);

if (result != null && result.contains("<modelName>OPPO BDP-103</modelName>")) {
model = MODEL103;
if (result != null && result.contains("BDP-103")) {
thingTypeUID = THING_TYPE_BDP103;
displayName = DISPLAY_NAME_103;
} else if (result != null && result.contains("<modelName>OPPO BDP-105</modelName>")) {
model = MODEL105;
} else if (result != null && result.contains("BDP-105")) {
thingTypeUID = THING_TYPE_BDP105;
displayName = DISPLAY_NAME_105;
} else {
model = MODEL103;
displayName = DISPLAY_NAME_103;
thingTypeUID = THING_TYPE_BDP93;
displayName = DISPLAY_NAME_93;
}
} catch (IOException e) {
logger.debug("Error getting player DLNA info page: {}", e.getMessage());
// the call failed for some reason, just assume we are a 103
model = MODEL103;
displayName = DISPLAY_NAME_103;
// the call failed, just assume we are a 93
thingTypeUID = THING_TYPE_BDP93;
displayName = DISPLAY_NAME_93;
}
} else if (UDP20X_PORT.toString().equals(port)) {
if (displayName != null && displayName.contains(Integer.toString(MODEL203))) {
model = MODEL203;
thingTypeUID = THING_TYPE_UDP203;
} else if (displayName != null && displayName.contains(Integer.toString(MODEL205))) {
model = MODEL205;
thingTypeUID = THING_TYPE_UDP205;
} else {
model = MODEL203;
displayName = "Unknown OPPO UDP player";
thingTypeUID = THING_TYPE_UDP203;
displayName = "OPPO UDP-20X";
}
}

if (model != null) {
ThingUID uid = new ThingUID(THING_TYPE_PLAYER, host.replace(".", "_"));
HashMap<String, Object> properties = new HashMap<>();
properties.put("model", model);
if (thingTypeUID != null) {
final ThingUID uid = new ThingUID(thingTypeUID, host.replace(".", "_"));
final HashMap<String, Object> properties = new HashMap<>(1);
properties.put("host", host);

DiscoveryResult result = DiscoveryResultBuilder.create(uid).withProperties(properties)
.withRepresentationProperty("host").withLabel(displayName + " (" + host + ")").build();
final DiscoveryResult result = DiscoveryResultBuilder.create(uid).withProperties(properties)
.withRepresentationProperty("host").withLabel(displayName).build();

this.thingDiscovered(result);
}
Expand Down
Loading