[wemo] Fix UPnP resubscription after lost network connection (#12648)

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
pull/12651/head
Jacob Laursen 2022-04-25 11:16:47 +02:00 committed by GitHub
parent 270c917e66
commit 241a613d65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 131 additions and 148 deletions

View File

@ -12,10 +12,7 @@
*/
package org.openhab.binding.wemo.internal;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
@ -126,14 +123,12 @@ public class WemoBindingConstants {
public static final String INSIGHTACTION = "insight";
public static final String INSIGHTEVENT = "insight1";
public static final Set<ThingTypeUID> SUPPORTED_BRIDGE_THING_TYPES = Collections.singleton(THING_TYPE_BRIDGE);
public static final Set<ThingTypeUID> SUPPORTED_BRIDGE_THING_TYPES = Set.of(THING_TYPE_BRIDGE);
public static final Set<ThingTypeUID> SUPPORTED_LIGHT_THING_TYPES = Collections.singleton(THING_TYPE_MZ100);
public static final Set<ThingTypeUID> SUPPORTED_LIGHT_THING_TYPES = Set.of(THING_TYPE_MZ100);
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections
.unmodifiableSet(Stream
.of(THING_TYPE_SOCKET, THING_TYPE_INSIGHT, THING_TYPE_LIGHTSWITCH, THING_TYPE_MOTION,
THING_TYPE_BRIDGE, THING_TYPE_MZ100, THING_TYPE_MAKER, THING_TYPE_COFFEE, THING_TYPE_DIMMER,
THING_TYPE_CROCKPOT, THING_TYPE_PURIFIER, THING_TYPE_HUMIDIFIER, THING_TYPE_HEATER)
.collect(Collectors.toSet()));
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_SOCKET, THING_TYPE_INSIGHT,
THING_TYPE_LIGHTSWITCH, THING_TYPE_MOTION, THING_TYPE_BRIDGE, THING_TYPE_MZ100, THING_TYPE_MAKER,
THING_TYPE_COFFEE, THING_TYPE_DIMMER, THING_TYPE_CROCKPOT, THING_TYPE_PURIFIER, THING_TYPE_HUMIDIFIER,
THING_TYPE_HEATER);
}

View File

