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.modbus.discovery.internal;
16 import java.util.concurrent.CopyOnWriteArraySet;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.openhab.binding.modbus.discovery.ModbusDiscoveryParticipant;
20 import org.openhab.core.config.discovery.AbstractDiscoveryService;
21 import org.openhab.core.config.discovery.DiscoveryResult;
22 import org.openhab.core.config.discovery.DiscoveryService;
23 import org.openhab.core.thing.ThingTypeUID;
24 import org.osgi.service.component.annotations.Component;
25 import org.osgi.service.component.annotations.Reference;
26 import org.osgi.service.component.annotations.ReferenceCardinality;
27 import org.osgi.service.component.annotations.ReferencePolicy;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
33 * Discovery service for Modbus bridges.
35 * This service acts as a rendezvous point between the different Modbus endpoints and any
36 * bundles that implement auto discovery through an endpoint.
38 * New bridges (TCP or Serial Modbus endpoint) should register with this service. This is
39 * handled automatically by the ModbusEndpointDiscoveryService.
40 * Also any bundles that perform auto discovery should register a ModbusDiscoveryParticipant.
41 * This ModbusDiscoveryParticipants will be called by the service when
42 * a discovery scan is requested.
44 * @author Nagy Attila Gabor - initial contribution
47 @Component(service = DiscoveryService.class, configurationPid = "discovery.modbus")
49 public class ModbusDiscoveryService extends AbstractDiscoveryService {
51 private final Logger logger = LoggerFactory.getLogger(ModbusDiscoveryService.class);
53 // Set of services that support Modbus discovery
54 private final Set<ModbusThingHandlerDiscoveryService> services = new CopyOnWriteArraySet<>();
56 // Set of the registered participants
57 private final Set<ModbusDiscoveryParticipant> participants = new CopyOnWriteArraySet<>();
59 // Set of the supported thing types. This is a union of all the thing types
60 // supported by the registered discovery services.
61 private final Set<ThingTypeUID> supportedThingTypes = new CopyOnWriteArraySet<>();
63 private static final int SEARCH_TIME_SECS = 5;
66 * Constructor for the discovery service.
67 * Set up default parameters
69 public ModbusDiscoveryService() {
70 // No supported thing types by default
71 // Search time is for the visual reference
72 // Background discovery disabled by default
73 super(null, SEARCH_TIME_SECS, false);
78 * Begin a discovery scan over each endpoint
81 protected void startScan() {
82 logger.trace("ModbusDiscoveryService starting scan");
84 if (participants.isEmpty()) {
85 // There's no point on continuing if there are no participants at the moment
90 boolean scanStarted = false;
91 for (ModbusThingHandlerDiscoveryService service : services) {
92 scanStarted |= service.startScan(this);
100 * Interface to notify us when a handler has finished it's discovery process
102 protected void scanFinished() {
103 for (ModbusThingHandlerDiscoveryService service : services) {
104 if (service.scanInProgress()) {
108 logger.trace("All endpoints finished scanning, stopping scan");
113 * Real discovery is done by the ModbusDiscoveryParticipants
114 * They are executed in series for each Modbus endpoint by ModbusDiscoveryProcess
115 * instances. They call back this method when a thing has been discovered
118 protected void thingDiscovered(DiscoveryResult discoveryResult) {
119 super.thingDiscovered(discoveryResult);
123 * Returns the list of {@code Thing} types which are supported by the {@link DiscoveryService}.
125 * @return the list of Thing types which are supported by the discovery service
126 * (not null, could be empty)
129 public Set<ThingTypeUID> getSupportedThingTypes() {
130 return this.supportedThingTypes;
134 * This reference is used to register any new Modbus bridge with the discovery service
135 * Running bridges have a ModbusThingHandlerDiscoveryService connected
136 * which will be responsible for the discovery
138 * @param handler the Modbus bridge handler
140 @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
141 protected void addModbusEndpoint(ModbusThingHandlerDiscoveryService service) {
142 logger.trace("Received new handler: {}", service);
143 services.add(service);
147 * Remove an already registered thing handler discovery component
149 * @param handler the handler that has been removed
151 protected void removeModbusEndpoint(ModbusThingHandlerDiscoveryService service) {
152 logger.trace("Removed handler: {}", service);
153 services.remove(service);
157 * Register a discovery participant. This participant will be called
158 * with any new Modbus bridges that allow discovery
162 @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
163 protected void addModbusDiscoveryParticipant(ModbusDiscoveryParticipant participant) {
164 logger.trace("Received new participant: {}", participant);
165 participants.add(participant);
166 supportedThingTypes.addAll(participant.getSupportedThingTypeUIDs());
170 * Remove an already registered discovery participant
174 protected void removeModbusDiscoveryParticipant(ModbusDiscoveryParticipant participant) {
175 logger.trace("Removing participant: {}", participant);
176 supportedThingTypes.removeAll(participant.getSupportedThingTypeUIDs());
177 participants.remove(participant);
181 * Return the set of participants
183 * @return a set of the participants. Note: this is a copy of the original set
185 public Set<ModbusDiscoveryParticipant> getDiscoveryParticipants() {
186 return new CopyOnWriteArraySet<>(participants);