]> git.basschouten.com Git - openhab-addons.git/blob
5226b6f1db78f6aa7abe4c73f5af75abf899ec58
[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.rfxcom.internal.discovery;
14
15 import java.io.IOException;
16 import java.util.HashMap;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.concurrent.ScheduledFuture;
20 import java.util.concurrent.TimeUnit;
21
22 import org.openhab.binding.rfxcom.internal.RFXComBindingConstants;
23 import org.openhab.binding.rfxcom.internal.config.RFXComBridgeConfiguration;
24 import org.openhab.core.config.discovery.AbstractDiscoveryService;
25 import org.openhab.core.config.discovery.DiscoveryResult;
26 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
27 import org.openhab.core.config.discovery.DiscoveryService;
28 import org.openhab.core.i18n.LocaleProvider;
29 import org.openhab.core.i18n.TranslationProvider;
30 import org.openhab.core.thing.ThingTypeUID;
31 import org.openhab.core.thing.ThingUID;
32 import org.osgi.service.component.annotations.Activate;
33 import org.osgi.service.component.annotations.Component;
34 import org.osgi.service.component.annotations.Reference;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import jd2xx.JD2XX;
39
40 /**
41  * The {@link RFXComBridgeDiscovery} is responsible for discovering new RFXCOM
42  * transceivers.
43  *
44  * @author Pauli Anttila - Initial contribution
45  *
46  */
47 @Component(service = DiscoveryService.class, configurationPid = "discovery.rfxcom")
48 public class RFXComBridgeDiscovery extends AbstractDiscoveryService {
49     private static final long REFRESH_INTERVAL_IN_SECONDS = 600;
50
51     private final Logger logger = LoggerFactory.getLogger(RFXComBridgeDiscovery.class);
52
53     private boolean unsatisfiedLinkErrorLogged = false;
54
55     private ScheduledFuture<?> discoveryJob;
56
57     @Activate
58     public RFXComBridgeDiscovery(@Reference TranslationProvider i18nProvider,
59             @Reference LocaleProvider localeProvider) {
60         super(RFXComBindingConstants.DISCOVERABLE_BRIDGE_THING_TYPES_UIDS, 10, false);
61         this.i18nProvider = i18nProvider;
62         this.localeProvider = localeProvider;
63     }
64
65     @Override
66     public Set<ThingTypeUID> getSupportedThingTypes() {
67         return RFXComBindingConstants.DISCOVERABLE_BRIDGE_THING_TYPES_UIDS;
68     }
69
70     @Override
71     public void startScan() {
72         logger.debug("Start discovery scan for RFXCOM transceivers");
73         discoverRfxcom();
74     }
75
76     @Override
77     protected void startBackgroundDiscovery() {
78         logger.debug("Start background discovery for RFXCOM transceivers");
79         discoveryJob = scheduler.scheduleWithFixedDelay(this::discoverRfxcom, 0, REFRESH_INTERVAL_IN_SECONDS,
80                 TimeUnit.SECONDS);
81     }
82
83     @Override
84     protected void stopBackgroundDiscovery() {
85         logger.debug("Stop background discovery for RFXCOM transceivers");
86         if (discoveryJob != null && !discoveryJob.isCancelled()) {
87             discoveryJob.cancel(true);
88             discoveryJob = null;
89         }
90     }
91
92     private synchronized void discoverRfxcom() {
93         try {
94             JD2XX jd2xx = new JD2XX();
95             logger.debug("Discovering RFXCOM transceiver devices by JD2XX version {}", jd2xx.getLibraryVersion());
96             String[] devDescriptions = (String[]) jd2xx.listDevicesByDescription();
97             String[] devSerialNumbers = (String[]) jd2xx.listDevicesBySerialNumber();
98             logger.debug("Discovered {} FTDI device(s)", devDescriptions.length);
99
100             for (int i = 0; i < devSerialNumbers.length; ++i) {
101                 if (devDescriptions.length > 0) {
102                     switch (devDescriptions[i]) {
103                         case RFXComBindingConstants.BRIDGE_TYPE_RFXTRX433:
104                             addBridge(RFXComBindingConstants.BRIDGE_RFXTRX443, devSerialNumbers[i]);
105                             break;
106                         case RFXComBindingConstants.BRIDGE_TYPE_RFXTRX315:
107                             addBridge(RFXComBindingConstants.BRIDGE_RFXTRX315, devSerialNumbers[i]);
108                             break;
109                         case RFXComBindingConstants.BRIDGE_TYPE_RFXREC433:
110                             addBridge(RFXComBindingConstants.BRIDGE_RFXREC443, devSerialNumbers[i]);
111                             break;
112                         default:
113                             logger.trace("Ignore unknown device '{}'", devDescriptions[i]);
114                     }
115                 }
116             }
117
118             logger.debug("Discovery done");
119         } catch (IOException e) {
120             logger.error("Error occurred during discovery", e);
121         } catch (UnsatisfiedLinkError e) {
122             if (unsatisfiedLinkErrorLogged) {
123                 logger.debug(
124                         "Error occurred when trying to load native library for OS '{}' version '{}', processor '{}'",
125                         System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch"),
126                         e);
127             } else {
128                 logger.error(
129                         "Error occurred when trying to load native library for OS '{}' version '{}', processor '{}'",
130                         System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch"),
131                         e);
132                 unsatisfiedLinkErrorLogged = true;
133             }
134         }
135     }
136
137     private void addBridge(ThingTypeUID bridgeType, String bridgeId) {
138         logger.debug("Discovered RFXCOM transceiver, bridgeType='{}', bridgeId='{}'", bridgeType, bridgeId);
139
140         Map<String, Object> properties = new HashMap<>();
141         properties.put(RFXComBridgeConfiguration.BRIDGE_ID, bridgeId);
142
143         ThingUID uid = new ThingUID(bridgeType, bridgeId);
144         DiscoveryResult result = DiscoveryResultBuilder.create(uid).withProperties(properties)
145                 .withLabel("@text/discovery.bridge.label").build();
146         thingDiscovered(result);
147     }
148 }