@ -21,6 +21,7 @@ import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.discovery.WemoLinkDiscoveryService;
import org.openhab.binding.wemo.internal.handler.WemoBridgeHandler;
import org.openhab.binding.wemo.internal.handler.WemoCoffeeHandler;
@ -67,6 +68,7 @@ public class WemoHandlerFactory extends BaseThingHandlerFactory {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = WemoBindingConstants.SUPPORTED_THING_TYPES;
private final UpnpIOService upnpIOService;
private final UpnpService upnpService;
private @Nullable WemoHttpCallFactory wemoHttpCallFactory;
@Override
@ -77,8 +79,9 @@ public class WemoHandlerFactory extends BaseThingHandlerFactory {
private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
@Activate
public WemoHandlerFactory(final @Reference UpnpIOService upnpIOService) {
public WemoHandlerFactory(final @Reference UpnpIOService upnpIOService, @Reference UpnpService upnpService) {
this.upnpIOService = upnpIOService;
this.upnpService = upnpService;
}
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
@ -108,46 +111,46 @@ public class WemoHandlerFactory extends BaseThingHandlerFactory {
} else if (WemoBindingConstants.THING_TYPE_INSIGHT.equals(thing.getThingTypeUID())) {
logger.debug("Creating a WemoInsightHandler for thing '{}' with UDN '{}'", thing.getUID(),
thing.getConfiguration().get(UDN));
return new WemoInsightHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoInsightHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else if (WemoBindingConstants.THING_TYPE_SOCKET.equals(thing.getThingTypeUID())
|| WemoBindingConstants.THING_TYPE_LIGHTSWITCH.equals(thing.getThingTypeUID())) {
logger.debug("Creating a WemoSwitchHandler for thing '{}' with UDN '{}'", thing.getUID(),
thing.getConfiguration().get(UDN));
return new WemoSwitchHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoSwitchHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else if (WemoBindingConstants.THING_TYPE_MOTION.equals(thing.getThingTypeUID())) {
logger.debug("Creating a WemoMotionHandler for thing '{}' with UDN '{}'", thing.getUID(),
thing.getConfiguration().get(UDN));
return new WemoMotionHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoMotionHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else if (thingTypeUID.equals(WemoBindingConstants.THING_TYPE_MAKER)) {
logger.debug("Creating a WemoMakerHandler for thing '{}' with UDN '{}'", thing.getUID(),
thing.getConfiguration().get(UDN));
return new WemoMakerHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoMakerHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else if (thingTypeUID.equals(WemoBindingConstants.THING_TYPE_COFFEE)) {
logger.debug("Creating a WemoCoffeeHandler for thing '{}' with UDN '{}'", thing.getUID(),
thing.getConfiguration().get(UDN));
return new WemoCoffeeHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoCoffeeHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else if (thingTypeUID.equals(WemoBindingConstants.THING_TYPE_DIMMER)) {
logger.debug("Creating a WemoDimmerHandler for thing '{}' with UDN '{}'", thing.getUID(),
thing.getConfiguration().get("udn"));
return new WemoDimmerHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoDimmerHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else if (thingTypeUID.equals(WemoBindingConstants.THING_TYPE_CROCKPOT)) {
logger.debug("Creating a WemoCockpotHandler for thing '{}' with UDN '{}'", thing.getUID(),
thing.getConfiguration().get("udn"));
return new WemoCrockpotHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoCrockpotHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else if (thingTypeUID.equals(WemoBindingConstants.THING_TYPE_PURIFIER)) {
logger.debug("Creating a WemoHolmesHandler for thing '{}' with UDN '{}'", thing.getUID(),
thing.getConfiguration().get("udn"));
return new WemoHolmesHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoHolmesHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else if (thingTypeUID.equals(WemoBindingConstants.THING_TYPE_HUMIDIFIER)) {
logger.debug("Creating a WemoHolmesHandler for thing '{}' with UDN '{}'", thing.getUID(),
thing.getConfiguration().get("udn"));
return new WemoHolmesHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoHolmesHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else if (thingTypeUID.equals(WemoBindingConstants.THING_TYPE_HEATER)) {
logger.debug("Creating a WemoHolmesHandler for thing '{}' with UDN '{}'", thing.getUID(),
thing.getConfiguration().get("udn"));
return new WemoHolmesHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoHolmesHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else if (thingTypeUID.equals(WemoBindingConstants.THING_TYPE_MZ100)) {
return new WemoLightHandler(thing, upnpIOService, wemoHttpcaller);
return new WemoLightHandler(thing, upnpIOService, upnpService, wemoHttpcaller);
} else {
logger.warn("ThingHandler not found for {}", thingTypeUID);
return null;

View File

@ -12,16 +12,13 @@
*/
package org.openhab.binding.wemo.internal;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.io.net.http.HttpUtil;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -34,8 +31,6 @@ import org.w3c.dom.Node;
@NonNullByDefault
public class WemoUtil {
public static BiFunction<String, Integer, Boolean> serviceAvailableFunction = WemoUtil::servicePing;
public static String substringBefore(@Nullable String string, String pattern) {
if (string != null) {
int pos = string.indexOf(pattern);
@ -125,15 +120,6 @@ public class WemoUtil {
return unescapedOutput.toString();
}
private static boolean servicePing(String host, int port) {
try {
HttpUtil.executeUrl("GET", "http://" + host + ":" + port, 250);
return true;
} catch (IOException e) {
return false;
}
}
private static Map<String, String> buildBuiltinXMLEntityMap() {
Map<String, String> entities = new HashMap<String, String>(10);
entities.put("lt", "<");

View File

@ -15,14 +15,16 @@ package org.openhab.binding.wemo.internal.handler;
import java.net.URL;
import java.time.Instant;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.jupnp.model.message.header.RootDeviceHeader;
import org.openhab.binding.wemo.internal.WemoBindingConstants;
import org.openhab.binding.wemo.internal.WemoUtil;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.io.transport.upnp.UpnpIOParticipant;
import org.openhab.core.io.transport.upnp.UpnpIOService;
@ -48,39 +50,36 @@ public abstract class WemoBaseThingHandler extends BaseThingHandler implements U
private static final int SUBSCRIPTION_RENEWAL_INTERVAL_SECONDS = 60;
private final Logger logger = LoggerFactory.getLogger(WemoBaseThingHandler.class);
private final UpnpIOService service;
private final UpnpService upnpService;
protected @Nullable UpnpIOService service;
protected WemoHttpCall wemoHttpCaller;
private @Nullable String host;
private Map<String, Instant> subscriptions = new ConcurrentHashMap<String, Instant>();
private @Nullable ScheduledFuture<?> subscriptionRenewalJob;
public WemoBaseThingHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpCaller) {
public WemoBaseThingHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService,
WemoHttpCall wemoHttpCaller) {
super(thing);
this.service = upnpIOService;
this.upnpService = upnpService;
this.wemoHttpCaller = wemoHttpCaller;
}
@Override
public void initialize() {
UpnpIOService service = this.service;
if (service != null) {
logger.debug("Registering UPnP participant for {}", getThing().getUID());
service.registerParticipant(this);
initializeHost();
}
logger.debug("Registering UPnP participant for {}", getThing().getUID());
service.registerParticipant(this);
initializeHost();
}
@Override
public void dispose() {
removeSubscriptions();
UpnpIOService service = this.service;
if (service != null) {
logger.debug("Unregistering UPnP participant for {}", getThing().getUID());
service.unregisterParticipant(this);
}
logger.debug("Unregistering UPnP participant for {}", getThing().getUID());
cancelSubscriptionRenewalJob();
service.unregisterParticipant(this);
}
@Override
@ -90,7 +89,20 @@ public abstract class WemoBaseThingHandler extends BaseThingHandler implements U
@Override
public void onStatusChanged(boolean status) {
// can be overridden by subclasses
if (status) {
logger.debug("UPnP device {} for {} is present", getUDN(), getThing().getUID());
if (service.isRegistered(this)) {
// After successful discovery, try to subscribe again.
renewSubscriptions();
}
} else {
logger.info("UPnP device {} for {} is absent", getUDN(), getThing().getUID());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR);
// Expire subscriptions.
for (Entry<String, Instant> subscription : subscriptions.entrySet()) {
subscription.setValue(Instant.MIN);
}
}
}
@Override
@ -111,12 +123,11 @@ public abstract class WemoBaseThingHandler extends BaseThingHandler implements U
@Override
public @Nullable String getUDN() {
return (String) this.getThing().getConfiguration().get(WemoBindingConstants.UDN);
return (String) this.getConfig().get(WemoBindingConstants.UDN);
}
protected boolean isUpnpDeviceRegistered() {
UpnpIOService service = this.service;
return service != null && service.isRegistered(this);
return service.isRegistered(this);
}
protected void addSubscription(String serviceId) {
@ -128,43 +139,12 @@ public abstract class WemoBaseThingHandler extends BaseThingHandler implements U
logger.debug("Adding first GENA subscription for {}, scheduling renewal job", getUDN());
scheduleSubscriptionRenewalJob();
}
subscriptions.put(serviceId, Instant.ofEpochSecond(0));
UpnpIOService service = this.service;
if (service == null) {
return;
}
if (!service.isRegistered(this)) {
logger.debug("Registering UPnP participant for {}", getUDN());
service.registerParticipant(this);
}
if (!service.isRegistered(this)) {
logger.debug("Trying to add GENA subscription {} for {}, but service is not registered", serviceId,
getUDN());
return;
}
logger.debug("Adding GENA subscription {} for {}", serviceId, getUDN());
subscriptions.put(serviceId, Instant.MIN);
logger.debug("Adding GENA subscription {} for {}, participant is {}", serviceId, getUDN(),
service.isRegistered(this) ? "registered" : "not registered");
service.addSubscription(this, serviceId, WemoBindingConstants.SUBSCRIPTION_DURATION_SECONDS);
}
protected void removeSubscription(String serviceId) {
UpnpIOService service = this.service;
if (service == null) {
return;
}
subscriptions.remove(serviceId);
if (subscriptions.isEmpty()) {
logger.debug("Removing last GENA subscription for {}, cancelling renewal job", getUDN());
cancelSubscriptionRenewalJob();
}
if (!service.isRegistered(this)) {
logger.debug("Trying to remove GENA subscription {} for {}, but service is not registered", serviceId,
getUDN());
return;
}
logger.debug("Unsubscribing {} from service {}", getUDN(), serviceId);
service.removeSubscription(this, serviceId);
}
private void scheduleSubscriptionRenewalJob() {
cancelSubscriptionRenewalJob();
this.subscriptionRenewalJob = scheduler.scheduleWithFixedDelay(this::renewSubscriptions,
@ -179,19 +159,14 @@ public abstract class WemoBaseThingHandler extends BaseThingHandler implements U
this.subscriptionRenewalJob = null;
}
private void renewSubscriptions() {
private synchronized void renewSubscriptions() {
if (subscriptions.isEmpty()) {
return;
}
UpnpIOService service = this.service;
if (service == null) {
return;
}
if (!service.isRegistered(this)) {
service.registerParticipant(this);
}
if (!service.isRegistered(this)) {
logger.debug("Trying to renew GENA subscriptions for {}, but service is not registered", getUDN());
logger.debug("Participant not registered when renewing GENA subscriptions for {}, starting UPnP discovery",
getUDN());
upnpService.getControlPoint().search(new RootDeviceHeader());
return;
}
logger.debug("Renewing GENA subscriptions for {}", getUDN());
@ -210,16 +185,8 @@ public abstract class WemoBaseThingHandler extends BaseThingHandler implements U
if (subscriptions.isEmpty()) {
return;
}
UpnpIOService service = this.service;
if (service == null) {
return;
}
if (!service.isRegistered(this)) {
logger.debug("Trying to remove GENA subscriptions for {}, but service is not registered",
getThing().getUID());
return;
}
logger.debug("Removing GENA subscriptions for {}", getUDN());
logger.debug("Removing GENA subscriptions for {}, participant is {}", getUDN(),
service.isRegistered(this) ? "registered" : "not registered");
subscriptions.forEach((serviceId, lastRenewed) -> {
logger.debug("Removing subscription for service {}", serviceId);
service.removeSubscription(this, serviceId);
@ -234,16 +201,8 @@ public abstract class WemoBaseThingHandler extends BaseThingHandler implements U
"@text/config-status.error.missing-ip");
return null;
}
int portCheckStart = 49151;
int portCheckStop = 49157;
String port = null;
for (int i = portCheckStart; i < portCheckStop; i++) {
if (WemoUtil.serviceAvailableFunction.apply(host, i)) {
port = String.valueOf(i);
break;
}
}
if (port == null) {
int port = scanForPort(host);
if (port == 0) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"@text/config-status.error.missing-url");
return null;
@ -263,13 +222,27 @@ public abstract class WemoBaseThingHandler extends BaseThingHandler implements U
host = getHostFromService();
}
private @Nullable String getHostFromService() {
UpnpIOService service = this.service;
if (service != null) {
URL descriptorURL = service.getDescriptorURL(this);
if (descriptorURL != null) {
return descriptorURL.getHost();
private int scanForPort(String host) {
int portCheckStart = 49151;
int portCheckStop = 49157;
int port = 0;
for (int portCheck = portCheckStart; portCheck < portCheckStop; portCheck++) {
String urlProbe = "http://" + host + ":" + portCheck;
logger.trace("Probing {} to find port", urlProbe);
if (!wemoHttpCaller.probeURL(urlProbe)) {
continue;
}
port = portCheck;
logger.trace("Successfully detected port {}", port);
break;
}
return port;
}
private @Nullable String getHostFromService() {
URL descriptorURL = service.getDescriptorURL(this);
if (descriptorURL != null) {
return descriptorURL.getHost();
}
return null;
}

View File

@ -29,6 +29,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.transport.upnp.UpnpIOService;
@ -69,8 +70,9 @@ public class WemoCoffeeHandler extends WemoBaseThingHandler {
private @Nullable ScheduledFuture<?> pollingJob;
public WemoCoffeeHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, wemoHttpCaller);
public WemoCoffeeHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService,
WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, upnpService, wemoHttpCaller);
logger.debug("Creating a WemoCoffeeHandler for thing '{}'", getThing().getUID());
}

View File

@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.transport.upnp.UpnpIOService;
@ -60,8 +61,9 @@ public class WemoCrockpotHandler extends WemoBaseThingHandler {
private @Nullable ScheduledFuture<?> pollingJob;
public WemoCrockpotHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, wemoHttpCaller);
public WemoCrockpotHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService,
WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, upnpService, wemoHttpCaller);
logger.debug("Creating a WemoCrockpotHandler for thing '{}'", getThing().getUID());
}

View File

@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.transport.upnp.UpnpIOService;
@ -73,8 +74,9 @@ public class WemoDimmerHandler extends WemoBaseThingHandler {
*/
private static final int DIM_STEPSIZE = 5;
public WemoDimmerHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, wemoHttpCaller);
public WemoDimmerHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService,
WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, upnpService, wemoHttpCaller);
logger.debug("Creating a WemoDimmerHandler for thing '{}'", getThing().getUID());
}

View File

@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.io.transport.upnp.UpnpIOService;
import org.openhab.core.library.types.OnOffType;
@ -52,8 +53,8 @@ public abstract class WemoHandler extends WemoBaseThingHandler {
private @Nullable ScheduledFuture<?> pollingJob;
public WemoHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, wemoHttpCaller);
public WemoHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService, WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, upnpService, wemoHttpCaller);
logger.debug("Creating a WemoHandler for thing '{}'", getThing().getUID());
}

View File

@ -30,6 +30,7 @@ import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.transport.upnp.UpnpIOService;
@ -74,8 +75,9 @@ public class WemoHolmesHandler extends WemoBaseThingHandler {
private @Nullable ScheduledFuture<?> pollingJob;
public WemoHolmesHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, wemoHttpCaller);
public WemoHolmesHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService,
WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, upnpService, wemoHttpCaller);
logger.debug("Creating a WemoHolmesHandler for thing '{}'", getThing().getUID());
}

View File

@ -20,6 +20,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.InsightParser;
import org.openhab.binding.wemo.internal.WemoBindingConstants;
import org.openhab.binding.wemo.internal.WemoPowerBank;
@ -51,8 +52,9 @@ public class WemoInsightHandler extends WemoHandler {
private int currentPowerSlidingSeconds;
private int currentPowerDeltaTrigger;
public WemoInsightHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, wemoHttpCaller);
public WemoInsightHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService,
WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, upnpService, wemoHttpCaller);
}
@Override

View File

@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.transport.upnp.UpnpIOService;
@ -70,8 +71,9 @@ public class WemoLightHandler extends WemoBaseThingHandler {
private @Nullable ScheduledFuture<?> pollingJob;
public WemoLightHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpcaller) {
super(thing, upnpIOService, wemoHttpcaller);
public WemoLightHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService,
WemoHttpCall wemoHttpcaller) {
super(thing, upnpIOService, upnpService, wemoHttpcaller);
logger.debug("Creating a WemoLightHandler for thing '{}'", getThing().getUID());
}

View File

@ -26,6 +26,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.transport.upnp.UpnpIOService;
@ -62,8 +63,9 @@ public class WemoMakerHandler extends WemoBaseThingHandler {
private @Nullable ScheduledFuture<?> pollingJob;
public WemoMakerHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpcaller) {
super(thing, upnpIOService, wemoHttpcaller);
public WemoMakerHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService,
WemoHttpCall wemoHttpcaller) {
super(thing, upnpIOService, upnpService, wemoHttpcaller);
logger.debug("Creating a WemoMakerHandler for thing '{}'", getThing().getUID());
}

View File

@ -17,6 +17,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.WemoBindingConstants;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.io.transport.upnp.UpnpIOService;
@ -40,8 +41,9 @@ public class WemoMotionHandler extends WemoHandler {
private final Logger logger = LoggerFactory.getLogger(WemoMotionHandler.class);
private final Map<String, String> stateMap = new ConcurrentHashMap<String, String>();
public WemoMotionHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, wemoHttpCaller);
public WemoMotionHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService,
WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, upnpService, wemoHttpCaller);
}
@Override

View File

@ -17,6 +17,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jupnp.UpnpService;
import org.openhab.binding.wemo.internal.WemoBindingConstants;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.io.transport.upnp.UpnpIOService;
@ -39,8 +40,9 @@ public class WemoSwitchHandler extends WemoHandler {
private final Logger logger = LoggerFactory.getLogger(WemoSwitchHandler.class);
private final Map<String, String> stateMap = new ConcurrentHashMap<String, String>();
public WemoSwitchHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, wemoHttpCaller);
public WemoSwitchHandler(Thing thing, UpnpIOService upnpIOService, UpnpService upnpService,
WemoHttpCall wemoHttpCaller) {
super(thing, upnpIOService, upnpService, wemoHttpCaller);
}
@Override

View File

@ -48,4 +48,13 @@ public class WemoHttpCall {
return responseBody;
}
public boolean probeURL(String url) {
try {
HttpUtil.executeUrl("GET", url, 250);
return true;
} catch (IOException e) {
return false;
}
}
}

View File

@ -143,7 +143,7 @@ public class WemoInsightHandlerTest {
String channelToWatch;
public MockWemoInsightHandler(Thing thing, String channelToWatch) {
super(thing, null, new WemoHttpCall());
super(thing, null, null, new WemoHttpCall());
this.channelToWatch = channelToWatch;
}

View File

@ -40,7 +40,6 @@ import org.jupnp.model.types.UDN;
import org.mockito.Mockito;
import org.openhab.binding.wemo.internal.WemoBindingConstants;
import org.openhab.binding.wemo.internal.WemoHttpCallFactory;
import org.openhab.binding.wemo.internal.WemoUtil;
import org.openhab.binding.wemo.internal.http.WemoHttpCall;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.transport.upnp.UpnpIOService;
@ -101,8 +100,6 @@ public abstract class GenericWemoOSGiTest extends JavaOSGiTest {
protected Thing thing;
protected void setUpServices() throws IOException {
WemoUtil.serviceAvailableFunction = (host, port) -> true;
// StorageService is required from the ManagedThingProvider
VolatileStorageService volatileStorageService = new VolatileStorageService();
registerService(volatileStorageService);
@ -123,6 +120,7 @@ public abstract class GenericWemoOSGiTest extends JavaOSGiTest {
assertThat(upnpIOService, is(notNullValue()));
mockCaller = Mockito.spy(new WemoHttpCall());
doReturn(true).when(mockCaller).probeURL(any());
WemoHttpCallFactory wemoHttpCallFactory = () -> mockCaller;
registerService(wemoHttpCallFactory, WemoHttpCallFactory.class.getName());