]> git.basschouten.com Git - openhab-addons.git/blob
243bc570e05318692e3cb0dd5c1656bd52893c64
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.bluetooth.bluez.internal;
14
15 import java.util.Set;
16 import java.util.concurrent.Future;
17 import java.util.concurrent.TimeUnit;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.core.config.discovery.AbstractDiscoveryService;
22 import org.openhab.core.config.discovery.DiscoveryResult;
23 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
24 import org.openhab.core.config.discovery.DiscoveryService;
25 import org.openhab.core.thing.ThingUID;
26 import org.osgi.service.component.annotations.Activate;
27 import org.osgi.service.component.annotations.Component;
28 import org.osgi.service.component.annotations.Reference;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import com.github.hypfvieh.bluetooth.wrapper.BluetoothAdapter;
33
34 /**
35  * This is a discovery service, which checks whether we are running on a Linux with a BlueZ stack.
36  * If this is the case, we create a bridge handler that provides Bluetooth access through BlueZ.
37  *
38  * @author Kai Kreuzer - Initial Contribution and API
39  * @author Hilbrand Bouwkamp - Moved background scan to actual background method
40  * @author Connor Petty - Replaced tinyB with bluezDbus
41  *
42  */
43 @NonNullByDefault
44 @Component(service = DiscoveryService.class, configurationPid = "discovery.bluetooth.bluez")
45 public class BlueZDiscoveryService extends AbstractDiscoveryService {
46
47     private final Logger logger = LoggerFactory.getLogger(BlueZDiscoveryService.class);
48
49     private final DeviceManagerFactory deviceManagerFactory;
50     private @Nullable Future<?> backgroundScan;
51
52     @Activate
53     public BlueZDiscoveryService(@Reference DeviceManagerFactory deviceManagerFactory) {
54         super(Set.of(BlueZAdapterConstants.THING_TYPE_BLUEZ), 1, true);
55         this.deviceManagerFactory = deviceManagerFactory;
56     }
57
58     private static void cancel(@Nullable Future<?> future) {
59         if (future != null) {
60             future.cancel(false);
61         }
62     }
63
64     @Override
65     protected void startBackgroundDiscovery() {
66         backgroundScan = scheduler.scheduleWithFixedDelay(() -> {
67             DeviceManagerWrapper deviceManager = deviceManagerFactory.getDeviceManager();
68             if (deviceManager == null) {
69                 return;
70             }
71             startScan();
72         }, 5, 10, TimeUnit.SECONDS);
73     }
74
75     @Override
76     protected void stopBackgroundDiscovery() {
77         cancel(backgroundScan);
78         backgroundScan = null;
79     }
80
81     @Override
82     protected void startScan() {
83         DeviceManagerWrapper deviceManager = deviceManagerFactory.getDeviceManager();
84         if (deviceManager == null) {
85             logger.warn("The DeviceManager is not available");
86             return;
87         }
88         // the first time the device manager is not null we can cancel background discovery
89         stopBackgroundDiscovery();
90         deviceManager.scanForBluetoothAdapters().stream()//
91                 .map(this::createDiscoveryResult)//
92                 .forEach(this::thingDiscovered);
93     }
94
95     private DiscoveryResult createDiscoveryResult(BluetoothAdapter adapter) {
96         return DiscoveryResultBuilder.create(new ThingUID(BlueZAdapterConstants.THING_TYPE_BLUEZ, getId(adapter)))
97                 .withLabel("Bluetooth Interface " + adapter.getName())
98                 .withProperty(BlueZAdapterConstants.PROPERTY_ADDRESS, adapter.getAddress())
99                 .withRepresentationProperty(BlueZAdapterConstants.PROPERTY_ADDRESS).build();
100     }
101
102     private String getId(BluetoothAdapter adapter) {
103         return adapter.getDeviceName().replaceAll("[^a-zA-Z0-9_]", "");
104     }
105 }