2 * Copyright (c) 2010-2021 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.souliss.internal.discovery;
15 import java.net.InetAddress;
17 import java.util.TreeMap;
18 import java.util.concurrent.ScheduledFuture;
19 import java.util.concurrent.TimeUnit;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.souliss.internal.SoulissBindingConstants;
24 import org.openhab.binding.souliss.internal.SoulissProtocolConstants;
25 import org.openhab.binding.souliss.internal.handler.SoulissGatewayHandler;
26 import org.openhab.core.config.discovery.AbstractDiscoveryService;
27 import org.openhab.core.config.discovery.DiscoveryResult;
28 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
29 import org.openhab.core.config.discovery.DiscoveryService;
30 import org.openhab.core.thing.ThingUID;
31 import org.openhab.core.thing.binding.ThingHandler;
32 import org.openhab.core.thing.binding.ThingHandlerService;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
37 * The {@link soulissHandlerFactory} is responsible for creating things and thingGeneric
40 * @author Tonino Fazio - Initial contribution
41 * @author Luca Calcaterra - Refactor for OH3
44 public class SoulissGatewayDiscovery extends AbstractDiscoveryService
45 implements DiscoverResult, DiscoveryService, ThingHandlerService {
46 private @Nullable ScheduledFuture<?> discoveryJob = null;
47 private final Logger logger = LoggerFactory.getLogger(SoulissGatewayDiscovery.class);
49 private @Nullable SoulissDiscoverJob soulissDiscoverRunnableClass = null;
51 private @Nullable SoulissGatewayHandler soulissGwHandler;
53 public SoulissGatewayDiscovery() {
54 super(SoulissBindingConstants.SUPPORTED_THING_TYPES_UIDS, SoulissBindingConstants.DISCOVERY_TIMEOUT_IN_SECONDS,
59 public void deactivate() {
64 * The {@link gatewayDetected} callback used to create the Gateway
67 public void gatewayDetected(InetAddress addr, String id) {
68 logger.debug("Souliss gateway found: {} ", addr.getHostName());
70 String label = "Souliss Gateway " + (Byte.parseByte(id) & 0xFF);
71 Map<String, Object> properties = new TreeMap<>();
72 properties.put(SoulissBindingConstants.CONFIG_IP_ADDRESS, addr.getHostAddress());
73 var gatewayUID = new ThingUID(SoulissBindingConstants.GATEWAY_THING_TYPE,
74 Integer.toString((Byte.parseByte(id) & 0xFF)));
75 var discoveryResult = DiscoveryResultBuilder.create(gatewayUID).withLabel(label)
76 .withRepresentationProperty(SoulissBindingConstants.CONFIG_IP_ADDRESS).withProperties(properties)
78 thingDiscovered(discoveryResult);
82 protected void startScan() {
83 logger.debug("Starting Scan Service");
85 // create discovery class
86 if (soulissDiscoverRunnableClass == null) {
87 soulissDiscoverRunnableClass = new SoulissDiscoverJob(this.soulissGwHandler);
89 // send command for gw struct (typicals).. must be not soo much quick..
90 discoveryJob = scheduler.scheduleWithFixedDelay(soulissDiscoverRunnableClass, 2,
91 SoulissBindingConstants.DISCOVERY_RESEND_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
92 logger.debug("Start Discovery Job");
97 protected synchronized void stopScan() {
98 ScheduledFuture<?> localDiscoveryJob = this.discoveryJob;
99 if (localDiscoveryJob != null) {
100 localDiscoveryJob.cancel(false);
101 soulissDiscoverRunnableClass = null;
102 logger.debug("Discovery Job Stopped");
108 public void thingDetectedActionMessages(String topicNumber, String sTopicVariant) {
109 ThingUID thingUID = null;
111 DiscoveryResult discoveryResult;
112 String sNodeID = topicNumber + SoulissBindingConstants.UUID_NODE_SLOT_SEPARATOR + sTopicVariant;
114 var localGwHandler = this.soulissGwHandler;
115 if (localGwHandler != null) {
116 var gatewayUID = localGwHandler.getThing().getUID();
117 thingUID = new ThingUID(SoulissBindingConstants.TOPICS_THING_TYPE, gatewayUID, sNodeID);
118 label = "Topic. Number: " + topicNumber + ", Variant: " + sTopicVariant;
120 discoveryResult = DiscoveryResultBuilder.create(thingUID).withLabel(label)
121 .withProperty("number", topicNumber).withProperty("variant", sTopicVariant)
122 .withRepresentationProperty("number").withBridge(gatewayUID).build();
123 thingDiscovered(discoveryResult);
128 public void thingDetectedTypicals(byte lastByteGatewayIP, byte typical, byte node, byte slot) {
129 ThingUID thingUID = null;
131 DiscoveryResult discoveryResult;
132 var gwHandler = this.soulissGwHandler;
133 if ((gwHandler != null) && (lastByteGatewayIP == (byte) Integer
134 .parseInt(gwHandler.getGwConfig().gatewayLanAddress.split("\\.")[3]))) {
135 String sNodeId = node + SoulissBindingConstants.UUID_NODE_SLOT_SEPARATOR + slot;
137 ThingUID gatewayUID = gwHandler.getThing().getUID();
138 var slotLabel = "slot";
141 case SoulissProtocolConstants.SOULISS_T11:
142 thingUID = new ThingUID(SoulissBindingConstants.T11_THING_TYPE, gatewayUID, sNodeId);
143 label = "T11: node " + node + slotLabel + slot;
145 case SoulissProtocolConstants.SOULISS_T12:
146 thingUID = new ThingUID(SoulissBindingConstants.T12_THING_TYPE, gatewayUID, sNodeId);
147 label = "T12: node " + node + slotLabel + slot;
149 case SoulissProtocolConstants.SOULISS_T13:
150 thingUID = new ThingUID(SoulissBindingConstants.T13_THING_TYPE, gatewayUID, sNodeId);
151 label = "T13: node " + node + slotLabel + slot;
153 case SoulissProtocolConstants.SOULISS_T14:
154 thingUID = new ThingUID(SoulissBindingConstants.T14_THING_TYPE, gatewayUID, sNodeId);
155 label = "T14: node " + node + slotLabel + slot;
157 case SoulissProtocolConstants.SOULISS_T16:
158 thingUID = new ThingUID(SoulissBindingConstants.T16_THING_TYPE, gatewayUID, sNodeId);
159 label = "T16: node " + node + slotLabel + slot;
161 case SoulissProtocolConstants.SOULISS_T18:
162 thingUID = new ThingUID(SoulissBindingConstants.T18_THING_TYPE, gatewayUID, sNodeId);
163 label = "T18: node " + node + slotLabel + slot;
165 case SoulissProtocolConstants.SOULISS_T19:
166 thingUID = new ThingUID(SoulissBindingConstants.T19_THING_TYPE, gatewayUID, sNodeId);
167 label = "T19: node " + node + slotLabel + slot;
169 case SoulissProtocolConstants.SOULISS_T1A:
170 thingUID = new ThingUID(SoulissBindingConstants.T1A_THING_TYPE, gatewayUID, sNodeId);
171 label = "T1A: node " + node + slotLabel + slot;
173 case SoulissProtocolConstants.SOULISS_T21:
174 thingUID = new ThingUID(SoulissBindingConstants.T21_THING_TYPE, gatewayUID, sNodeId);
175 label = "T21: node " + node + slotLabel + slot;
177 case SoulissProtocolConstants.SOULISS_T22:
178 thingUID = new ThingUID(SoulissBindingConstants.T22_THING_TYPE, gatewayUID, sNodeId);
179 label = "T22: node " + node + slotLabel + slot;
181 case SoulissProtocolConstants.SOULISS_T41_ANTITHEFT_MAIN:
182 thingUID = new ThingUID(SoulissBindingConstants.T41_THING_TYPE, gatewayUID, sNodeId);
183 label = "T41: node " + node + slotLabel + slot;
185 case SoulissProtocolConstants.SOULISS_T42_ANTITHEFT_PEER:
186 thingUID = new ThingUID(SoulissBindingConstants.T42_THING_TYPE, gatewayUID, sNodeId);
187 label = "T42: node " + node + slotLabel + slot;
189 case SoulissProtocolConstants.SOULISS_T31:
190 thingUID = new ThingUID(SoulissBindingConstants.T31_THING_TYPE, gatewayUID, sNodeId);
191 label = "T31: node " + node + slotLabel + slot;
193 case SoulissProtocolConstants.SOULISS_T52_TEMPERATURE_SENSOR:
194 thingUID = new ThingUID(SoulissBindingConstants.T52_THING_TYPE, gatewayUID, sNodeId);
195 label = "T52: node " + node + slotLabel + slot;
197 case SoulissProtocolConstants.SOULISS_T53_HUMIDITY_SENSOR:
198 thingUID = new ThingUID(SoulissBindingConstants.T53_THING_TYPE, gatewayUID, sNodeId);
199 label = "T53: node " + node + slotLabel + slot;
201 case SoulissProtocolConstants.SOULISS_T54_LUX_SENSOR:
202 thingUID = new ThingUID(SoulissBindingConstants.T54_THING_TYPE, gatewayUID, sNodeId);
203 label = "T54: node " + node + slotLabel + slot;
205 case SoulissProtocolConstants.SOULISS_T55_VOLTAGE_SENSOR:
206 thingUID = new ThingUID(SoulissBindingConstants.T55_THING_TYPE, gatewayUID, sNodeId);
207 label = "T55: node " + node + slotLabel + slot;
209 case SoulissProtocolConstants.SOULISS_T56_CURRENT_SENSOR:
210 thingUID = new ThingUID(SoulissBindingConstants.T56_THING_TYPE, gatewayUID, sNodeId);
211 label = "T56: node " + node + slotLabel + slot;
213 case SoulissProtocolConstants.SOULISS_T57_POWER_SENSOR:
214 thingUID = new ThingUID(SoulissBindingConstants.T57_THING_TYPE, gatewayUID, sNodeId);
215 label = "T57: node " + node + slotLabel + slot;
217 case SoulissProtocolConstants.SOULISS_T61:
218 thingUID = new ThingUID(SoulissBindingConstants.T61_THING_TYPE, gatewayUID, sNodeId);
219 label = "T61: node " + node + slotLabel + slot;
221 case SoulissProtocolConstants.SOULISS_T62_TEMPERATURE_SENSOR:
222 thingUID = new ThingUID(SoulissBindingConstants.T62_THING_TYPE, gatewayUID, sNodeId);
223 label = "T62: node " + node + slotLabel + slot;
225 case SoulissProtocolConstants.SOULISS_T63_HUMIDITY_SENSOR:
226 thingUID = new ThingUID(SoulissBindingConstants.T63_THING_TYPE, gatewayUID, sNodeId);
227 label = "T63: node " + node + slotLabel + slot;
229 case SoulissProtocolConstants.SOULISS_T64_LUX_SENSOR:
230 thingUID = new ThingUID(SoulissBindingConstants.T64_THING_TYPE, gatewayUID, sNodeId);
231 label = "T64: node " + node + slotLabel + slot;
233 case SoulissProtocolConstants.SOULISS_T65_VOLTAGE_SENSOR:
234 thingUID = new ThingUID(SoulissBindingConstants.T65_THING_TYPE, gatewayUID, sNodeId);
235 label = "T65: node " + node + slotLabel + slot;
237 case SoulissProtocolConstants.SOULISS_T66_CURRENT_SENSOR:
238 thingUID = new ThingUID(SoulissBindingConstants.T66_THING_TYPE, gatewayUID, sNodeId);
239 label = "T66: node " + node + slotLabel + slot;
241 case SoulissProtocolConstants.SOULISS_T67_POWER_SENSOR:
242 thingUID = new ThingUID(SoulissBindingConstants.T67_THING_TYPE, gatewayUID, sNodeId);
243 label = "T67: node " + node + slotLabel + slot;
246 logger.debug("no supported things found ...");
249 if (thingUID != null) {
250 label = "[" + gwHandler.getThing().getUID().getAsString() + "] " + label;
251 var uniqueId = "N" + Byte.toString(node) + "S" + Byte.toString(slot);
252 discoveryResult = DiscoveryResultBuilder.create(thingUID).withLabel(label)
253 .withProperty(SoulissBindingConstants.PROPERTY_NODE, node)
254 .withProperty(SoulissBindingConstants.PROPERTY_SLOT, slot)
255 .withProperty(SoulissBindingConstants.PROPERTY_UNIQUEID, uniqueId)
256 .withRepresentationProperty(SoulissBindingConstants.PROPERTY_UNIQUEID)
257 .withBridge(gwHandler.getThing().getUID()).build();
258 thingDiscovered(discoveryResult);
259 gwHandler.setThereIsAThingDetection();
265 public void setThingHandler(ThingHandler handler) {
266 if (handler instanceof SoulissGatewayHandler) {
267 var localGwHandler = this.soulissGwHandler;
268 localGwHandler = (SoulissGatewayHandler) handler;
269 localGwHandler.discoverResult = this;
274 public @Nullable ThingHandler getThingHandler() {
275 return soulissGwHandler;