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.pulseaudio.internal.discovery;
15 import java.io.IOException;
16 import java.net.Socket;
17 import java.util.HashMap;
21 import javax.jmdns.ServiceInfo;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.pulseaudio.internal.PulseaudioBindingConstants;
26 import org.openhab.binding.pulseaudio.internal.handler.PulseaudioBridgeHandler;
27 import org.openhab.core.config.discovery.DiscoveryResult;
28 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
29 import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
30 import org.openhab.core.thing.ThingTypeUID;
31 import org.openhab.core.thing.ThingUID;
32 import org.osgi.service.component.annotations.Component;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
37 * The {@link PulseaudioDiscoveryParticipant} is responsible processing the
38 * results of searches for mDNS services of type _pulse-server._tcp.local.
40 * @author Tobias Bräutigam - Initial contribution
44 public class PulseaudioDiscoveryParticipant implements MDNSDiscoveryParticipant {
46 private final Logger logger = LoggerFactory.getLogger(PulseaudioDiscoveryParticipant.class);
49 public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
50 return PulseaudioBridgeHandler.SUPPORTED_THING_TYPES_UIDS;
54 public @Nullable DiscoveryResult createResult(ServiceInfo info) {
55 DiscoveryResult result = null;
56 ThingUID uid = getThingUID(info);
58 Map<String, Object> properties = new HashMap<>(3);
59 String label = "Pulseaudio server";
61 label = info.getName();
62 } catch (Exception e) {
63 // ignore and use default label
65 // remove the domain from the name
66 String hostname = info.getServer().replace("." + info.getDomain() + ".", "");
67 try (Socket testSocket = new Socket(hostname, 4712)) {
68 logger.debug("testing connection to pulseaudio server {}:4712", hostname);
70 if (testSocket.isConnected()) {
71 properties.put(PulseaudioBindingConstants.BRIDGE_PARAMETER_HOST, hostname);
72 // we do not read the port here because the given port is 4713 and we need 4712 to query the server
73 result = DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label).build();
75 logger.trace("Created a DiscoveryResult for device '{}' on host '{}'", info.getName(), hostname);
78 } catch (IOException e) {
85 public @Nullable ThingUID getThingUID(ServiceInfo info) {
86 logger.debug("ServiceInfo: {}", info);
87 if (info.getType() != null) {
88 if (info.getType().equals(getServiceType())) {
89 logger.trace("Discovered a pulseaudio server thing with name '{}'", info.getName());
90 return new ThingUID(PulseaudioBindingConstants.BRIDGE_THING_TYPE, info.getName().replace("@", "_AT_"));
97 public String getServiceType() {
98 return "_pulse-server._tcp.local.";