2 * Copyright (c) 2010-2023 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.onewire.internal.discovery;
15 import static org.openhab.binding.onewire.internal.OwBindingConstants.*;
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.onewire.internal.OwException;
27 import org.openhab.binding.onewire.internal.SensorId;
28 import org.openhab.binding.onewire.internal.device.OwSensorType;
29 import org.openhab.binding.onewire.internal.handler.OwserverBridgeHandler;
30 import org.openhab.core.config.discovery.AbstractDiscoveryService;
31 import org.openhab.core.config.discovery.DiscoveryResult;
32 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
33 import org.openhab.core.thing.ThingTypeUID;
34 import org.openhab.core.thing.ThingUID;
35 import org.openhab.core.thing.binding.ThingHandler;
36 import org.openhab.core.thing.binding.ThingHandlerService;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
41 * The {@link OwDiscoveryService} implements the discovery service for the OneWire binding.
43 * @author Jan N. Klug - Initial contribution
46 public class OwDiscoveryService extends AbstractDiscoveryService implements ThingHandlerService {
47 private final Logger logger = LoggerFactory.getLogger(OwDiscoveryService.class);
49 private @Nullable OwserverBridgeHandler bridgeHandler;
51 Map<SensorId, OwDiscoveryItem> owDiscoveryItems = new HashMap<>();
52 Set<SensorId> associatedSensors = new HashSet<>();
54 public OwDiscoveryService() {
55 super(SUPPORTED_THING_TYPES, 60, false);
56 logger.debug("registering discovery service for {}", bridgeHandler);
59 private void scanDirectory(OwserverBridgeHandler bridgeHandler, String baseDirectory) {
60 ThingUID bridgeUID = bridgeHandler.getThing().getUID();
62 List<SensorId> directoryList;
64 logger.trace("scanning {} on bridge {}", baseDirectory, bridgeUID);
66 directoryList = bridgeHandler.getDirectory(baseDirectory);
67 } catch (OwException e) {
68 logger.info("empty directory '{}' for {}", baseDirectory, bridgeUID);
72 // find all valid sensors
73 for (SensorId directoryEntry : directoryList) {
75 OwDiscoveryItem owDiscoveryItem = new OwDiscoveryItem(bridgeHandler, directoryEntry);
76 if (owDiscoveryItem.getSensorType() == OwSensorType.DS2409) {
77 // scan hub sub-directories
78 logger.trace("found hub {}, scanning sub-directories", directoryEntry);
80 scanDirectory(bridgeHandler, owDiscoveryItem.getSensorId().getFullPath() + "/main/");
81 scanDirectory(bridgeHandler, owDiscoveryItem.getSensorId().getFullPath() + "/aux/");
83 // add found sensor to list
84 logger.trace("found sensor {} (type: {})", directoryEntry, owDiscoveryItem.getSensorType());
86 owDiscoveryItems.put(owDiscoveryItem.getSensorId(), owDiscoveryItem);
87 associatedSensors.addAll(owDiscoveryItem.getAssociatedSensorIds());
89 } catch (OwException e) {
90 logger.debug("error while scanning for sensors in directory {} on bridge {}: {}", baseDirectory,
91 bridgeUID, e.getMessage());
97 public void startScan() {
98 OwserverBridgeHandler bridgeHandler = this.bridgeHandler;
99 if (bridgeHandler == null) {
100 logger.warn("bridgeHandler not found");
104 ThingUID bridgeUID = bridgeHandler.getThing().getUID();
106 scanDirectory(bridgeHandler, "/");
109 owDiscoveryItems.entrySet().removeIf(s -> associatedSensors.contains(s.getKey()));
111 // make discovery results
112 for (OwDiscoveryItem owDiscoveryItem : owDiscoveryItems.values()) {
113 owDiscoveryItem.checkSensorType();
115 ThingTypeUID thingTypeUID = owDiscoveryItem.getThingTypeUID();
117 String normalizedId = owDiscoveryItem.getNormalizedSensorId();
118 ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, normalizedId);
119 logger.debug("created thing UID {} for sensor {}, type {}", thingUID, owDiscoveryItem.getSensorId(),
120 owDiscoveryItem.getSensorType());
122 Map<String, Object> properties = new HashMap<>();
123 properties.put(PROPERTY_MODELID, owDiscoveryItem.getSensorType().toString());
124 properties.put(PROPERTY_VENDOR, owDiscoveryItem.getVendor());
125 properties.put(CONFIG_ID, owDiscoveryItem.getSensorId().getFullPath());
127 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID)
128 .withProperties(properties).withBridge(bridgeUID).withLabel(owDiscoveryItem.getLabel()).build();
130 thingDiscovered(discoveryResult);
131 } catch (OwException e) {
132 logger.info("sensor-id {}: {}", owDiscoveryItem.getSensorId(), e.getMessage());
138 protected synchronized void stopScan() {
139 removeOlderResults(getTimestampOfLastScan());
144 public void setThingHandler(ThingHandler thingHandler) {
145 if (thingHandler instanceof OwserverBridgeHandler) {
146 this.bridgeHandler = (OwserverBridgeHandler) thingHandler;
151 public @Nullable ThingHandler getThingHandler() {
152 return bridgeHandler;
156 public void deactivate() {
157 removeOlderResults(new Date().getTime());