]> git.basschouten.com Git - openhab-addons.git/blob
a0e895940b08f481da0238cc36b4c5e16e6c7dda
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.discovery;
14
15 import java.util.Collections;
16
17 import org.openhab.binding.bluetooth.bluez.BlueZAdapterConstants;
18 import org.openhab.core.config.discovery.AbstractDiscoveryService;
19 import org.openhab.core.config.discovery.DiscoveryResult;
20 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
21 import org.openhab.core.config.discovery.DiscoveryService;
22 import org.openhab.core.thing.ThingUID;
23 import org.osgi.service.component.annotations.Component;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 import tinyb.BluetoothAdapter;
28 import tinyb.BluetoothManager;
29
30 /**
31  * This is a discovery service, which checks whether we are running on a Linux with a BlueZ stack.
32  * If this is the case, we create a bridge handler that provides Bluetooth access through BlueZ.
33  *
34  * @author Kai Kreuzer - Initial Contribution and API
35  * @author Hilbrand Bouwkamp - Moved background scan to actual background method
36  *
37  */
38 @Component(immediate = true, service = DiscoveryService.class, configurationPid = "discovery.bluetooth.bluez")
39 public class BlueZDiscoveryService extends AbstractDiscoveryService {
40
41     private final Logger logger = LoggerFactory.getLogger(BlueZDiscoveryService.class);
42
43     private BluetoothManager manager;
44
45     public BlueZDiscoveryService() {
46         super(Collections.singleton(BlueZAdapterConstants.THING_TYPE_BLUEZ), 1, true);
47     }
48
49     @Override
50     protected void startBackgroundDiscovery() {
51         startScan();
52     }
53
54     @Override
55     protected void startScan() {
56         try {
57             manager = BluetoothManager.getBluetoothManager();
58             manager.getAdapters().stream().map(this::createDiscoveryResult).forEach(this::thingDiscovered);
59         } catch (UnsatisfiedLinkError e) {
60             logger.debug("Not possible to initialize the BlueZ stack. ", e);
61             return;
62         } catch (RuntimeException e) {
63             // we do not get anything more specific from TinyB here
64             if (e.getMessage() != null && e.getMessage().contains("AccessDenied")) {
65                 logger.warn(
66                         "Cannot access BlueZ stack due to permission problems. Make sure that your OS user is part of the 'bluetooth' group of BlueZ.");
67             } else {
68                 logger.warn("Failed to scan for Bluetooth devices", e);
69             }
70         }
71     }
72
73     private DiscoveryResult createDiscoveryResult(BluetoothAdapter adapter) {
74         return DiscoveryResultBuilder.create(new ThingUID(BlueZAdapterConstants.THING_TYPE_BLUEZ, getId(adapter)))
75                 .withLabel("Bluetooth Interface " + adapter.getName())
76                 .withProperty(BlueZAdapterConstants.PROPERTY_ADDRESS, adapter.getAddress())
77                 .withRepresentationProperty(BlueZAdapterConstants.PROPERTY_ADDRESS).build();
78     }
79
80     private String getId(BluetoothAdapter adapter) {
81         return adapter.getInterfaceName().replaceAll("[^a-zA-Z0-9_]", "");
82     }
83 }