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.vitotronic.internal.discovery;
15 import java.io.IOException;
16 import java.net.DatagramPacket;
17 import java.net.DatagramSocket;
18 import java.net.InetAddress;
19 import java.util.HashMap;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.openhab.binding.vitotronic.internal.VitotronicBindingConstants;
24 import org.openhab.core.config.discovery.AbstractDiscoveryService;
25 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
26 import org.openhab.core.config.discovery.DiscoveryService;
27 import org.openhab.core.thing.ThingUID;
28 import org.osgi.service.component.annotations.Component;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 * The {@link VitotronicBridgeDiscovery} class handles the discovery of optolink adapter
34 * with broadcasting and put it to inbox, if found.
37 * @author Stefan Andres - Initial contribution
40 @Component(service = DiscoveryService.class, configurationPid = "discovery.vitotronic")
41 public class VitotronicBridgeDiscovery extends AbstractDiscoveryService {
43 private int adapterPort = 31113;
45 private final Logger logger = LoggerFactory.getLogger(VitotronicBridgeDiscovery.class);
47 public VitotronicBridgeDiscovery() throws IllegalArgumentException {
48 super(VitotronicBindingConstants.SUPPORTED_BRIDGE_THING_TYPES_UIDS, 15, false);
52 protected void startScan() {
53 logger.trace("Start discovery of Vitotronic Optolink Adapter (VOP)");
54 adapterPort = VitotronicBindingConstants.BROADCAST_PORT;
55 scheduler.execute(searchRunnable);
58 // Runnable for search adapter
60 private Runnable searchRunnable = () -> {
61 logger.trace("Start adapter discovery ");
62 logger.debug("Send broadcast message");
63 try (DatagramSocket localSocket = new DatagramSocket()) {
64 localSocket.setBroadcast(true);
65 localSocket.setSoTimeout(10000); // Listen 10 seconds
67 String broadcastMsg = VitotronicBindingConstants.BROADCAST_MESSAGE + "*";
68 byte[] sendData = broadcastMsg.getBytes();
70 DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
71 InetAddress.getByName("255.255.255.255"), adapterPort);
72 localSocket.send(sendPacket);
74 byte[] receiveBuffer = new byte[255];
78 DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
79 localSocket.receive(receivePacket);
80 String receiveMessage = new String(receivePacket.getData()).trim();
81 String receiveIP = receivePacket.getAddress().getHostAddress();
82 int receivePort = receivePacket.getPort();
83 logger.debug("Received Message: {} ", receiveMessage);
84 logger.debug("Received from Host: {}", receiveIP);
85 logger.debug("Received from Port: {}", receivePort);
87 if (receiveMessage.startsWith(VitotronicBindingConstants.BROADCAST_MESSAGE)) {
89 String adapterID = receiveMessage.substring(VitotronicBindingConstants.BROADCAST_MESSAGE.length())
91 addAdapter(receiveIP, receivePort, adapterID);
93 } catch (IOException e) {
94 logger.debug("No optolink adapter found!");
98 private void addAdapter(String remoteIP, int remotePort, String adapterID) {
99 Map<String, Object> properties = new HashMap<>(3);
100 properties.put(VitotronicBindingConstants.IP_ADDRESS, remoteIP);
101 properties.put(VitotronicBindingConstants.PORT, remotePort);
102 properties.put(VitotronicBindingConstants.ADAPTER_ID, adapterID);
104 ThingUID uid = new ThingUID(VitotronicBindingConstants.THING_TYPE_UID_BRIDGE, adapterID);
105 thingDiscovered(DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(adapterID).build());