Hi!
I’m currently working on learning to implement a binding and in the binding that I’m currently trying to improve (Verisure) I’ve just switched to using the HttpClientFactory instead of instantiating and starting a binding specific HttpClient.
My binding specific VerisureHandlerFactory has now added the two methods:
@Reference
protected void setHttpClientFactory(HttpClientFactory httpClientFactory) {
logger.debug("setHttpClientFactory this: " + this.toString());
VerisureHandlerFactory.httpClient = httpClientFactory.getCommonHttpClient();
}
protected void unsetHttpClientFactory(HttpClientFactory httpClientFactory) {
logger.debug("unsetHttpClientFactory this: " + this.toString());
VerisureHandlerFactory.httpClient = null;
}
When running I can see that the setHttpClientFactory gets called by the ESH framework:
2018-10-05 22:58:13.281 [DEBUG] [org.openhab.binding.verisure ] - BundleEvent RESOLVED - org.openhab.binding.verisure
2018-10-05 22:58:13.299 [DEBUG] [org.openhab.binding.verisure ] - BundleEvent STARTING - org.openhab.binding.verisure
2018-10-05 22:58:13.334 [DEBUG] [org.openhab.binding.verisure ] - ServiceEvent REGISTERED - {org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory}={service.id=430, service.bundleid=237, ser
vice.scope=bundle, component.name=binding.verisure, component.id=268} - org.openhab.binding.verisure
2018-10-05 22:58:13.438 [DEBUG] [org.openhab.binding.verisure ] - ServiceEvent REGISTERED - {org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory}={service.id=431, service.bundleid=237, ser
vice.scope=bundle, component.name=org.openhab.binding.verisure.internal.VerisureHandlerFactory, component.id=269} - org.openhab.binding.verisure
2018-10-05 22:58:13.444 [DEBUG] [sure.internal.VerisureHandlerFactory] - setHttpClientFactory this: org.openhab.binding.verisure.internal.VerisureHandlerFactory@1b677e7
2018-10-05 22:58:13.462 [DEBUG] [org.openhab.binding.verisure ] - BundleEvent STARTED - org.openhab.binding.verisure
2018-10-05 22:58:13.659 [DEBUG] [sure.internal.VerisureHandlerFactory] - createHandler this: org.openhab.binding.verisure.internal.VerisureHandlerFactory@6bc8fa
2018-10-05 22:58:13.692 [DEBUG] [org.openhab.binding.verisure ] - ServiceEvent REGISTERED - {org.eclipse.smarthome.config.discovery.DiscoveryService}={service.id=432, service.bundleid=237, service.
scope=singleton} - org.openhab.binding.verisure
It seems like my binding HandlerFactory gets called for 2 different objects/instances:
setHttpClientFactory this: org.openhab.binding.verisure.internal.VerisureHandlerFactory@1b677e7
createHandler this: org.openhab.binding.verisure.internal.VerisureHandlerFactory@6bc8fa
Hence. in the second call my private member httpClient is not initialised (null) so my binding BridgeHandler is created with a null argument for the HttpClient.
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.verisure")
public class VerisureHandlerFactory extends BaseThingHandlerFactory {
private final static Set<ThingTypeUID> SUPPORTED_THING_TYPES = Sets
.union(VerisureBridgeHandler.SUPPORTED_THING_TYPES, VerisureThingHandler.SUPPORTED_THING_TYPES);
private Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
private HttpClient httpClient;
private Logger logger = LoggerFactory.getLogger(VerisureHandlerFactory.class);
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES.contains(thingTypeUID);
}
@Override
protected ThingHandler createHandler(Thing thing) {
logger.debug("createHandler this: " + this.toString());
if (VerisureBridgeHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
VerisureBridgeHandler handler = new VerisureBridgeHandler((Bridge) thing, httpClient);
registerObjectDiscoveryService(handler);
return handler;
} else if (VerisureThingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
return new VerisureThingHandler(thing);
}
return null;
}
Why is the binding HandlerFactory called for different objects/instances? Shouldn’t I only have one instance of my binding HandlerFactory instantiated by the ESH framework?
I get the same behaviour locally on my Eclipse environment (as on my openHAB 2.3.0 Release Build production environment).
I temporary worked around it making my private member static, but other bindings does not do that.
What have I missed?
BR,
/Janne