Skip to content

Commit 703796d

Browse files
authored
[squeezebox] Fix properties for manually configured Things (openhab#18347)
* Refactor discovery Add null annotations and fix warnings Signed-off-by: Jacob Laursen <[email protected]> * Fix property initialization for manually configured player Things Signed-off-by: Jacob Laursen <[email protected]> --------- Signed-off-by: Jacob Laursen <[email protected]>
1 parent e40481c commit 703796d

20 files changed

+267
-194
lines changed

bundles/org.openhab.binding.squeezebox/src/main/java/org/openhab/binding/squeezebox/internal/SqueezeBoxAudioSink.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
import java.util.Locale;
1818
import java.util.Set;
1919

20+
import org.eclipse.jdt.annotation.NonNullByDefault;
2021
import org.eclipse.jdt.annotation.Nullable;
2122
import org.openhab.binding.squeezebox.internal.handler.SqueezeBoxPlayerHandler;
2223
import org.openhab.core.audio.AudioFormat;
2324
import org.openhab.core.audio.AudioHTTPServer;
24-
import org.openhab.core.audio.AudioSink;
2525
import org.openhab.core.audio.AudioSinkSync;
2626
import org.openhab.core.audio.AudioStream;
2727
import org.openhab.core.audio.FileAudioStream;
@@ -36,11 +36,12 @@
3636
import org.slf4j.LoggerFactory;
3737

3838
/**
39-
* This makes a SqueezeBox Player serve as an {@link AudioSink}-
39+
* This makes a SqueezeBox Player serve as an {@link org.openhab.core.audio.AudioSink}
4040
*
4141
* @author Mark Hilbush - Initial contribution
4242
* @author Mark Hilbush - Add callbackUrl
4343
*/
44+
@NonNullByDefault
4445
public class SqueezeBoxAudioSink extends AudioSinkSync {
4546
private final Logger logger = LoggerFactory.getLogger(SqueezeBoxAudioSink.class);
4647

@@ -50,13 +51,13 @@ public class SqueezeBoxAudioSink extends AudioSinkSync {
5051
// Needed because Squeezebox does multiple requests for the stream
5152
private static final int STREAM_TIMEOUT = 10;
5253

53-
private String callbackUrl;
54+
private @Nullable String callbackUrl;
5455

5556
private AudioHTTPServer audioHTTPServer;
5657
private SqueezeBoxPlayerHandler playerHandler;
5758

5859
public SqueezeBoxAudioSink(SqueezeBoxPlayerHandler playerHandler, AudioHTTPServer audioHTTPServer,
59-
String callbackUrl) {
60+
@Nullable String callbackUrl) {
6061
this.playerHandler = playerHandler;
6162
this.audioHTTPServer = audioHTTPServer;
6263
this.callbackUrl = callbackUrl;
@@ -71,12 +72,12 @@ public String getId() {
7172
}
7273

7374
@Override
74-
public String getLabel(Locale locale) {
75+
public @Nullable String getLabel(@Nullable Locale locale) {
7576
return playerHandler.getThing().getLabel();
7677
}
7778

7879
@Override
79-
public void processSynchronously(AudioStream audioStream)
80+
public void processSynchronously(@Nullable AudioStream audioStream)
8081
throws UnsupportedAudioFormatException, UnsupportedAudioStreamException {
8182
if (audioStream == null) {
8283
return;
@@ -105,6 +106,7 @@ public void processSynchronously(AudioStream audioStream)
105106

106107
// Form the URL for streaming the notification from the OH web server
107108
// Use the callback URL if it is set in the binding configuration
109+
String callbackUrl = this.callbackUrl;
108110
String host = callbackUrl == null || callbackUrl.isEmpty() ? playerHandler.getHostAndPort()
109111
: callbackUrl;
110112
if (host == null) {

bundles/org.openhab.binding.squeezebox/src/main/java/org/openhab/binding/squeezebox/internal/SqueezeBoxBindingConstants.java

+5
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,9 @@ public class SqueezeBoxBindingConstants {
7474
public static final String CHANNEL_FAVORITES_PLAY = "playFavorite";
7575
public static final String CHANNEL_RATE = "rate";
7676
public static final String CHANNEL_SLEEP = "sleep";
77+
78+
// List of all properties
79+
public static final String PROPERTY_NAME = "name";
80+
public static final String PROPERTY_UID = "uid";
81+
public static final String PROPERTY_IP = "ip";
7782
}

bundles/org.openhab.binding.squeezebox/src/main/java/org/openhab/binding/squeezebox/internal/SqueezeBoxHandlerFactory.java

+22-74
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,24 @@
1515
import static org.openhab.binding.squeezebox.internal.SqueezeBoxBindingConstants.*;
1616

1717
import java.util.Dictionary;
18-
import java.util.HashMap;
1918
import java.util.Hashtable;
2019
import java.util.Map;
2120
import java.util.Set;
2221
import java.util.concurrent.ConcurrentHashMap;
2322
import java.util.stream.Collectors;
2423
import java.util.stream.Stream;
2524

26-
import org.openhab.binding.squeezebox.internal.discovery.SqueezeBoxPlayerDiscoveryParticipant;
27-
import org.openhab.binding.squeezebox.internal.handler.SqueezeBoxPlayerEventListener;
25+
import org.eclipse.jdt.annotation.NonNullByDefault;
26+
import org.eclipse.jdt.annotation.Nullable;
2827
import org.openhab.binding.squeezebox.internal.handler.SqueezeBoxPlayerHandler;
2928
import org.openhab.binding.squeezebox.internal.handler.SqueezeBoxServerHandler;
3029
import org.openhab.core.audio.AudioHTTPServer;
3130
import org.openhab.core.audio.AudioSink;
32-
import org.openhab.core.config.discovery.DiscoveryService;
3331
import org.openhab.core.net.HttpServiceUtil;
3432
import org.openhab.core.net.NetworkAddressService;
3533
import org.openhab.core.thing.Bridge;
3634
import org.openhab.core.thing.Thing;
3735
import org.openhab.core.thing.ThingTypeUID;
38-
import org.openhab.core.thing.ThingUID;
3936
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
4037
import org.openhab.core.thing.binding.ThingHandler;
4138
import org.openhab.core.thing.binding.ThingHandlerFactory;
@@ -56,6 +53,7 @@
5653
* @author Mark Hilbush - Add callbackUrl
5754
*/
5855
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.squeezebox")
56+
@NonNullByDefault
5957
public class SqueezeBoxHandlerFactory extends BaseThingHandlerFactory {
6058
private final Logger logger = LoggerFactory.getLogger(SqueezeBoxHandlerFactory.class);
6159

@@ -64,21 +62,19 @@ public class SqueezeBoxHandlerFactory extends BaseThingHandlerFactory {
6462
SqueezeBoxPlayerHandler.SUPPORTED_THING_TYPES_UIDS.stream())
6563
.collect(Collectors.toSet());
6664

67-
private Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
68-
6965
private final AudioHTTPServer audioHTTPServer;
7066
private final NetworkAddressService networkAddressService;
7167
private final SqueezeBoxStateDescriptionOptionsProvider stateDescriptionProvider;
7268

7369
private Map<String, ServiceRegistration<AudioSink>> audioSinkRegistrations = new ConcurrentHashMap<>();
7470

7571
// Callback url (scheme+server+port) to use for playing notification sounds
76-
private String callbackUrl = null;
72+
private @Nullable String callbackUrl = null;
7773

7874
@Activate
79-
public SqueezeBoxHandlerFactory(@Reference AudioHTTPServer audioHTTPServer,
80-
@Reference NetworkAddressService networkAddressService,
81-
@Reference SqueezeBoxStateDescriptionOptionsProvider stateDescriptionProvider) {
75+
public SqueezeBoxHandlerFactory(final @Reference AudioHTTPServer audioHTTPServer,
76+
final @Reference NetworkAddressService networkAddressService,
77+
final @Reference SqueezeBoxStateDescriptionOptionsProvider stateDescriptionProvider) {
8278
this.audioHTTPServer = audioHTTPServer;
8379
this.networkAddressService = networkAddressService;
8480
this.stateDescriptionProvider = stateDescriptionProvider;
@@ -97,101 +93,53 @@ protected void activate(ComponentContext componentContext) {
9793
}
9894

9995
@Override
100-
protected ThingHandler createHandler(Thing thing) {
96+
protected @Nullable ThingHandler createHandler(Thing thing) {
10197
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
10298

103-
if (thingTypeUID.equals(SQUEEZEBOXSERVER_THING_TYPE)) {
104-
logger.trace("creating handler for bridge thing {}", thing);
105-
SqueezeBoxServerHandler bridge = new SqueezeBoxServerHandler((Bridge) thing);
106-
registerSqueezeBoxPlayerDiscoveryService(bridge);
107-
return bridge;
99+
if (SQUEEZEBOXSERVER_THING_TYPE.equals(thingTypeUID)) {
100+
logger.trace("Creating handler for bridge thing {}", thing);
101+
return new SqueezeBoxServerHandler((Bridge) thing);
108102
}
109103

110-
if (thingTypeUID.equals(SQUEEZEBOXPLAYER_THING_TYPE)) {
111-
logger.trace("creating handler for player thing {}", thing);
104+
if (SQUEEZEBOXPLAYER_THING_TYPE.equals(thingTypeUID)) {
105+
logger.trace("Creating handler for player thing {}", thing);
112106
SqueezeBoxPlayerHandler playerHandler = new SqueezeBoxPlayerHandler(thing, createCallbackUrl(),
113107
stateDescriptionProvider);
114108

115109
// Register the player as an audio sink
116110
logger.trace("Registering an audio sink for player thing {}", thing.getUID());
117111
SqueezeBoxAudioSink audioSink = new SqueezeBoxAudioSink(playerHandler, audioHTTPServer, callbackUrl);
118-
@SuppressWarnings("unchecked")
119-
ServiceRegistration<AudioSink> reg = (ServiceRegistration<AudioSink>) bundleContext
120-
.registerService(AudioSink.class.getName(), audioSink, new Hashtable<>());
121-
audioSinkRegistrations.put(thing.getUID().toString(), reg);
112+
ServiceRegistration<AudioSink> audioSinkRegistration = bundleContext.registerService(AudioSink.class,
113+
audioSink, new Hashtable<>());
114+
audioSinkRegistrations.put(thing.getUID().toString(), audioSinkRegistration);
122115

123116
return playerHandler;
124117
}
125118

126119
return null;
127120
}
128121

129-
/**
130-
* Adds SqueezeBoxServerHandlers to the discovery service to find SqueezeBox
131-
* Players
132-
*
133-
* @param squeezeBoxServerHandler
134-
*/
135-
private synchronized void registerSqueezeBoxPlayerDiscoveryService(
136-
SqueezeBoxServerHandler squeezeBoxServerHandler) {
137-
logger.trace("registering player discovery service");
138-
139-
SqueezeBoxPlayerDiscoveryParticipant discoveryService = new SqueezeBoxPlayerDiscoveryParticipant(
140-
squeezeBoxServerHandler);
141-
142-
// Register the PlayerListener with the SqueezeBoxServerHandler
143-
squeezeBoxServerHandler.registerSqueezeBoxPlayerListener(discoveryService);
144-
145-
// Register the service, then add the service to the ServiceRegistration map
146-
discoveryServiceRegs.put(squeezeBoxServerHandler.getThing().getUID(),
147-
bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
148-
}
149-
150122
@Override
151123
protected synchronized void removeHandler(ThingHandler thingHandler) {
152-
if (thingHandler instanceof SqueezeBoxServerHandler serverHandler) {
153-
logger.trace("removing handler for bridge thing {}", thingHandler.getThing());
154-
155-
ServiceRegistration<?> serviceReg = this.discoveryServiceRegs.get(thingHandler.getThing().getUID());
156-
if (serviceReg != null) {
157-
logger.trace("unregistering player discovery service");
158-
159-
// Get the discovery service object and use it to cancel the RequestPlayerJob
160-
SqueezeBoxPlayerDiscoveryParticipant discoveryService = (SqueezeBoxPlayerDiscoveryParticipant) bundleContext
161-
.getService(serviceReg.getReference());
162-
discoveryService.cancelRequestPlayerJob();
163-
164-
// Unregister the PlayerListener from the SqueezeBoxServerHandler
165-
serverHandler.unregisterSqueezeBoxPlayerListener(
166-
(SqueezeBoxPlayerEventListener) bundleContext.getService(serviceReg.getReference()));
167-
168-
// Unregister the PlayerListener service
169-
serviceReg.unregister();
170-
171-
// Remove the service from the ServiceRegistration map
172-
discoveryServiceRegs.remove(thingHandler.getThing().getUID());
173-
}
174-
}
175-
176124
if (thingHandler instanceof SqueezeBoxPlayerHandler playerHandler) {
177125
SqueezeBoxServerHandler bridge = playerHandler.getSqueezeBoxServerHandler();
178126
if (bridge != null) {
179127
// Unregister the player's audio sink
180128
logger.trace("Unregistering the audio sync service for player thing {}",
181129
thingHandler.getThing().getUID());
182-
ServiceRegistration<AudioSink> reg = audioSinkRegistrations
183-
.get(thingHandler.getThing().getUID().toString());
184-
if (reg != null) {
185-
reg.unregister();
130+
ServiceRegistration<AudioSink> audioSinkRegistration = audioSinkRegistrations
131+
.remove(thingHandler.getThing().getUID().toString());
132+
if (audioSinkRegistration != null) {
133+
audioSinkRegistration.unregister();
186134
}
187135

188-
logger.trace("removing handler for player thing {}", thingHandler.getThing());
136+
logger.trace("Removing handler for player thing {}", thingHandler.getThing());
189137
bridge.removePlayerCache(playerHandler.getMac());
190138
}
191139
}
192140
}
193141

194-
private String createCallbackUrl() {
142+
private @Nullable String createCallbackUrl() {
195143
final String ipAddress = networkAddressService.getPrimaryIpv4HostAddress();
196144
if (ipAddress == null) {
197145
logger.warn("No network interface could be found.");

bundles/org.openhab.binding.squeezebox/src/main/java/org/openhab/binding/squeezebox/internal/config/SqueezeBoxPlayerConfig.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@
1212
*/
1313
package org.openhab.binding.squeezebox.internal.config;
1414

15+
import org.eclipse.jdt.annotation.NonNullByDefault;
16+
import org.eclipse.jdt.annotation.Nullable;
17+
1518
/**
1619
* Configuration for a player
1720
*
1821
* @author Dan Cunningham - Initial contribution
1922
* @author Mark Hilbush - Convert sound notification volume from channel to config parameter
2023
*
2124
*/
25+
@NonNullByDefault
2226
public class SqueezeBoxPlayerConfig {
2327
/**
2428
* MAC address of player
2529
*/
26-
public String mac;
30+
public String mac = "";
2731

2832
/**
2933
* Number of seconds to wait to time out a notification
@@ -33,5 +37,5 @@ public class SqueezeBoxPlayerConfig {
3337
/**
3438
* Volume used for playing notifications
3539
*/
36-
public Integer notificationVolume;
40+
public @Nullable Integer notificationVolume;
3741
}

0 commit comments

Comments
 (0)