]> git.basschouten.com Git - openhab-addons.git/blob
0f6cac6670f89210f522e9824e9801c2ba3fb423
[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.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.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;
39
40 /**
41  * The {@link OwDiscoveryService} implements the discovery service for the OneWire binding.
42  *
43  * @author Jan N. Klug - Initial contribution
44  */
45 @NonNullByDefault
46 public class OwDiscoveryService extends AbstractDiscoveryService implements ThingHandlerService {
47     private final Logger logger = LoggerFactory.getLogger(OwDiscoveryService.class);
48
49     private @Nullable OwserverBridgeHandler bridgeHandler;
50
51     Map<SensorId, OwDiscoveryItem> owDiscoveryItems = new HashMap<>();
52     Set<SensorId> associatedSensors = new HashSet<>();
53
54     public OwDiscoveryService() {
55         super(SUPPORTED_THING_TYPES, 60, false);
56         logger.debug("registering discovery service for {}", bridgeHandler);
57     }
58
59     private void scanDirectory(OwserverBridgeHandler bridgeHandler, String baseDirectory) {
60         ThingUID bridgeUID = bridgeHandler.getThing().getUID();
61
62         List<SensorId> directoryList;
63
64         logger.trace("scanning {} on bridge {}", baseDirectory, bridgeUID);
65         try {
66             directoryList = bridgeHandler.getDirectory(baseDirectory);
67         } catch (OwException e) {
68             logger.info("empty directory '{}' for {}", baseDirectory, bridgeUID);
69             return;
70         }
71
72         // find all valid sensors
73         for (SensorId directoryEntry : directoryList) {
74             try {
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);
79
80                     scanDirectory(bridgeHandler, owDiscoveryItem.getSensorId().getFullPath() + "/main/");
81                     scanDirectory(bridgeHandler, owDiscoveryItem.getSensorId().getFullPath() + "/aux/");
82                 } else {
83                     // add found sensor to list
84                     logger.trace("found sensor {} (type: {})", directoryEntry, owDiscoveryItem.getSensorType());
85
86                     owDiscoveryItems.put(owDiscoveryItem.getSensorId(), owDiscoveryItem);
87                     associatedSensors.addAll(owDiscoveryItem.getAssociatedSensorIds());
88                 }
89             } catch (OwException e) {
90                 logger.debug("error while scanning for sensors in directory {} on bridge {}: {}", baseDirectory,
91                         bridgeUID, e.getMessage());
92             }
93         }
94     }
95
96     @Override
97     public void startScan() {
98         OwserverBridgeHandler bridgeHandler = this.bridgeHandler;
99         if (bridgeHandler == null) {
100             logger.warn("bridgeHandler not found");
101             return;
102         }
103
104         ThingUID bridgeUID = bridgeHandler.getThing().getUID();
105
106         scanDirectory(bridgeHandler, "/");
107
108         // remove duplicates
109         owDiscoveryItems.entrySet().removeIf(s -> associatedSensors.contains(s.getKey()));
110
111         // make discovery results
112         for (OwDiscoveryItem owDiscoveryItem : owDiscoveryItems.values()) {
113             owDiscoveryItem.checkSensorType();
114             try {
115                 ThingTypeUID thingTypeUID = owDiscoveryItem.getThingTypeUID();
116
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());
121
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());
126
127                 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID)
128                         .withProperties(properties).withBridge(bridgeUID).withLabel(owDiscoveryItem.getLabel()).build();
129
130                 thingDiscovered(discoveryResult);
131             } catch (OwException e) {
132                 logger.info("sensor-id {}: {}", owDiscoveryItem.getSensorId(), e.getMessage());
133             }
134         }
135     }
136
137     @Override
138     protected synchronized void stopScan() {
139         removeOlderResults(getTimestampOfLastScan());
140         super.stopScan();
141     }
142
143     @Override
144     public void setThingHandler(ThingHandler thingHandler) {
145         if (thingHandler instanceof OwserverBridgeHandler) {
146             this.bridgeHandler = (OwserverBridgeHandler) thingHandler;
147         }
148     }
149
150     @Override
151     public @Nullable ThingHandler getThingHandler() {
152         return bridgeHandler;
153     }
154
155     @Override
156     public void deactivate() {
157         removeOlderResults(new Date().getTime());
158     }
159 }