]> git.basschouten.com Git - openhab-addons.git/blob
3312659dc5bbadd67c9ad457917fdbb95753fca2
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.onewire.internal.discovery;
14
15 import static org.openhab.binding.onewire.internal.OwBindingConstants.*;
16
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Set;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.openhab.binding.onewire.internal.OwException;
26 import org.openhab.binding.onewire.internal.SensorId;
27 import org.openhab.binding.onewire.internal.device.OwSensorType;
28 import org.openhab.binding.onewire.internal.handler.OwserverBridgeHandler;
29 import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService;
30 import org.openhab.core.config.discovery.DiscoveryResult;
31 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
32 import org.openhab.core.thing.ThingTypeUID;
33 import org.openhab.core.thing.ThingUID;
34 import org.osgi.service.component.annotations.Component;
35 import org.osgi.service.component.annotations.ServiceScope;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * The {@link OwDiscoveryService} implements the discovery service for the OneWire binding.
41  *
42  * @author Jan N. Klug - Initial contribution
43  */
44 @Component(scope = ServiceScope.PROTOTYPE, service = OwDiscoveryService.class)
45 @NonNullByDefault
46 public class OwDiscoveryService extends AbstractThingHandlerDiscoveryService<OwserverBridgeHandler> {
47     private final Logger logger = LoggerFactory.getLogger(OwDiscoveryService.class);
48
49     Map<SensorId, OwDiscoveryItem> owDiscoveryItems = new HashMap<>();
50     Set<SensorId> associatedSensors = new HashSet<>();
51
52     public OwDiscoveryService() {
53         super(OwserverBridgeHandler.class, SUPPORTED_THING_TYPES, 60, false);
54     }
55
56     private void scanDirectory(OwserverBridgeHandler bridgeHandler, String baseDirectory) {
57         ThingUID bridgeUID = bridgeHandler.getThing().getUID();
58
59         List<SensorId> directoryList;
60
61         logger.trace("scanning {} on bridge {}", baseDirectory, bridgeUID);
62         try {
63             directoryList = bridgeHandler.getDirectory(baseDirectory);
64         } catch (OwException e) {
65             logger.info("empty directory '{}' for {}", baseDirectory, bridgeUID);
66             return;
67         }
68
69         // find all valid sensors
70         for (SensorId directoryEntry : directoryList) {
71             try {
72                 OwDiscoveryItem owDiscoveryItem = new OwDiscoveryItem(bridgeHandler, directoryEntry);
73                 if (owDiscoveryItem.getSensorType() == OwSensorType.DS2409) {
74                     // scan hub sub-directories
75                     logger.trace("found hub {}, scanning sub-directories", directoryEntry);
76
77                     scanDirectory(bridgeHandler, owDiscoveryItem.getSensorId().getFullPath() + "/main/");
78                     scanDirectory(bridgeHandler, owDiscoveryItem.getSensorId().getFullPath() + "/aux/");
79                 } else {
80                     // add found sensor to list
81                     logger.trace("found sensor {} (type: {})", directoryEntry, owDiscoveryItem.getSensorType());
82
83                     owDiscoveryItems.put(owDiscoveryItem.getSensorId(), owDiscoveryItem);
84                     associatedSensors.addAll(owDiscoveryItem.getAssociatedSensorIds());
85                 }
86             } catch (OwException e) {
87                 logger.debug("error while scanning for sensors in directory {} on bridge {}: {}", baseDirectory,
88                         bridgeUID, e.getMessage());
89             }
90         }
91     }
92
93     @Override
94     public void startScan() {
95         ThingUID bridgeUID = thingHandler.getThing().getUID();
96
97         scanDirectory(thingHandler, "/");
98
99         // remove duplicates
100         owDiscoveryItems.entrySet().removeIf(s -> associatedSensors.contains(s.getKey()));
101
102         // make discovery results
103         for (OwDiscoveryItem owDiscoveryItem : owDiscoveryItems.values()) {
104             owDiscoveryItem.checkSensorType();
105             try {
106                 ThingTypeUID thingTypeUID = owDiscoveryItem.getThingTypeUID();
107
108                 String normalizedId = owDiscoveryItem.getNormalizedSensorId();
109                 ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, normalizedId);
110                 logger.debug("created thing UID {} for sensor {}, type {}", thingUID, owDiscoveryItem.getSensorId(),
111                         owDiscoveryItem.getSensorType());
112
113                 Map<String, Object> properties = new HashMap<>();
114                 properties.put(PROPERTY_MODELID, owDiscoveryItem.getSensorType().toString());
115                 properties.put(PROPERTY_VENDOR, owDiscoveryItem.getVendor());
116                 properties.put(CONFIG_ID, owDiscoveryItem.getSensorId().getFullPath());
117
118                 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID)
119                         .withProperties(properties).withBridge(bridgeUID).withLabel(owDiscoveryItem.getLabel()).build();
120
121                 thingDiscovered(discoveryResult);
122             } catch (OwException e) {
123                 logger.info("sensor-id {}: {}", owDiscoveryItem.getSensorId(), e.getMessage());
124             }
125         }
126     }
127
128     @Override
129     protected synchronized void stopScan() {
130         removeOlderResults(getTimestampOfLastScan());
131         super.stopScan();
132     }
133
134     @Override
135     public void dispose() {
136         super.dispose();
137         removeOlderResults(new Date().getTime());
138     }
139 }