Improve discovery service (#11258)
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
This commit is contained in:
parent
3fc7c6559c
commit
84ba4fc333
|
@ -32,9 +32,8 @@ The supported thing types are:
|
||||||
|
|
||||||
## Discovery
|
## Discovery
|
||||||
|
|
||||||
Manually initiated Auto-discovery is supported if Kaleidescape components are accessible on the same IP subnet of the openHAB server.
|
Manually initiated Auto-discovery will locate all suported Kaleidescape components if they are on the same IP subnet of the openHAB server.
|
||||||
Since discovery involves scanning all IP addresses in the subnet range for an open socket, the discovery must be initiated by the user.
|
In the Inbox, select Search For Things and then choose the Kaleidescape System Binding to initiate a discovery scan.
|
||||||
In the Inbox, select Search For Things and then choose the Kaleidescape System Binding to initiate discovery.
|
|
||||||
|
|
||||||
## Binding Configuration
|
## Binding Configuration
|
||||||
|
|
||||||
|
|
|
@ -1,209 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2010-2021 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.kaleidescape.internal.discovery;
|
|
||||||
|
|
||||||
import static org.openhab.binding.kaleidescape.internal.KaleidescapeBindingConstants.*;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
|
||||||
import org.openhab.core.thing.ThingTypeUID;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link KaleidescapeDiscoveryJob} class allow manual discovery of
|
|
||||||
* Kaleidescape components for a single IP address. This is used
|
|
||||||
* for threading to make discovery faster.
|
|
||||||
*
|
|
||||||
* @author Chris Graham - Initial contribution
|
|
||||||
* @author Michael Lobstein - Adapted for the Kaleidescape binding
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@NonNullByDefault
|
|
||||||
public class KaleidescapeDiscoveryJob implements Runnable {
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(KaleidescapeDiscoveryJob.class);
|
|
||||||
|
|
||||||
// Component Types
|
|
||||||
private static final String PLAYER = "Player";
|
|
||||||
private static final String CINEMA_ONE = "Cinema One";
|
|
||||||
private static final String ALTO = "Alto";
|
|
||||||
private static final String STRATO = "Strato";
|
|
||||||
private static final String STRATO_S = "Strato S";
|
|
||||||
private static final String DISC_VAULT = "Disc Vault";
|
|
||||||
|
|
||||||
private static final Set<String> ALLOWED_DEVICES = new HashSet<String>(
|
|
||||||
Arrays.asList(PLAYER, CINEMA_ONE, ALTO, STRATO, STRATO_S, DISC_VAULT));
|
|
||||||
|
|
||||||
private KaleidescapeDiscoveryService discoveryClass;
|
|
||||||
|
|
||||||
private ThingTypeUID thingTypeUid = THING_TYPE_PLAYER;
|
|
||||||
private String ipAddress = EMPTY;
|
|
||||||
private String friendlyName = EMPTY;
|
|
||||||
private String serialNumber = EMPTY;
|
|
||||||
|
|
||||||
public KaleidescapeDiscoveryJob(KaleidescapeDiscoveryService service, String ip) {
|
|
||||||
this.discoveryClass = service;
|
|
||||||
this.ipAddress = ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (hasKaleidescapeDevice(this.ipAddress)) {
|
|
||||||
discoveryClass.submitDiscoveryResults(this.thingTypeUid, this.ipAddress, this.friendlyName,
|
|
||||||
this.serialNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if a Kaleidescape component with a movie player zone is available at a given IP address.
|
|
||||||
*
|
|
||||||
* @param ip IP address of the Kaleidescape component as a string.
|
|
||||||
* @return True if a component is found, false if not.
|
|
||||||
*/
|
|
||||||
private boolean hasKaleidescapeDevice(String ip) {
|
|
||||||
try {
|
|
||||||
InetAddress address = InetAddress.getByName(ip);
|
|
||||||
|
|
||||||
if (isKaleidescapeDevice(address, DEFAULT_API_PORT)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
logger.debug("No Kaleidescape component found at IP address ({})", ip);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
logger.debug("Unknown host: {} - {}", ip, e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to establish a connection to a hostname and port and then interrogate the component
|
|
||||||
*
|
|
||||||
* @param host Hostname or IP address to connect to.
|
|
||||||
* @param port Port to attempt to connect to.
|
|
||||||
* @return True if the component found is one the binding supports
|
|
||||||
*/
|
|
||||||
private boolean isKaleidescapeDevice(InetAddress host, int port) {
|
|
||||||
try (Socket socket = new Socket()) {
|
|
||||||
socket.connect(new InetSocketAddress(host, port), DISCOVERY_DEFAULT_IP_TIMEOUT_RATE_MS);
|
|
||||||
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
PrintWriter writer = new PrintWriter(output, true);
|
|
||||||
|
|
||||||
// query the component to see if it has video zones, the device type, friendly name, and serial number
|
|
||||||
writer.println("01/1/GET_NUM_ZONES:");
|
|
||||||
writer.println("01/1/GET_DEVICE_TYPE_NAME:");
|
|
||||||
writer.println("01/1/GET_FRIENDLY_NAME:");
|
|
||||||
writer.println("01/1/GET_DEVICE_INFO:");
|
|
||||||
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
|
|
||||||
|
|
||||||
String componentType = EMPTY;
|
|
||||||
String line;
|
|
||||||
String videoZone = null;
|
|
||||||
String audioZone = null;
|
|
||||||
int lineCount = 0;
|
|
||||||
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
String[] strArr = line.split(":");
|
|
||||||
|
|
||||||
if (strArr.length >= 4) {
|
|
||||||
switch (strArr[1]) {
|
|
||||||
case "NUM_ZONES":
|
|
||||||
videoZone = strArr[2];
|
|
||||||
audioZone = strArr[3];
|
|
||||||
break;
|
|
||||||
case "DEVICE_TYPE_NAME":
|
|
||||||
componentType = strArr[2];
|
|
||||||
break;
|
|
||||||
case "FRIENDLY_NAME":
|
|
||||||
friendlyName = strArr[2];
|
|
||||||
break;
|
|
||||||
case "DEVICE_INFO":
|
|
||||||
serialNumber = strArr[3].trim(); // take off leading zeros
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.debug("isKaleidescapeDevice() - Unable to process line: {}", line);
|
|
||||||
}
|
|
||||||
|
|
||||||
lineCount++;
|
|
||||||
|
|
||||||
// stop after reading four lines
|
|
||||||
if (lineCount > 3) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// see if we have a video zone
|
|
||||||
if ("01".equals(videoZone)) {
|
|
||||||
// now check if we are one of the allowed types
|
|
||||||
if (ALLOWED_DEVICES.contains(componentType)) {
|
|
||||||
if (STRATO_S.equals(componentType) || STRATO.equals(componentType)) {
|
|
||||||
thingTypeUid = THING_TYPE_STRATO;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A 'Player' without an audio zone is really a Strato C
|
|
||||||
// does not work yet, Strato C erroneously reports "01" for audio zones
|
|
||||||
// so we are unable to differentiate a Strato C from a Premiere player
|
|
||||||
if ("00".equals(audioZone) && PLAYER.equals(componentType)) {
|
|
||||||
thingTypeUid = THING_TYPE_STRATO;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alto
|
|
||||||
if (ALTO.equals(componentType)) {
|
|
||||||
thingTypeUid = THING_TYPE_ALTO;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cinema One
|
|
||||||
if (CINEMA_ONE.equals(componentType)) {
|
|
||||||
thingTypeUid = THING_TYPE_CINEMA_ONE;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Disc Vault with a video zone (the M700 vault), just call it a THING_TYPE_PLAYER
|
|
||||||
if (DISC_VAULT.equals(componentType)) {
|
|
||||||
thingTypeUid = THING_TYPE_PLAYER;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// default returns THING_TYPE_PLAYER
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.debug("isKaleidescapeDevice() IOException: {}", e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,26 +14,30 @@ package org.openhab.binding.kaleidescape.internal.discovery;
|
||||||
|
|
||||||
import static org.openhab.binding.kaleidescape.internal.KaleidescapeBindingConstants.*;
|
import static org.openhab.binding.kaleidescape.internal.KaleidescapeBindingConstants.*;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
import java.io.BufferedReader;
|
||||||
import java.net.Inet6Address;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.io.InputStream;
|
||||||
import java.net.InterfaceAddress;
|
import java.io.InputStreamReader;
|
||||||
import java.net.NetworkInterface;
|
import java.io.OutputStream;
|
||||||
import java.net.SocketException;
|
import java.io.PrintWriter;
|
||||||
import java.net.UnknownHostException;
|
import java.net.DatagramPacket;
|
||||||
import java.util.ArrayList;
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.net.util.SubnetUtils;
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.core.common.NamedThreadFactory;
|
import org.openhab.core.common.NamedThreadFactory;
|
||||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||||
|
@ -60,6 +64,29 @@ public class KaleidescapeDiscoveryService extends AbstractDiscoveryService {
|
||||||
.unmodifiableSet(Stream.of(THING_TYPE_PLAYER, THING_TYPE_CINEMA_ONE, THING_TYPE_ALTO, THING_TYPE_STRATO)
|
.unmodifiableSet(Stream.of(THING_TYPE_PLAYER, THING_TYPE_CINEMA_ONE, THING_TYPE_ALTO, THING_TYPE_STRATO)
|
||||||
.collect(Collectors.toSet()));
|
.collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
private static final int K_HEARTBEAT_PORT = 1443;
|
||||||
|
|
||||||
|
// Component Types
|
||||||
|
private static final String PLAYER = "Player";
|
||||||
|
private static final String CINEMA_ONE = "Cinema One";
|
||||||
|
private static final String ALTO = "Alto";
|
||||||
|
private static final String STRATO = "Strato";
|
||||||
|
private static final String STRATO_S = "Strato S";
|
||||||
|
private static final String DISC_VAULT = "Disc Vault";
|
||||||
|
|
||||||
|
private static final Set<String> ALLOWED_DEVICES = new HashSet<String>(
|
||||||
|
Arrays.asList(PLAYER, CINEMA_ONE, ALTO, STRATO, STRATO_S, DISC_VAULT));
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private ExecutorService executorService = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether we are currently scanning or not
|
||||||
|
*/
|
||||||
|
private boolean scanning;
|
||||||
|
|
||||||
|
private Set<String> foundIPs = new HashSet<String>();
|
||||||
|
|
||||||
@Activate
|
@Activate
|
||||||
public KaleidescapeDiscoveryService() {
|
public KaleidescapeDiscoveryService() {
|
||||||
super(SUPPORTED_THING_TYPES_UIDS, DISCOVERY_DEFAULT_TIMEOUT_RATE_MS, DISCOVERY_DEFAULT_AUTO_DISCOVER);
|
super(SUPPORTED_THING_TYPES_UIDS, DISCOVERY_DEFAULT_TIMEOUT_RATE_MS, DISCOVERY_DEFAULT_AUTO_DISCOVER);
|
||||||
|
@ -70,27 +97,194 @@ public class KaleidescapeDiscoveryService extends AbstractDiscoveryService {
|
||||||
return SUPPORTED_THING_TYPES_UIDS;
|
return SUPPORTED_THING_TYPES_UIDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* Starts the scan. This discovery will:
|
||||||
|
* <ul>
|
||||||
|
* <li>Create a listening thread that opens up a broadcast {@link DatagramSocket} on port {@link #K_HEARTBEAT_PORT}
|
||||||
|
* and will receive any {@link DatagramPacket} that comes in</li>
|
||||||
|
* <li>The source IP address of the {@link DatagramPacket} is interrogated to verify it is a Kaleidescape component
|
||||||
|
* and will create a new thing from it</li>
|
||||||
|
* </ul>
|
||||||
|
* The process will continue until {@link #stopScan()} is called.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void startScan() {
|
protected void startScan() {
|
||||||
logger.debug("Starting discovery of Kaleidescape components.");
|
logger.debug("Starting discovery of Kaleidescape components.");
|
||||||
|
|
||||||
try {
|
if (executorService != null) {
|
||||||
List<String> ipList = getIpAddressScanList();
|
stopScan();
|
||||||
|
}
|
||||||
|
|
||||||
ExecutorService discoverySearchPool = Executors.newFixedThreadPool(DISCOVERY_THREAD_POOL_SIZE,
|
final ExecutorService service = Executors.newFixedThreadPool(DISCOVERY_THREAD_POOL_SIZE,
|
||||||
new NamedThreadFactory("OH-binding-discovery.kaleidescape", true));
|
new NamedThreadFactory("OH-binding-discovery.kaleidescape", true));
|
||||||
|
executorService = service;
|
||||||
|
|
||||||
for (String ip : ipList) {
|
scanning = true;
|
||||||
discoverySearchPool.execute(new KaleidescapeDiscoveryJob(this, ip));
|
foundIPs.clear();
|
||||||
|
|
||||||
|
service.execute(() -> {
|
||||||
|
try {
|
||||||
|
DatagramSocket dSocket = new DatagramSocket(K_HEARTBEAT_PORT);
|
||||||
|
dSocket.setSoTimeout(DISCOVERY_DEFAULT_TIMEOUT_RATE_MS);
|
||||||
|
dSocket.setBroadcast(true);
|
||||||
|
|
||||||
|
while (scanning) {
|
||||||
|
DatagramPacket receivePacket = new DatagramPacket(new byte[1], 1);
|
||||||
|
try {
|
||||||
|
dSocket.receive(receivePacket);
|
||||||
|
|
||||||
|
if (!foundIPs.contains(receivePacket.getAddress().getHostAddress())) {
|
||||||
|
String foundIp = receivePacket.getAddress().getHostAddress();
|
||||||
|
logger.debug("RECEIVED Kaleidescape packet from: {}", foundIp);
|
||||||
|
foundIPs.add(foundIp);
|
||||||
|
isKaleidescapeDevice(foundIp);
|
||||||
|
}
|
||||||
|
} catch (SocketTimeoutException e) {
|
||||||
|
// ignore
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
discoverySearchPool.shutdown();
|
dSocket.close();
|
||||||
} catch (Exception exp) {
|
} catch (IOException e) {
|
||||||
logger.debug("Kaleidescape discovery service encountered an error while scanning for components: {}",
|
logger.debug("KaleidescapeDiscoveryService IOException: {}", e.getMessage(), e);
|
||||||
exp.getMessage());
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("Completed discovery of Kaleidescape components.");
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* Stops the discovery scan. We set {@link #scanning} to false (allowing the listening thread to end naturally
|
||||||
|
* within {@link #TIMEOUT) * 5 time then shutdown the {@link #executorService}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected synchronized void stopScan() {
|
||||||
|
super.stopScan();
|
||||||
|
ExecutorService service = executorService;
|
||||||
|
if (service == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scanning = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
service.awaitTermination(DISCOVERY_DEFAULT_TIMEOUT_RATE_MS * 5, TimeUnit.MILLISECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
service.shutdown();
|
||||||
|
executorService = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to establish a connection to the specified ip address and then interrogate the component,
|
||||||
|
* creates a discovery result if a valid component is found.
|
||||||
|
*
|
||||||
|
* @param ipAddress IP address to connect to
|
||||||
|
*/
|
||||||
|
private void isKaleidescapeDevice(String ipAddress) {
|
||||||
|
try (Socket socket = new Socket()) {
|
||||||
|
socket.connect(new InetSocketAddress(ipAddress, DEFAULT_API_PORT), DISCOVERY_DEFAULT_IP_TIMEOUT_RATE_MS);
|
||||||
|
|
||||||
|
OutputStream output = socket.getOutputStream();
|
||||||
|
PrintWriter writer = new PrintWriter(output, true);
|
||||||
|
|
||||||
|
// query the component to see if it has video zones, the device type, friendly name, and serial number
|
||||||
|
writer.println("01/1/GET_NUM_ZONES:");
|
||||||
|
writer.println("01/1/GET_DEVICE_TYPE_NAME:");
|
||||||
|
writer.println("01/1/GET_FRIENDLY_NAME:");
|
||||||
|
writer.println("01/1/GET_DEVICE_INFO:");
|
||||||
|
|
||||||
|
InputStream input = socket.getInputStream();
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
|
||||||
|
|
||||||
|
ThingTypeUID thingTypeUid = THING_TYPE_PLAYER;
|
||||||
|
String friendlyName = EMPTY;
|
||||||
|
String serialNumber = EMPTY;
|
||||||
|
String componentType = EMPTY;
|
||||||
|
String line;
|
||||||
|
String videoZone = null;
|
||||||
|
String audioZone = null;
|
||||||
|
int lineCount = 0;
|
||||||
|
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
String[] strArr = line.split(":");
|
||||||
|
|
||||||
|
if (strArr.length >= 4) {
|
||||||
|
switch (strArr[1]) {
|
||||||
|
case "NUM_ZONES":
|
||||||
|
videoZone = strArr[2];
|
||||||
|
audioZone = strArr[3];
|
||||||
|
break;
|
||||||
|
case "DEVICE_TYPE_NAME":
|
||||||
|
componentType = strArr[2];
|
||||||
|
break;
|
||||||
|
case "FRIENDLY_NAME":
|
||||||
|
friendlyName = strArr[2];
|
||||||
|
break;
|
||||||
|
case "DEVICE_INFO":
|
||||||
|
serialNumber = strArr[3].trim(); // take off leading zeros
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.debug("isKaleidescapeDevice() - Unable to process line: {}", line);
|
||||||
|
}
|
||||||
|
|
||||||
|
lineCount++;
|
||||||
|
|
||||||
|
// stop after reading four lines
|
||||||
|
if (lineCount > 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if we have a video zone
|
||||||
|
if ("01".equals(videoZone)) {
|
||||||
|
// now check if we are one of the allowed types
|
||||||
|
if (ALLOWED_DEVICES.contains(componentType)) {
|
||||||
|
if (STRATO_S.equals(componentType) || STRATO.equals(componentType)) {
|
||||||
|
thingTypeUid = THING_TYPE_STRATO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A 'Player' without an audio zone is really a Strato C
|
||||||
|
// does not work yet, Strato C erroneously reports "01" for audio zones
|
||||||
|
// so we are unable to differentiate a Strato C from a Premiere player
|
||||||
|
if ("00".equals(audioZone) && PLAYER.equals(componentType)) {
|
||||||
|
thingTypeUid = THING_TYPE_STRATO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alto
|
||||||
|
if (ALTO.equals(componentType)) {
|
||||||
|
thingTypeUid = THING_TYPE_ALTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cinema One
|
||||||
|
if (CINEMA_ONE.equals(componentType)) {
|
||||||
|
thingTypeUid = THING_TYPE_CINEMA_ONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Disc Vault with a video zone (the M700 vault), just call it a THING_TYPE_PLAYER
|
||||||
|
if (DISC_VAULT.equals(componentType)) {
|
||||||
|
thingTypeUid = THING_TYPE_PLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default THING_TYPE_PLAYER
|
||||||
|
submitDiscoveryResults(thingTypeUid, ipAddress, friendlyName, serialNumber);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.debug("No Suitable Kaleidescape component found at IP address ({})", ipAddress);
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
input.close();
|
||||||
|
writer.close();
|
||||||
|
output.close();
|
||||||
|
socket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.debug("isKaleidescapeDevice() IOException: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,7 +295,8 @@ public class KaleidescapeDiscoveryService extends AbstractDiscoveryService {
|
||||||
* @param friendlyName Name of Kaleidescape component as a string.
|
* @param friendlyName Name of Kaleidescape component as a string.
|
||||||
* @param serialNumber Serial Number of Kaleidescape component as a string.
|
* @param serialNumber Serial Number of Kaleidescape component as a string.
|
||||||
*/
|
*/
|
||||||
public void submitDiscoveryResults(ThingTypeUID thingTypeUid, String ip, String friendlyName, String serialNumber) {
|
private void submitDiscoveryResults(ThingTypeUID thingTypeUid, String ip, String friendlyName,
|
||||||
|
String serialNumber) {
|
||||||
ThingUID uid = new ThingUID(thingTypeUid, serialNumber);
|
ThingUID uid = new ThingUID(thingTypeUid, serialNumber);
|
||||||
|
|
||||||
HashMap<String, Object> properties = new HashMap<>();
|
HashMap<String, Object> properties = new HashMap<>();
|
||||||
|
@ -112,41 +307,4 @@ public class KaleidescapeDiscoveryService extends AbstractDiscoveryService {
|
||||||
thingDiscovered(DiscoveryResultBuilder.create(uid).withProperties(properties).withRepresentationProperty("host")
|
thingDiscovered(DiscoveryResultBuilder.create(uid).withProperties(properties).withRepresentationProperty("host")
|
||||||
.withLabel(friendlyName).build());
|
.withLabel(friendlyName).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide a string list of all the IP addresses associated with the network interfaces on
|
|
||||||
* this machine.
|
|
||||||
*
|
|
||||||
* @return String list of IP addresses.
|
|
||||||
* @throws UnknownHostException
|
|
||||||
* @throws SocketException
|
|
||||||
*/
|
|
||||||
private List<String> getIpAddressScanList() throws UnknownHostException, SocketException {
|
|
||||||
List<String> results = new ArrayList<>();
|
|
||||||
|
|
||||||
InetAddress localHost = InetAddress.getLocalHost();
|
|
||||||
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
|
|
||||||
|
|
||||||
for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
|
|
||||||
InetAddress ipAddress = address.getAddress();
|
|
||||||
|
|
||||||
String cidrSubnet = ipAddress.getHostAddress() + "/" + address.getNetworkPrefixLength();
|
|
||||||
|
|
||||||
/* Apache Subnet Utils only supports IP v4 for creating string list of IP's */
|
|
||||||
if (ipAddress instanceof Inet4Address) {
|
|
||||||
logger.debug("Found interface IPv4 address to scan: {}", cidrSubnet);
|
|
||||||
|
|
||||||
SubnetUtils utils = new SubnetUtils(cidrSubnet);
|
|
||||||
|
|
||||||
results.addAll(Arrays.asList(utils.getInfo().getAllAddresses())); // not sure how to do this without the
|
|
||||||
// Apache libraries
|
|
||||||
} else if (ipAddress instanceof Inet6Address) {
|
|
||||||
logger.debug("Found interface IPv6 address to scan: {}, ignoring", cidrSubnet);
|
|
||||||
} else {
|
|
||||||
logger.debug("Found interface unknown IP type address to scan: {}", cidrSubnet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue