22
22
23
23
import javax .jmdns .ServiceInfo ;
24
24
25
+ import org .eclipse .jdt .annotation .NonNullByDefault ;
26
+ import org .eclipse .jdt .annotation .Nullable ;
25
27
import org .openhab .core .config .discovery .DiscoveryResult ;
26
28
import org .openhab .core .config .discovery .DiscoveryResultBuilder ;
27
29
import org .openhab .core .config .discovery .mdns .MDNSDiscoveryParticipant ;
33
35
import org .slf4j .LoggerFactory ;
34
36
35
37
/**
36
- * @author Jan-Willem Veldhuis - Initial contribution
38
+ * The {@link DenonMarantzMDNSDiscoveryParticipant} is responsible for discovering Denon/Marantz AV Receivers.
39
+ * It uses the central {@link org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant}.
37
40
*
41
+ * @author Jan-Willem Veldhuis - Initial contribution
38
42
*/
39
- @ Component
40
- public class DenonMarantzDiscoveryParticipant implements MDNSDiscoveryParticipant {
43
+ @ Component (configurationPid = "discovery.denonmarantz" )
44
+ @ NonNullByDefault
45
+ public class DenonMarantzMDNSDiscoveryParticipant implements MDNSDiscoveryParticipant {
41
46
42
- private Logger logger = LoggerFactory .getLogger (DenonMarantzDiscoveryParticipant .class );
47
+ private Logger logger = LoggerFactory .getLogger (DenonMarantzMDNSDiscoveryParticipant .class );
43
48
44
49
// Service type for 'Airplay enabled' receivers
45
50
private static final String RAOP_SERVICE_TYPE = "_raop._tcp.local." ;
46
51
47
52
/**
48
53
* Match the serial number, vendor and model of the discovered AVR.
49
54
* Input is like "0006781D58B1@Marantz SR5008._raop._tcp.local."
50
- * A Denon AVR serial (MAC address) starts with 0005CD
51
- * A Marantz AVR serial (MAC address) starts with 000678
55
+ * Older Denon AVR's serial (MAC address) starts with 0005CD
56
+ * Older Marantz AVR's serial (MAC address) starts with 000678
57
+ * Newer Denon AVR's can start with 000678 as well.
52
58
*/
53
59
private static final Pattern DENON_MARANTZ_PATTERN = Pattern
54
60
.compile ("^((?:0005CD|000678)[A-Z0-9]+)@(.+)\\ ._raop\\ ._tcp\\ .local\\ .$" );
55
61
56
- /**
57
- * Denon AVRs have a MAC address / serial number starting with 0005CD
58
- */
59
- private static final String DENON_MAC_PREFIX = "0005CD" ;
60
-
61
- /**
62
- * Marantz AVRs have a MAC address / serial number starting with 000678
63
- */
64
- private static final String MARANTZ_MAC_PREFIX = "000678" ;
62
+ private static final String DENON_MODEL_PREFIX = "denon" ;
63
+ private static final String MARANTZ_MODEL_PREFIX = "marantz" ;
65
64
66
65
@ Override
67
66
public Set <ThingTypeUID > getSupportedThingTypeUIDs () {
@@ -74,55 +73,58 @@ public String getServiceType() {
74
73
}
75
74
76
75
@ Override
76
+ @ Nullable
77
77
public DiscoveryResult createResult (ServiceInfo serviceInfo ) {
78
78
String qualifiedName = serviceInfo .getQualifiedName ();
79
79
logger .debug ("AVR found: {}" , qualifiedName );
80
80
ThingUID thingUID = getThingUID (serviceInfo );
81
- if (thingUID != null ) {
82
- Matcher matcher = DENON_MARANTZ_PATTERN .matcher (qualifiedName );
83
- matcher .matches (); // we already know it matches, it was matched in getThingUID
84
- String serial = matcher .group (1 ).toLowerCase ();
81
+ if (thingUID == null ) {
82
+ return null ;
83
+ }
85
84
86
- /**
87
- * The Vendor is not available from the mDNS result.
88
- * We assign the Vendor based on our assumptions of the MAC address prefix.
89
- */
90
- String vendor = "" ;
91
- if (serial .startsWith (MARANTZ_MAC_PREFIX )) {
92
- vendor = "Marantz" ;
93
- } else if (serial .startsWith (DENON_MAC_PREFIX )) {
94
- vendor = "Denon" ;
95
- }
96
-
97
- // 'am=...' property describes the model name
98
- String model = serviceInfo .getPropertyString ("am" );
99
- String friendlyName = matcher .group (2 ).trim ();
100
-
101
- Map <String , Object > properties = new HashMap <>(2 );
102
-
103
- if (serviceInfo .getHostAddresses ().length == 0 ) {
104
- logger .debug ("Could not determine IP address for the Denon/Marantz AVR" );
105
- return null ;
106
- }
107
- String host = serviceInfo .getHostAddresses ()[0 ];
108
-
109
- logger .debug ("IP Address: {}" , host );
110
-
111
- properties .put (PARAMETER_HOST , host );
112
- properties .put (Thing .PROPERTY_SERIAL_NUMBER , serial );
113
- properties .put (Thing .PROPERTY_VENDOR , vendor );
114
- properties .put (Thing .PROPERTY_MODEL_ID , model );
85
+ Matcher matcher = DENON_MARANTZ_PATTERN .matcher (qualifiedName );
86
+ matcher .matches (); // we already know it matches, it was matched in getThingUID
87
+ String serial = matcher .group (1 ).toLowerCase ();
115
88
116
- String label = friendlyName + " (" + vendor + ' ' + model + ")" ;
117
- return DiscoveryResultBuilder . create ( thingUID ). withProperties ( properties ). withLabel ( label )
118
- . withRepresentationProperty ( Thing . PROPERTY_SERIAL_NUMBER ). build ();
89
+ // 'am=...' property describes the model name
90
+ String model = serviceInfo . getPropertyString ( "am" );
91
+ String friendlyName = matcher . group ( 2 ). trim ();
119
92
93
+ String vendor ;
94
+ String modelLowerCase = model == null ? "" : model .toLowerCase ();
95
+ if (modelLowerCase .startsWith (DENON_MODEL_PREFIX )) {
96
+ vendor = VENDOR_DENON ;
97
+ } else if (modelLowerCase .startsWith (MARANTZ_MODEL_PREFIX )) {
98
+ vendor = VENDOR_MARANTZ ;
120
99
} else {
100
+ vendor = null ;
101
+ }
102
+
103
+ Map <String , Object > properties = new HashMap <>(4 );
104
+
105
+ if (serviceInfo .getHostAddresses ().length == 0 ) {
106
+ logger .debug ("Could not determine IP address for the Denon/Marantz AVR" );
121
107
return null ;
122
108
}
109
+ String host = serviceInfo .getHostAddresses ()[0 ];
110
+
111
+ logger .debug ("IP Address: {}" , host );
112
+
113
+ properties .put (PARAMETER_HOST , host );
114
+ if (vendor != null ) {
115
+ properties .put (Thing .PROPERTY_VENDOR , vendor );
116
+ }
117
+ properties .put (Thing .PROPERTY_SERIAL_NUMBER , serial );
118
+ if (model != null ) {
119
+ properties .put (Thing .PROPERTY_MODEL_ID , model );
120
+ }
121
+
122
+ return DiscoveryResultBuilder .create (thingUID ).withProperties (properties ).withLabel (friendlyName )
123
+ .withRepresentationProperty (Thing .PROPERTY_SERIAL_NUMBER ).build ();
123
124
}
124
125
125
126
@ Override
127
+ @ Nullable
126
128
public ThingUID getThingUID (ServiceInfo service ) {
127
129
Matcher matcher = DENON_MARANTZ_PATTERN .matcher (service .getQualifiedName ());
128
130
if (matcher .matches ()) {
0 commit comments