]> git.basschouten.com Git - openhab-addons.git/blob
07484151cdebd4412d2e00c248bf5f05c8fed3cf
[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.jeelink.internal.discovery;
14
15 import static org.openhab.binding.jeelink.internal.JeeLinkBindingConstants.*;
16
17 import java.util.List;
18 import java.util.concurrent.atomic.AtomicBoolean;
19
20 import org.openhab.binding.jeelink.internal.JeeLinkHandler;
21 import org.openhab.binding.jeelink.internal.Reading;
22 import org.openhab.binding.jeelink.internal.ReadingHandler;
23 import org.openhab.binding.jeelink.internal.SensorDefinition;
24 import org.openhab.binding.jeelink.internal.config.JeeLinkSensorConfig;
25 import org.openhab.core.config.discovery.AbstractDiscoveryService;
26 import org.openhab.core.config.discovery.DiscoveryResult;
27 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
28 import org.openhab.core.thing.Thing;
29 import org.openhab.core.thing.ThingUID;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * Discovery service for sensors connected to a JeeLink USB Receiver.
35  *
36  * @author Volker Bier - Initial contribution
37  */
38 public class SensorDiscoveryService extends AbstractDiscoveryService implements ReadingHandler<Reading> {
39     private static final int DISCOVER_TIMEOUT_SECONDS = 30;
40
41     private final Logger logger = LoggerFactory.getLogger(SensorDiscoveryService.class);
42
43     JeeLinkHandler bridge;
44     AtomicBoolean capture = new AtomicBoolean();
45
46     /**
47      * Creates the discovery service for the given handler and converter.
48      */
49     public SensorDiscoveryService(JeeLinkHandler jeeLinkHandler) {
50         super(SUPPORTED_SENSOR_THING_TYPES_UIDS, DISCOVER_TIMEOUT_SECONDS, true);
51
52         bridge = jeeLinkHandler;
53     }
54
55     @Override
56     protected synchronized void startScan() {
57         if (!capture.getAndSet(true)) {
58             logger.debug("discovery started for bridge {}", bridge.getThing().getUID());
59
60             // start listening for new sensor values
61             bridge.addReadingHandler(this);
62             capture.set(true);
63         }
64     }
65
66     @Override
67     protected void startBackgroundDiscovery() {
68         startScan();
69     }
70
71     @Override
72     protected synchronized void stopScan() {
73         if (capture.getAndSet(false)) {
74             bridge.removeReadingHandler(this);
75             logger.debug("discovery stopped for bridge {}", bridge.getThing().getUID());
76         }
77     }
78
79     @Override
80     protected void stopBackgroundDiscovery() {
81         stopScan();
82     }
83
84     private boolean idExistsAtBridge(String id) {
85         List<Thing> existingThings = bridge.getThing().getThings();
86         boolean idExists = false;
87         for (Thing t : existingThings) {
88             idExists = idExists || t.getUID().getId().equals(id);
89         }
90         return idExists;
91     }
92
93     @Override
94     public void handleReading(Reading reading) {
95         final String id = reading.getSensorId();
96
97         List<Thing> existingThings = bridge.getThing().getThings();
98         boolean sensorThingExists = false;
99
100         for (Thing t : existingThings) {
101             sensorThingExists = sensorThingExists
102                     || id.equals(t.getConfiguration().as(JeeLinkSensorConfig.class).sensorId);
103         }
104
105         ThingUID bridgeUID = bridge.getThing().getUID();
106
107         if (!sensorThingExists) {
108             SensorDefinition<?> def = SensorDefinition.getSensorDefinition(reading);
109             logger.debug("discovery for bridge {} found unknown sensor of type {} with id {}", bridgeUID,
110                     def.getThingTypeUID(), id);
111
112             boolean idExists = idExistsAtBridge(id);
113             String newId = id;
114
115             if (idExists) {
116                 logger.debug("bridge {} already has a connected sensor with thing id {}", bridgeUID, id);
117
118                 int idx = 1;
119                 while (idExists) {
120                     newId = id + "-" + idx++;
121                     idExists = idExistsAtBridge(newId);
122                 }
123
124                 logger.debug("Bridge {} uses thing id {} instead of {}", bridgeUID, newId, id);
125             }
126
127             ThingUID sensorThing = new ThingUID(def.getThingTypeUID(), bridgeUID, newId);
128
129             DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(sensorThing).withLabel(def.getName())
130                     .withBridge(bridgeUID).withRepresentationProperty("id").withProperty(PROPERTY_SENSOR_ID, id)
131                     .build();
132             thingDiscovered(discoveryResult);
133         } else {
134             logger.debug("discovery for bridge {} found already known sensor id {}", bridgeUID, id);
135         }
136     }
137
138     @Override
139     public Class<Reading> getReadingClass() {
140         return Reading.class;
141     }
142
143     @Override
144     public String getSensorType() {
145         return SensorDefinition.ALL_TYPE;
146     }
147 }