[SOLVED] Cannot figure out how to avoid bundleContext.registerService()!

Hi All,

In the middle of creating a new binding and the way I did it before appears no longer to be valid. Specifically in relation to doing discovery.

Previously, you created a discovery service that implemented AbstractDiscoveryService and then registered that discovery service using something like:

MyDiscovery d = new MyDiscovery(bridge)
bundleContext.registerService(DiscoveryService.class.getName(),
d, new Hashtable<String, Object>());

However, I can see that use of the bundleContext is no longer permitted as it has been deprecated. So, I have looked through literally 1000’s of lines of code from other peoples bindings to try to figure out how to proceed. However, I have not had any luck in figuring it out!

If I do it this way…

@Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.<bindingID>")
public class MyDiscovery...

I am unable to get a reference to the bridge as I cannot use the traditional approach of constructing the discovery object with the bridge as a parameter, the constructor is required by the annotation to have no parameters.

To be clear, the nature of the discovery is such that it needs the bridge as the bridge has the connection to the device and it is this connection that will be queried to do the discovery!

Can someone point me in the direction of the correct pattern to use please? I am very aware of the documentation (https://www.eclipse.org/smarthome/documentation/development/bindings/discovery-services.html), but that’s not shedding any light (for me at least).

Thanks,
MKF

I’m trying to find out what you mean by the bundleContext has been deprecated. Where did you see this? If I walk through the code of a binding I developed that uses a similar approach I don’t see anything deprecated and I updated all code to the latest version.

Hi Hilbrand,

This is what I have in BaseThingHandler

    @Deprecated // this must not be used by bindings!
    @NonNullByDefault({})
    protected BundleContext bundleContext;

Doing it the ‘old’ way does appear to work. However, you do get the usual warnings in Eclipse about things being deprecated. In my searching for the ‘proper’ way, I also saw some references to people being asked to change their method, eg:

Cheers
MFK

Ah ok. You can register it in your HandlerFactory, where you create the handler. For example see here:

@hilbrand, thanks soooooo much. Was really bashing my head off a wall for hours today trying to figure out the correct way! All implemented now and working correctly.

One quick question to make sure that I don’t need to do something additional. When the bridge is added, nothing appears in the “Inbox” until I click into (+) on to add additional things for the binding and then lots of things get discovered. Is this normal? Should discovery not kick-off at the point that the Bridge comes on-line?

Thanks again,
MKF

PS - I noticed that when I remove the bridge, the child things aren’t getting removed. They are going to state “updated: UNINITIALIZED (HANDLER_MISSING_ERROR)”. Don’t know if this is a symptom of the new approach I am using for discovery. More digging needed!

Yes that is normal. Basically because the handler is not really aware if this was the first time, or if it’s just when the system was started. You can implement background discovery in the discovery service (override startBackgroundDiscovery() and start a scheduled method). In that case it will start the background discovery once it comes online.

That is expected behavior. Well it’s how it works at the moment. Because things can be assigned a new bridge they are still relevant.

Excellent, thanks for that. Binding nearly ready so! Last few tidy’ ups remaining!