Hello, I’m having problems with discovery service of Nuki binding I’m updating. The discovery process for discovering Nuki bridges works like this:
User starts discovery, the binding calls API for obtaining list of Nuki bridges on the same network
Binding attemps to obtain API token for each bridge by calling HTTP endpoint on the bridge
If user then presses button on the bridge, that HTTP call succeedes and returns valid API token. Binding then creates bridge with token as a discovery result
If user fails to press button within 30s, the HTTP call fails, binding then creates discovery result wihtout token (and user must supply it manually)
Every time discovery is started, it will discover the same bridge which was already previously configured. User does not expect this and won’t press the button on bridge again and thus after the 30s interval bridge is discovered without API token. But since the id of bridge is the same as the id of existing bridge, it is not displayed in inbox as a new thing.
Now the problem - every time bridge discovery result is created without token, it will call initialize() method on existing bridge, but now getConfigAs method returns configuration without API token - the discovery result rewrites configuration of existing thing.
Is there a way to prevent this? Maybe somehow get list of existing things when starting discovery and skip discovering already configured bridges?
This sounds like something unique to the Nuki binding. If there is no other advice here, I recommend opening a new issue on the openhab-addons repo. See How to file an Issue.
I’ve moved your post to a more appropriate category.
I don’t think we understand each other. I’m the one implementing discovery service in nuki binding and I’m having problems with openHab API.
I’ll try to rephrase it:
The binding has a Thing with “apiToken” configuration property and unique identifier.
The discovery service I’m implementing will always discover the Thing with specific id, even if it was already discovered and is configured, but sometimes without “apiToken”
The problem is that when i call thingDiscovered on DiscoveryService with DiscoveryResult that has same id as the one that already exists but without “apiToken”, the existing already configured Thing will have it’s “apiToken” overwritten and set to null.
I’d like to know if there’s some way to solve this. Perhaps some API I can use to get list of existing things to check if thing with same id already exists, so I can skip creating DiscoveryResult.
Ok, since apparently there is no API which I can query to check if some thing already exists or not, I’ve created my own service which keeps track of created things (using createHandler and removeThing on ThingHandlerFactory). I then check it during bridge discovery and skip bridges which already exist.
Yes, it is computed from nukiId and is unique for each device.
What I find weird is that discovery result with same representation property is ignored from inbox, but at the same time it overwrites all the properties user configured on the existing thing.
Do I understand correctly, that discovery modifys an existing thing only by discovering a thing with the same representation property? Are you sure about that?
In general, the usage of the representation property is the correct way to go.
Yes, that’s exactly what’s happening. Every time the discovery finishes, api_token of existing bridge gets overwritten to null and it gets offline. That’s why I created this thread, this seems like a weird behavior but I don’t think I’m doing anything unusual with the discovery result.
I’m not sure, looking at PersistentInbox:258 source code that’s exactly what it’s meant to be doing:
logger.debug(
"Discovery result with thing '{}' not added as inbox entry. It is already present as thing in the ThingRegistry.",
thingUID);
boolean updated = synchronizeConfiguration(result.getThingTypeUID(), result.getProperties(),
thing.getConfiguration());
It takes properties from discovered thing and replaces existing thing configuration with them.
Is the discovery result usable at all, if the API token is empty? If not, you could skip the invocation of thingDiscovered() for that Thing during discovery.
I believe it is, you still get ip address and port of the bridge filled in automatically, so you don’t have to look it up.
Anyway, all that looking through openHAB core wasn’t for nothing. I found ThingRegistry which is exactly what I was looking for. I’ve injected it into bridge discovery service and use it to check if bridge with the same uuid already exists. Seems like a better solution than rolling my own service.