Simplify discovery registration (#18609)
Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>pull/18725/head
parent
84e1508054
commit
fe31deff03
|
@ -14,15 +14,9 @@ package org.openhab.binding.wemo.internal;
|
|||
|
||||
import static org.openhab.binding.wemo.internal.WemoBindingConstants.UDN;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.wemo.internal.discovery.WemoLinkDiscoveryService;
|
||||
import org.openhab.binding.wemo.internal.handler.WemoBridgeHandler;
|
||||
import org.openhab.binding.wemo.internal.handler.WemoCoffeeHandler;
|
||||
import org.openhab.binding.wemo.internal.handler.WemoCrockpotHandler;
|
||||
|
@ -33,17 +27,14 @@ import org.openhab.binding.wemo.internal.handler.WemoLightHandler;
|
|||
import org.openhab.binding.wemo.internal.handler.WemoMakerHandler;
|
||||
import org.openhab.binding.wemo.internal.handler.WemoMotionHandler;
|
||||
import org.openhab.binding.wemo.internal.handler.WemoSwitchHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.io.transport.upnp.UpnpIOService;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
@ -63,18 +54,14 @@ public class WemoHandlerFactory extends BaseThingHandlerFactory {
|
|||
|
||||
private final Logger logger = LoggerFactory.getLogger(WemoHandlerFactory.class);
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = WemoBindingConstants.SUPPORTED_THING_TYPES;
|
||||
|
||||
private final UpnpIOService upnpIOService;
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES.contains(thingTypeUID);
|
||||
return WemoBindingConstants.SUPPORTED_THING_TYPES.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
|
||||
|
||||
@Activate
|
||||
public WemoHandlerFactory(final @Reference UpnpIOService upnpIOService,
|
||||
final @Reference HttpClientFactory httpClientFactory) {
|
||||
|
@ -90,9 +77,7 @@ public class WemoHandlerFactory extends BaseThingHandlerFactory {
|
|||
if (thingTypeUID.equals(WemoBindingConstants.THING_TYPE_BRIDGE)) {
|
||||
logger.debug("Creating a WemoBridgeHandler for thing '{}' with UDN '{}'", thing.getUID(),
|
||||
thing.getConfiguration().get(UDN));
|
||||
WemoBridgeHandler handler = new WemoBridgeHandler((Bridge) thing);
|
||||
registerDeviceDiscoveryService(handler);
|
||||
return handler;
|
||||
return new WemoBridgeHandler((Bridge) thing, upnpIOService, httpClient);
|
||||
} else if (WemoBindingConstants.THING_TYPE_INSIGHT.equals(thing.getThingTypeUID())) {
|
||||
logger.debug("Creating a WemoInsightHandler for thing '{}' with UDN '{}'", thing.getUID(),
|
||||
thing.getConfiguration().get(UDN));
|
||||
|
@ -141,21 +126,4 @@ public class WemoHandlerFactory extends BaseThingHandlerFactory {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void removeHandler(ThingHandler thingHandler) {
|
||||
if (thingHandler instanceof WemoBridgeHandler) {
|
||||
ServiceRegistration<?> serviceReg = this.discoveryServiceRegs.remove(thingHandler.getThing().getUID());
|
||||
if (serviceReg != null) {
|
||||
serviceReg.unregister();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void registerDeviceDiscoveryService(WemoBridgeHandler wemoBridgeHandler) {
|
||||
WemoLinkDiscoveryService discoveryService = new WemoLinkDiscoveryService(wemoBridgeHandler, upnpIOService,
|
||||
httpClient);
|
||||
this.discoveryServiceRegs.put(wemoBridgeHandler.getThing().getUID(),
|
||||
bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ import static org.openhab.binding.wemo.internal.WemoBindingConstants.*;
|
|||
import static org.openhab.binding.wemo.internal.WemoUtil.*;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -28,16 +27,16 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
|||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.wemo.internal.ApiController;
|
||||
import org.openhab.binding.wemo.internal.exception.WemoException;
|
||||
import org.openhab.binding.wemo.internal.handler.WemoBridgeHandler;
|
||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.io.transport.upnp.UpnpIOParticipant;
|
||||
import org.openhab.core.io.transport.upnp.UpnpIOService;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.ServiceScope;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.CharacterData;
|
||||
|
@ -54,8 +53,10 @@ import org.xml.sax.InputSource;
|
|||
* @author Hans-Jörg Merk - Initial contribution
|
||||
*
|
||||
*/
|
||||
@Component(scope = ServiceScope.PROTOTYPE, service = WemoLinkDiscoveryService.class)
|
||||
@NonNullByDefault
|
||||
public class WemoLinkDiscoveryService extends AbstractDiscoveryService implements UpnpIOParticipant {
|
||||
public class WemoLinkDiscoveryService extends AbstractThingHandlerDiscoveryService<WemoBridgeHandler>
|
||||
implements UpnpIOParticipant {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_MZ100);
|
||||
private static final String NORMALIZE_ID_REGEX = "[^a-zA-Z0-9_]";
|
||||
|
@ -63,153 +64,118 @@ public class WemoLinkDiscoveryService extends AbstractDiscoveryService implement
|
|||
private static final int SCAN_INTERVAL_SECONDS = 120;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(WemoLinkDiscoveryService.class);
|
||||
private final WemoBridgeHandler wemoBridgeHandler;
|
||||
private final WemoLinkScan scanningRunnable;
|
||||
private final UpnpIOService service;
|
||||
private final ApiController apiController;
|
||||
|
||||
private @Nullable ScheduledFuture<?> scanningJob;
|
||||
|
||||
public WemoLinkDiscoveryService(final WemoBridgeHandler wemoBridgeHandler, final UpnpIOService upnpIOService,
|
||||
final HttpClient httpClient) {
|
||||
super(DISCOVERY_TIMEOUT_SECONDS);
|
||||
this.service = upnpIOService;
|
||||
this.wemoBridgeHandler = wemoBridgeHandler;
|
||||
this.apiController = new ApiController(httpClient);
|
||||
|
||||
public WemoLinkDiscoveryService() {
|
||||
super(WemoBridgeHandler.class, SUPPORTED_THING_TYPES, DISCOVERY_TIMEOUT_SECONDS);
|
||||
this.scanningRunnable = new WemoLinkScan();
|
||||
this.activate(null);
|
||||
}
|
||||
|
||||
public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
|
||||
return SUPPORTED_THING_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScan() {
|
||||
logger.trace("Starting WeMoEndDevice discovery on WeMo Link {}", wemoBridgeHandler.getThing().getUID());
|
||||
logger.trace("Starting WeMoEndDevice discovery on WeMo Link {}", thingHandler.getThing().getUID());
|
||||
|
||||
String endDevicesResponse;
|
||||
try {
|
||||
String devUDN = "uuid:" + wemoBridgeHandler.getThing().getConfiguration().get(UDN).toString();
|
||||
logger.trace("devUDN = '{}'", devUDN);
|
||||
endDevicesResponse = thingHandler.getEndDevices(this);
|
||||
} catch (WemoException e) {
|
||||
logger.debug("Failed to get endDevices for bridge '{}'", thingHandler.getThing().getUID(), e);
|
||||
return;
|
||||
} catch (InterruptedException e) {
|
||||
// Stop scanning
|
||||
return;
|
||||
}
|
||||
|
||||
String soapHeader = "\"urn:Belkin:service:bridge:1#GetEndDevices\"";
|
||||
String content = """
|
||||
<?xml version="1.0"?>\
|
||||
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">\
|
||||
<s:Body>\
|
||||
<u:GetEndDevices xmlns:u="urn:Belkin:service:bridge:1">\
|
||||
<DevUDN>\
|
||||
"""
|
||||
+ devUDN + """
|
||||
</DevUDN>\
|
||||
<ReqListType>PAIRED_LIST</ReqListType>\
|
||||
</u:GetEndDevices>\
|
||||
</s:Body>\
|
||||
</s:Envelope>\
|
||||
""";
|
||||
try {
|
||||
String stringParser = substringBetween(endDevicesResponse, "<DeviceLists>", "</DeviceLists>");
|
||||
|
||||
URL descriptorURL = service.getDescriptorURL(this);
|
||||
stringParser = unescapeXml(stringParser);
|
||||
|
||||
if (descriptorURL != null) {
|
||||
String deviceURL = substringBefore(descriptorURL.toString(), "/setup.xml");
|
||||
String wemoURL = deviceURL + "/upnp/control/bridge1";
|
||||
// check if there are already paired devices with WeMo Link
|
||||
if ("0".equals(stringParser)) {
|
||||
logger.debug("There are no devices connected with WeMo Link. Exit discovery");
|
||||
return;
|
||||
}
|
||||
|
||||
String endDeviceRequest = apiController.executeCall(wemoURL, soapHeader, content);
|
||||
// Build parser for received <DeviceList>
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
// see
|
||||
// https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
dbf.setXIncludeAware(false);
|
||||
dbf.setExpandEntityReferences(false);
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(stringParser));
|
||||
|
||||
logger.trace("endDeviceRequest answered '{}'", endDeviceRequest);
|
||||
Document doc = db.parse(is);
|
||||
NodeList nodes = doc.getElementsByTagName("DeviceInfo");
|
||||
|
||||
try {
|
||||
String stringParser = substringBetween(endDeviceRequest, "<DeviceLists>", "</DeviceLists>");
|
||||
// iterate the devices
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Element element = (Element) nodes.item(i);
|
||||
|
||||
stringParser = unescapeXml(stringParser);
|
||||
NodeList deviceIndex = element.getElementsByTagName("DeviceIndex");
|
||||
Element line = (Element) deviceIndex.item(0);
|
||||
logger.trace("DeviceIndex: {}", getCharacterDataFromElement(line));
|
||||
|
||||
// check if there are already paired devices with WeMo Link
|
||||
if ("0".equals(stringParser)) {
|
||||
logger.debug("There are no devices connected with WeMo Link. Exit discovery");
|
||||
return;
|
||||
NodeList deviceID = element.getElementsByTagName("DeviceID");
|
||||
line = (Element) deviceID.item(0);
|
||||
String endDeviceID = getCharacterDataFromElement(line);
|
||||
logger.trace("DeviceID: {}", endDeviceID);
|
||||
|
||||
NodeList friendlyName = element.getElementsByTagName("FriendlyName");
|
||||
line = (Element) friendlyName.item(0);
|
||||
String endDeviceName = getCharacterDataFromElement(line);
|
||||
logger.trace("FriendlyName: {}", endDeviceName);
|
||||
|
||||
NodeList vendor = element.getElementsByTagName("Manufacturer");
|
||||
line = (Element) vendor.item(0);
|
||||
String endDeviceVendor = getCharacterDataFromElement(line);
|
||||
logger.trace("Manufacturer: {}", endDeviceVendor);
|
||||
|
||||
NodeList model = element.getElementsByTagName("ModelCode");
|
||||
line = (Element) model.item(0);
|
||||
String endDeviceModelID = getCharacterDataFromElement(line);
|
||||
endDeviceModelID = endDeviceModelID.replaceAll(NORMALIZE_ID_REGEX, "_");
|
||||
|
||||
logger.trace("ModelCode: {}", endDeviceModelID);
|
||||
|
||||
if (SUPPORTED_THING_TYPES.contains(new ThingTypeUID(BINDING_ID, endDeviceModelID))) {
|
||||
logger.debug("Discovered a WeMo LED Light thing with ID '{}'", endDeviceID);
|
||||
|
||||
ThingUID bridgeUID = thingHandler.getThing().getUID();
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, endDeviceModelID);
|
||||
|
||||
if (thingTypeUID.equals(THING_TYPE_MZ100)) {
|
||||
String thingLightId = endDeviceID;
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, thingLightId);
|
||||
|
||||
Map<String, Object> properties = new HashMap<>(1);
|
||||
properties.put(DEVICE_ID, endDeviceID);
|
||||
|
||||
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID)
|
||||
.withProperties(properties).withBridge(thingHandler.getThing().getUID())
|
||||
.withLabel(endDeviceName).build();
|
||||
|
||||
thingDiscovered(discoveryResult);
|
||||
}
|
||||
|
||||
// Build parser for received <DeviceList>
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
// see
|
||||
// https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
dbf.setXIncludeAware(false);
|
||||
dbf.setExpandEntityReferences(false);
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(stringParser));
|
||||
|
||||
Document doc = db.parse(is);
|
||||
NodeList nodes = doc.getElementsByTagName("DeviceInfo");
|
||||
|
||||
// iterate the devices
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Element element = (Element) nodes.item(i);
|
||||
|
||||
NodeList deviceIndex = element.getElementsByTagName("DeviceIndex");
|
||||
Element line = (Element) deviceIndex.item(0);
|
||||
logger.trace("DeviceIndex: {}", getCharacterDataFromElement(line));
|
||||
|
||||
NodeList deviceID = element.getElementsByTagName("DeviceID");
|
||||
line = (Element) deviceID.item(0);
|
||||
String endDeviceID = getCharacterDataFromElement(line);
|
||||
logger.trace("DeviceID: {}", endDeviceID);
|
||||
|
||||
NodeList friendlyName = element.getElementsByTagName("FriendlyName");
|
||||
line = (Element) friendlyName.item(0);
|
||||
String endDeviceName = getCharacterDataFromElement(line);
|
||||
logger.trace("FriendlyName: {}", endDeviceName);
|
||||
|
||||
NodeList vendor = element.getElementsByTagName("Manufacturer");
|
||||
line = (Element) vendor.item(0);
|
||||
String endDeviceVendor = getCharacterDataFromElement(line);
|
||||
logger.trace("Manufacturer: {}", endDeviceVendor);
|
||||
|
||||
NodeList model = element.getElementsByTagName("ModelCode");
|
||||
line = (Element) model.item(0);
|
||||
String endDeviceModelID = getCharacterDataFromElement(line);
|
||||
endDeviceModelID = endDeviceModelID.replaceAll(NORMALIZE_ID_REGEX, "_");
|
||||
|
||||
logger.trace("ModelCode: {}", endDeviceModelID);
|
||||
|
||||
if (SUPPORTED_THING_TYPES.contains(new ThingTypeUID(BINDING_ID, endDeviceModelID))) {
|
||||
logger.debug("Discovered a WeMo LED Light thing with ID '{}'", endDeviceID);
|
||||
|
||||
ThingUID bridgeUID = wemoBridgeHandler.getThing().getUID();
|
||||
ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, endDeviceModelID);
|
||||
|
||||
if (thingTypeUID.equals(THING_TYPE_MZ100)) {
|
||||
String thingLightId = endDeviceID;
|
||||
ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, thingLightId);
|
||||
|
||||
Map<String, Object> properties = new HashMap<>(1);
|
||||
properties.put(DEVICE_ID, endDeviceID);
|
||||
|
||||
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID)
|
||||
.withProperties(properties).withBridge(wemoBridgeHandler.getThing().getUID())
|
||||
.withLabel(endDeviceName).build();
|
||||
|
||||
thingDiscovered(discoveryResult);
|
||||
}
|
||||
} else {
|
||||
logger.debug("Discovered an unsupported device :");
|
||||
logger.debug("DeviceIndex : {}", getCharacterDataFromElement(line));
|
||||
logger.debug("DeviceID : {}", endDeviceID);
|
||||
logger.debug("FriendlyName: {}", endDeviceName);
|
||||
logger.debug("Manufacturer: {}", endDeviceVendor);
|
||||
logger.debug("ModelCode : {}", endDeviceModelID);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to parse endDevices for bridge '{}'", wemoBridgeHandler.getThing().getUID(), e);
|
||||
} else {
|
||||
logger.debug("Discovered an unsupported device :");
|
||||
logger.debug("DeviceIndex : {}", getCharacterDataFromElement(line));
|
||||
logger.debug("DeviceID : {}", endDeviceID);
|
||||
logger.debug("FriendlyName: {}", endDeviceName);
|
||||
logger.debug("Manufacturer: {}", endDeviceVendor);
|
||||
logger.debug("ModelCode : {}", endDeviceModelID);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to get endDevices for bridge '{}'", wemoBridgeHandler.getThing().getUID(), e);
|
||||
logger.warn("Failed to parse endDevices for bridge '{}'", thingHandler.getThing().getUID(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,8 +186,8 @@ public class WemoLinkDiscoveryService extends AbstractDiscoveryService implement
|
|||
ScheduledFuture<?> job = scanningJob;
|
||||
|
||||
if (job == null || job.isCancelled()) {
|
||||
this.scanningJob = scheduler.scheduleWithFixedDelay(this.scanningRunnable,
|
||||
LINK_DISCOVERY_SERVICE_INITIAL_DELAY, SCAN_INTERVAL_SECONDS, TimeUnit.SECONDS);
|
||||
this.scanningJob = scheduler.scheduleWithFixedDelay(scanningRunnable, LINK_DISCOVERY_SERVICE_INITIAL_DELAY,
|
||||
SCAN_INTERVAL_SECONDS, TimeUnit.SECONDS);
|
||||
} else {
|
||||
logger.trace("scanningJob active");
|
||||
}
|
||||
|
@ -232,7 +198,7 @@ public class WemoLinkDiscoveryService extends AbstractDiscoveryService implement
|
|||
logger.debug("Stop WeMo device background discovery");
|
||||
|
||||
ScheduledFuture<?> job = scanningJob;
|
||||
if (job != null && !job.isCancelled()) {
|
||||
if (job != null) {
|
||||
job.cancel(true);
|
||||
}
|
||||
scanningJob = null;
|
||||
|
@ -240,7 +206,7 @@ public class WemoLinkDiscoveryService extends AbstractDiscoveryService implement
|
|||
|
||||
@Override
|
||||
public String getUDN() {
|
||||
return (String) this.wemoBridgeHandler.getThing().getConfiguration().get(UDN);
|
||||
return (String) thingHandler.getThing().getConfiguration().get(UDN);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -255,7 +221,7 @@ public class WemoLinkDiscoveryService extends AbstractDiscoveryService implement
|
|||
public void onStatusChanged(boolean status) {
|
||||
}
|
||||
|
||||
public static String getCharacterDataFromElement(Element e) {
|
||||
private static String getCharacterDataFromElement(Element e) {
|
||||
Node child = e.getFirstChild();
|
||||
if (child instanceof CharacterData cd) {
|
||||
return cd.getData();
|
||||
|
@ -263,7 +229,7 @@ public class WemoLinkDiscoveryService extends AbstractDiscoveryService implement
|
|||
return "?";
|
||||
}
|
||||
|
||||
public class WemoLinkScan implements Runnable {
|
||||
private class WemoLinkScan implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
startScan();
|
||||
|
|
|
@ -13,17 +13,27 @@
|
|||
package org.openhab.binding.wemo.internal.handler;
|
||||
|
||||
import static org.openhab.binding.wemo.internal.WemoBindingConstants.*;
|
||||
import static org.openhab.binding.wemo.internal.WemoUtil.substringBefore;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.wemo.internal.ApiController;
|
||||
import org.openhab.binding.wemo.internal.discovery.WemoLinkDiscoveryService;
|
||||
import org.openhab.binding.wemo.internal.exception.WemoException;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.io.transport.upnp.UpnpIOParticipant;
|
||||
import org.openhab.core.io.transport.upnp.UpnpIOService;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -40,10 +50,13 @@ public class WemoBridgeHandler extends BaseBridgeHandler {
|
|||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_BRIDGE);
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(WemoBridgeHandler.class);
|
||||
private final UpnpIOService service;
|
||||
private final ApiController apiController;
|
||||
|
||||
public WemoBridgeHandler(Bridge bridge) {
|
||||
public WemoBridgeHandler(final Bridge bridge, final UpnpIOService upnpIOService, final HttpClient httpClient) {
|
||||
super(bridge);
|
||||
logger.debug("Creating a WemoBridgeHandler for thing '{}'", getThing().getUID());
|
||||
this.service = upnpIOService;
|
||||
this.apiController = new ApiController(httpClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,4 +79,44 @@ public class WemoBridgeHandler extends BaseBridgeHandler {
|
|||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
// Not needed, all commands are handled in the {@link WemoLightHandler}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||
return Set.of(WemoLinkDiscoveryService.class);
|
||||
}
|
||||
|
||||
public String getEndDevices(UpnpIOParticipant participant) throws InterruptedException, WemoException {
|
||||
String devUDN = "uuid:" + getConfig().get(UDN).toString();
|
||||
logger.trace("getEndDevices for devUDN '{}'", devUDN);
|
||||
|
||||
String soapHeader = "\"urn:Belkin:service:bridge:1#GetEndDevices\"";
|
||||
String content = """
|
||||
<?xml version="1.0"?>\
|
||||
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">\
|
||||
<s:Body>\
|
||||
<u:GetEndDevices xmlns:u="urn:Belkin:service:bridge:1">\
|
||||
<DevUDN>\
|
||||
"""
|
||||
+ devUDN + """
|
||||
</DevUDN>\
|
||||
<ReqListType>PAIRED_LIST</ReqListType>\
|
||||
</u:GetEndDevices>\
|
||||
</s:Body>\
|
||||
</s:Envelope>\
|
||||
""";
|
||||
|
||||
URL descriptorURL = service.getDescriptorURL(participant);
|
||||
if (descriptorURL == null) {
|
||||
throw new WemoException("Descriptor URL for participant " + participant.getUDN() + " not found");
|
||||
}
|
||||
|
||||
String deviceURL = substringBefore(descriptorURL.toString(), "/setup.xml");
|
||||
String wemoURL = deviceURL + "/upnp/control/bridge1";
|
||||
|
||||
String endDeviceResponse = apiController.executeCall(wemoURL, soapHeader, content);
|
||||
|
||||
logger.trace("endDeviceRequest answered '{}'", endDeviceResponse);
|
||||
|
||||
return endDeviceResponse;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue