2 * Copyright (c) 2010-2022 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.flicbutton.internal.discovery;
15 import java.io.IOException;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.binding.flicbutton.internal.FlicButtonBindingConstants;
21 import org.openhab.binding.flicbutton.internal.util.FlicButtonUtils;
22 import org.openhab.core.config.discovery.AbstractDiscoveryService;
23 import org.openhab.core.config.discovery.DiscoveryResult;
24 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
25 import org.openhab.core.thing.ThingUID;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 import io.flic.fliclib.javaclient.Bdaddr;
30 import io.flic.fliclib.javaclient.FlicClient;
31 import io.flic.fliclib.javaclient.GeneralCallbacks;
32 import io.flic.fliclib.javaclient.GetInfoResponseCallback;
33 import io.flic.fliclib.javaclient.enums.BdAddrType;
34 import io.flic.fliclib.javaclient.enums.BluetoothControllerState;
37 * For each configured flicd service, there is a {@link FlicSimpleclientDiscoveryServiceImpl} which will be initialized
38 * by {@link org.openhab.binding.flicbutton.internal.FlicButtonHandlerFactory}.
40 * It can scan for Flic Buttons already that are already added to fliclib-linux-hci ("verified" buttons), *
41 * but it does not support adding and verify new buttons on it's own.
42 * New buttons have to be added (verified) e.g. via simpleclient by Shortcut Labs.
43 * Background discovery listens for new buttons that are getting verified.
45 * @author Patrick Fink - Initial contribution
48 public class FlicSimpleclientDiscoveryServiceImpl extends AbstractDiscoveryService
49 implements FlicButtonDiscoveryService {
50 private final Logger logger = LoggerFactory.getLogger(FlicSimpleclientDiscoveryServiceImpl.class);
52 private boolean activated = false;
53 private ThingUID bridgeUID;
54 private @Nullable FlicClient flicClient;
56 public FlicSimpleclientDiscoveryServiceImpl(ThingUID bridgeUID) {
57 super(FlicButtonBindingConstants.SUPPORTED_THING_TYPES_UIDS, 2, true);
58 this.bridgeUID = bridgeUID;
62 public void activate(FlicClient flicClient) {
63 this.flicClient = flicClient;
69 public void deactivate() {
75 protected void startScan() {
78 discoverVerifiedButtons();
80 } catch (IOException e) {
81 logger.warn("Error occured during button discovery", e);
82 if (this.scanListener != null) {
83 scanListener.onErrorOccurred(e);
88 protected void discoverVerifiedButtons() throws IOException {
89 flicClient.getInfo(new GetInfoResponseCallback() {
91 public void onGetInfoResponse(@Nullable BluetoothControllerState bluetoothControllerState,
92 @Nullable Bdaddr myBdAddr, @Nullable BdAddrType myBdAddrType, int maxPendingConnections,
93 int maxConcurrentlyConnectedButtons, int currentPendingConnections,
94 boolean currentlyNoSpaceForNewConnection, Bdaddr @Nullable [] verifiedButtons) throws IOException {
95 for (final @Nullable Bdaddr bdaddr : verifiedButtons) {
97 flicButtonDiscovered((@NonNull Bdaddr) bdaddr);
105 protected void startBackgroundDiscovery() {
106 super.startBackgroundDiscovery();
107 flicClient.setGeneralCallbacks(new GeneralCallbacks() {
109 public void onNewVerifiedButton(@Nullable Bdaddr bdaddr) throws IOException {
110 logger.debug("A new Flic button was added by an external flicd client: {}", bdaddr);
111 if (bdaddr != null) {
112 flicButtonDiscovered((@NonNull Bdaddr) bdaddr);
119 protected void stopBackgroundDiscovery() {
120 super.stopBackgroundDiscovery();
121 if (flicClient != null) {
122 flicClient.setGeneralCallbacks(null);
127 public ThingUID flicButtonDiscovered(Bdaddr bdaddr) {
128 logger.debug("Flic Button {} discovered!", bdaddr);
129 ThingUID flicButtonUID = FlicButtonUtils.getThingUIDFromBdAddr(bdaddr, bridgeUID);
131 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(flicButtonUID).withBridge(bridgeUID)
132 .withLabel("Flic Button " + bdaddr.toString().replace(":", ""))
133 .withProperty(FlicButtonBindingConstants.CONFIG_ADDRESS, bdaddr.toString())
134 .withRepresentationProperty(FlicButtonBindingConstants.CONFIG_ADDRESS).build();
135 this.thingDiscovered(discoveryResult);
136 return flicButtonUID;