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.denonmarantz.internal.discovery;
15 import static org.openhab.binding.denonmarantz.internal.DenonMarantzBindingConstants.*;
17 import java.util.Collections;
18 import java.util.HashMap;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
24 import javax.jmdns.ServiceInfo;
26 import org.openhab.core.config.discovery.DiscoveryResult;
27 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
28 import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
29 import org.openhab.core.thing.Thing;
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 * @author Jan-Willem Veldhuis - Initial contribution
41 public class DenonMarantzDiscoveryParticipant implements MDNSDiscoveryParticipant {
43 private Logger logger = LoggerFactory.getLogger(DenonMarantzDiscoveryParticipant.class);
45 // Service type for 'Airplay enabled' receivers
46 private static final String RAOP_SERVICE_TYPE = "_raop._tcp.local.";
49 * Match the serial number, vendor and model of the discovered AVR.
50 * Input is like "0006781D58B1@Marantz SR5008._raop._tcp.local."
51 * A Denon AVR serial (MAC address) starts with 0005CD
52 * A Marantz AVR serial (MAC address) starts with 000678
54 private static final Pattern DENON_MARANTZ_PATTERN = Pattern
55 .compile("^((?:0005CD|000678)[A-Z0-9]+)@(.+)\\._raop\\._tcp\\.local\\.$");
58 * Denon AVRs have a MAC address / serial number starting with 0005CD
60 private static final String DENON_MAC_PREFIX = "0005CD";
63 * Marantz AVRs have a MAC address / serial number starting with 000678
65 private static final String MARANTZ_MAC_PREFIX = "000678";
68 public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
69 return Collections.singleton(THING_TYPE_AVR);
73 public String getServiceType() {
74 return RAOP_SERVICE_TYPE;
78 public DiscoveryResult createResult(ServiceInfo serviceInfo) {
79 String qualifiedName = serviceInfo.getQualifiedName();
80 logger.debug("AVR found: {}", qualifiedName);
81 ThingUID thingUID = getThingUID(serviceInfo);
82 if (thingUID != null) {
83 Matcher matcher = DENON_MARANTZ_PATTERN.matcher(qualifiedName);
84 matcher.matches(); // we already know it matches, it was matched in getThingUID
85 String serial = matcher.group(1).toLowerCase();
88 * The Vendor is not available from the mDNS result.
89 * We assign the Vendor based on our assumptions of the MAC address prefix.
92 if (serial.startsWith(MARANTZ_MAC_PREFIX)) {
94 } else if (serial.startsWith(DENON_MAC_PREFIX)) {
98 // 'am=...' property describes the model name
99 String model = serviceInfo.getPropertyString("am");
100 String friendlyName = matcher.group(2).trim();
102 Map<String, Object> properties = new HashMap<>(2);
104 if (serviceInfo.getHostAddresses().length == 0) {
105 logger.debug("Could not determine IP address for the Denon/Marantz AVR");
108 String host = serviceInfo.getHostAddresses()[0];
110 logger.debug("IP Address: {}", host);
112 properties.put(PARAMETER_HOST, host);
113 properties.put(Thing.PROPERTY_SERIAL_NUMBER, serial);
114 properties.put(Thing.PROPERTY_VENDOR, vendor);
115 properties.put(Thing.PROPERTY_MODEL_ID, model);
117 String label = friendlyName + " (" + vendor + ' ' + model + ")";
118 DiscoveryResult result = DiscoveryResultBuilder.create(thingUID).withProperties(properties).withLabel(label)
119 .withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER).build();
128 public ThingUID getThingUID(ServiceInfo service) {
129 Matcher matcher = DENON_MARANTZ_PATTERN.matcher(service.getQualifiedName());
130 if (matcher.matches()) {
131 logger.debug("This seems like a supported Denon/Marantz AVR!");
132 String serial = matcher.group(1).toLowerCase();
133 return new ThingUID(THING_TYPE_AVR, serial);
135 logger.trace("This discovered device is not supported by the DenonMarantz binding, ignoring..");