mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-29 12:34:21 +02:00
Fix warnings (#19453)
Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
+1
-2
@@ -23,7 +23,6 @@ import org.openhab.binding.heos.internal.handler.HeosThingBaseHandler;
|
||||
import org.openhab.binding.heos.internal.resources.Telnet.ReadException;
|
||||
import org.openhab.core.audio.AudioFormat;
|
||||
import org.openhab.core.audio.AudioHTTPServer;
|
||||
import org.openhab.core.audio.AudioSink;
|
||||
import org.openhab.core.audio.AudioSinkAsync;
|
||||
import org.openhab.core.audio.AudioStream;
|
||||
import org.openhab.core.audio.FileAudioStream;
|
||||
@@ -38,7 +37,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This makes HEOS to serve as an {@link AudioSink}.
|
||||
* This makes HEOS to serve as an {@link org.openhab.core.audio.AudioSink}.
|
||||
*
|
||||
* @author Johannes Einig - Initial contribution
|
||||
* @author Laurent Garnier - Extend AudioSinkAsync
|
||||
|
||||
+8
-6
@@ -29,7 +29,6 @@ import org.openhab.binding.heos.internal.json.payload.Group;
|
||||
import org.openhab.binding.heos.internal.json.payload.Media;
|
||||
import org.openhab.binding.heos.internal.json.payload.Player;
|
||||
import org.openhab.binding.heos.internal.resources.HeosCommands;
|
||||
import org.openhab.binding.heos.internal.resources.HeosConstants;
|
||||
import org.openhab.binding.heos.internal.resources.HeosEventListener;
|
||||
import org.openhab.binding.heos.internal.resources.Telnet.ReadException;
|
||||
import org.slf4j.Logger;
|
||||
@@ -84,13 +83,14 @@ public class HeosFacade {
|
||||
List<Media> media = new ArrayList<>();
|
||||
for (int page = 0; page < MAX_QUEUE_PAGES; page++) {
|
||||
HeosResponseObject<Media[]> response = fetchQueue(pid, page);
|
||||
if (!response.result || response.payload == null) {
|
||||
Media[] payload = response.payload;
|
||||
if (!response.result || payload == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
media.addAll(Arrays.asList(response.payload));
|
||||
media.addAll(Arrays.asList(payload));
|
||||
|
||||
if (response.payload.length < 100) {
|
||||
if (payload.length < 100) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -457,8 +457,10 @@ public class HeosFacade {
|
||||
|
||||
/**
|
||||
* Asks for the actual state of the player. The result has
|
||||
* to be handled by the event controller. The system returns {@link HeosConstants#PLAY},
|
||||
* {@link HeosConstants#PAUSE} or {@link HeosConstants#STOP}.
|
||||
* to be handled by the event controller. The system returns
|
||||
* {@link org.openhab.binding.heos.internal.resources.HeosConstants#PLAY},
|
||||
* {@link org.openhab.binding.heos.internal.resources.HeosConstants#PAUSE} or
|
||||
* {@link org.openhab.binding.heos.internal.resources.HeosConstants#STOP}.
|
||||
*
|
||||
* @param id The player ID the state shall get for
|
||||
* @return
|
||||
|
||||
-1
@@ -144,7 +144,6 @@ public class HeosSystem {
|
||||
eventSendCommand.stopInputListener(HeosCommands.registerChangeEventOff());
|
||||
eventSendCommand.disconnect();
|
||||
sendCommand.disconnect();
|
||||
@Nullable
|
||||
ExecutorService executor = this.singleThreadExecutor;
|
||||
if (executor != null && executor.isShutdown()) {
|
||||
executor.shutdownNow();
|
||||
|
||||
+2
-3
@@ -13,7 +13,6 @@
|
||||
package org.openhab.binding.heos.internal.configuration;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Configuration wrapper for bridge configuration
|
||||
@@ -32,12 +31,12 @@ public class BridgeConfiguration {
|
||||
/**
|
||||
* Username for login to the HEOS account.
|
||||
*/
|
||||
public @Nullable String username;
|
||||
public String username = "";
|
||||
|
||||
/**
|
||||
* Password for login to the HEOS account
|
||||
*/
|
||||
public @Nullable String password;
|
||||
public String password = "";
|
||||
|
||||
/**
|
||||
* The time in seconds for the HEOS Heartbeat (default = 60 s)
|
||||
|
||||
+4
-2
@@ -18,6 +18,7 @@ import static org.openhab.binding.heos.internal.handler.FutureUtil.cancel;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -189,9 +190,10 @@ public class HeosPlayerDiscovery extends AbstractDiscoveryService implements Heo
|
||||
|
||||
private <K, V> Map<K, V> findRemovedEntries(Map<K, V> mapNew, Map<K, V> mapOld) {
|
||||
Map<K, V> removedItems = new HashMap<>();
|
||||
for (K key : mapOld.keySet()) {
|
||||
for (Entry<K, V> entry : mapOld.entrySet()) {
|
||||
K key = entry.getKey();
|
||||
if (!mapNew.containsKey(key)) {
|
||||
removedItems.put(key, mapOld.get(key));
|
||||
removedItems.put(key, entry.getValue());
|
||||
}
|
||||
}
|
||||
return removedItems;
|
||||
|
||||
+2
-2
@@ -13,13 +13,13 @@
|
||||
package org.openhab.binding.heos.internal.discovery;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.heos.internal.handler.HeosBridgeHandler;
|
||||
|
||||
/**
|
||||
* The {@link HeosPlayerDiscoveryListener } is an Event Listener
|
||||
* for the HEOS network. Handler which wants the get informed
|
||||
* if the player or groups within the HEOS network have changed has to
|
||||
* implement this class and register itself at the {@link HeosBridgeHandler}
|
||||
* implement this class and register itself at the
|
||||
* {@link org.openhab.binding.heos.internal.handler.HeosBridgeHandler}
|
||||
*
|
||||
* @author Johannes Einig - Initial contribution
|
||||
*/
|
||||
|
||||
+2
@@ -24,6 +24,8 @@ import org.openhab.binding.heos.internal.json.dto.HeosErrorCode;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HeosFunctionalException extends IOException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final HeosErrorCode code;
|
||||
|
||||
public HeosFunctionalException(HeosErrorCode code) {
|
||||
|
||||
+2
@@ -23,6 +23,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HeosNotConnectedException extends IOException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public HeosNotConnectedException() {
|
||||
super("HEOS not connected");
|
||||
}
|
||||
|
||||
+2
@@ -23,6 +23,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HeosNotFoundException extends IOException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public HeosNotFoundException() {
|
||||
super("HEOS not found");
|
||||
}
|
||||
|
||||
+7
-26
@@ -83,10 +83,10 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventListener {
|
||||
private final Logger logger = LoggerFactory.getLogger(HeosBridgeHandler.class);
|
||||
|
||||
private static final int HEOS_PORT = 1255;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(HeosBridgeHandler.class);
|
||||
|
||||
private final Set<HeosMediaEventListener> heosMediaEventListeners = new CopyOnWriteArraySet<>();
|
||||
private final List<HeosPlayerDiscoveryListener> playerDiscoveryList = new CopyOnWriteArrayList<>();
|
||||
private final HeosChannelManager channelManager = new HeosChannelManager(this);
|
||||
@@ -121,16 +121,13 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
if (command instanceof RefreshType) {
|
||||
return;
|
||||
}
|
||||
@Nullable
|
||||
Channel channel = this.getThing().getChannel(channelUID.getId());
|
||||
if (channel == null) {
|
||||
logger.debug("No valid channel found");
|
||||
return;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
ChannelTypeUID channelTypeUID = channel.getChannelTypeUID();
|
||||
@Nullable
|
||||
HeosChannelHandler channelHandler = channelHandlerFactory.getChannelHandler(channelUID, this, channelTypeUID);
|
||||
if (channelHandler != null) {
|
||||
try {
|
||||
@@ -157,7 +154,6 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
}
|
||||
|
||||
private void delayedInitialize() {
|
||||
@Nullable
|
||||
HeosFacade connection = null;
|
||||
try {
|
||||
logger.debug("Running scheduledStartUp job");
|
||||
@@ -170,11 +166,9 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
// gets all available player and groups to ensure that the system knows
|
||||
// about the conjunction between the groupMemberHash and the GID
|
||||
triggerPlayerDiscovery();
|
||||
@Nullable
|
||||
String username = configuration.username;
|
||||
@Nullable
|
||||
String password = configuration.password;
|
||||
if (username != null && !"".equals(username) && password != null && !"".equals(password)) {
|
||||
if (!username.isBlank() && !password.isBlank()) {
|
||||
login(connection, username, password);
|
||||
} else {
|
||||
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
@@ -195,9 +189,7 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
|
||||
private void fetchPlayersAndGroups() {
|
||||
try {
|
||||
@Nullable
|
||||
Player[] onlinePlayers = getApiConnection().getPlayers().payload;
|
||||
@Nullable
|
||||
Group[] onlineGroups = getApiConnection().getGroups().payload;
|
||||
|
||||
if (onlinePlayers != null && onlineGroups != null) {
|
||||
@@ -208,17 +200,13 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePlayerStatus(@Nullable Player[] onlinePlayers, @Nullable Group[] onlineGroups) {
|
||||
if (onlinePlayers == null || onlineGroups == null) {
|
||||
return;
|
||||
}
|
||||
private void updatePlayerStatus(Player[] onlinePlayers, Group[] onlineGroups) {
|
||||
Set<String> players = Stream.of(onlinePlayers).map(p -> Objects.toString(p.playerId))
|
||||
.collect(Collectors.toSet());
|
||||
Set<String> groups = Stream.of(onlineGroups).map(p -> p.id).collect(Collectors.toSet());
|
||||
|
||||
for (Thing thing : getThing().getThings()) {
|
||||
try {
|
||||
@Nullable
|
||||
ThingHandler handler = thing.getHandler();
|
||||
if (handler instanceof HeosThingBaseHandler heosHandler) {
|
||||
Set<String> target = handler instanceof HeosPlayerHandler ? players : groups;
|
||||
@@ -260,7 +248,6 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
return;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
HeosError error = response.getError();
|
||||
logger.debug("Failed to login: {}", error);
|
||||
updateStatus(ONLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
@@ -276,7 +263,6 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
cancel(future);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
HeosFacade localApiConnection = apiConnection;
|
||||
if (localApiConnection == null) {
|
||||
logger.debug("Not disposing bridge because of missing apiConnection");
|
||||
@@ -296,9 +282,11 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
@Override
|
||||
public synchronized void childHandlerDisposed(ThingHandler childHandler, Thing childThing) {
|
||||
logger.debug("Disposing child handler for: {}.", childThing.getUID().getId());
|
||||
if (bridgeHandlerDisposalOngoing) { // Checks if bridgeHandler is going to disposed (by stopping the binding or
|
||||
if (bridgeHandlerDisposalOngoing) {
|
||||
// Checks if bridgeHandler is going to disposed (by stopping the binding or
|
||||
// openHAB for example) and prevents it from being updated which stops the
|
||||
// disposal process.
|
||||
return;
|
||||
} else if (childHandler instanceof HeosPlayerHandler) {
|
||||
String channelIdentifier = "P" + childThing.getUID().getId();
|
||||
updateThingChannels(channelManager.removeSingleChannel(channelIdentifier));
|
||||
@@ -326,7 +314,6 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
/**
|
||||
* Sets the HEOS Thing offline
|
||||
*/
|
||||
@SuppressWarnings("null")
|
||||
public void setGroupOffline(String groupMemberHash) {
|
||||
HeosGroupHandler groupHandler = groupHandlerMap.get(groupMemberHash);
|
||||
if (groupHandler != null) {
|
||||
@@ -358,7 +345,6 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
try {
|
||||
String channelIdentifier = "";
|
||||
String pid = "";
|
||||
@Nullable
|
||||
ThingHandler handler = childThing.getHandler();
|
||||
if (handler instanceof HeosPlayerHandler playerHandler) {
|
||||
channelIdentifier = "P" + childThing.getUID().getId();
|
||||
@@ -372,7 +358,6 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
}
|
||||
}
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
@Nullable
|
||||
String playerName = childThing.getLabel();
|
||||
playerName = playerName == null ? pid : playerName;
|
||||
ChannelUID channelUID = new ChannelUID(getThing().getUID(), channelIdentifier);
|
||||
@@ -444,7 +429,6 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
|
||||
public Player[] getPlayers() throws IOException, ReadException {
|
||||
HeosResponseObject<Player[]> response = getApiConnection().getPlayers();
|
||||
@Nullable
|
||||
Player[] players = response.payload;
|
||||
if (players == null) {
|
||||
throw new IOException("Received no valid payload");
|
||||
@@ -454,7 +438,6 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
|
||||
public Group[] getGroups() throws IOException, ReadException {
|
||||
HeosResponseObject<Group[]> response = getApiConnection().getGroups();
|
||||
@Nullable
|
||||
Group[] groups = response.payload;
|
||||
if (groups == null) {
|
||||
throw new IOException("Received no valid payload");
|
||||
@@ -502,13 +485,11 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis
|
||||
}
|
||||
|
||||
public boolean isBridgeConnected() {
|
||||
@Nullable
|
||||
HeosFacade connection = apiConnection;
|
||||
return connection != null && connection.isConnected();
|
||||
}
|
||||
|
||||
public HeosFacade getApiConnection() throws HeosNotConnectedException {
|
||||
@Nullable
|
||||
HeosFacade localApiConnection = apiConnection;
|
||||
if (localApiConnection != null) {
|
||||
return localApiConnection;
|
||||
|
||||
-1
@@ -65,7 +65,6 @@ public class HeosChannelHandlerInputs extends BaseHeosChannelHandler {
|
||||
|
||||
private void handleCommand(Command command, String id) throws IOException, ReadException {
|
||||
if (command instanceof RefreshType) {
|
||||
@Nullable
|
||||
Media payload = getApi().getNowPlayingMedia(id).payload;
|
||||
if (payload != null) {
|
||||
eventListener.playerMediaChangeEvent(id, payload);
|
||||
|
||||
-1
@@ -62,7 +62,6 @@ public class HeosChannelHandlerNowPlaying extends BaseHeosChannelHandler {
|
||||
private void handleCommand(Command command, String id) throws IOException, ReadException {
|
||||
if (command instanceof RefreshType) {
|
||||
// TODO consider caching this somehow, this method is triggered from a lot of channels for the same player
|
||||
@Nullable
|
||||
Media payload = getApi().getNowPlayingMedia(id).payload;
|
||||
if (payload != null) {
|
||||
eventListener.playerMediaChangeEvent(id, payload);
|
||||
|
||||
+4
-3
@@ -13,7 +13,8 @@
|
||||
package org.openhab.binding.heos.internal.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
@@ -65,9 +66,9 @@ public class HeosChannelHandlerPlayURL extends BaseHeosChannelHandler {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
URL url = new URL(command.toString());
|
||||
URL url = new URI(command.toString()).toURL();
|
||||
getApi().playURL(id, url);
|
||||
} catch (MalformedURLException e) {
|
||||
} catch (URISyntaxException e) {
|
||||
logger.debug("Command '{}' is not a proper URL. Error: {}", command.toString(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -39,11 +39,14 @@ import org.osgi.service.component.annotations.Component;
|
||||
public class HeosDynamicStateDescriptionProvider extends BaseDynamicStateDescriptionProvider {
|
||||
|
||||
String getValueByLabel(ChannelUID channelUID, String input) {
|
||||
Optional<String> optionalValueByLabel = channelOptionsMap.get(channelUID).stream()
|
||||
.filter(o -> input.equals(o.getLabel())).map(StateOption::getValue).findFirst();
|
||||
List<StateOption> options = channelOptionsMap.get(channelUID);
|
||||
if (options == null) {
|
||||
return input;
|
||||
}
|
||||
|
||||
// if no match was found we assume that it already was a value and not a label
|
||||
return Objects.requireNonNull(optionalValueByLabel.orElse(input));
|
||||
return Objects.requireNonNull(options.stream().filter(o -> input.equals(o.getLabel()))
|
||||
.map(StateOption::getValue).findFirst().orElse(input));
|
||||
}
|
||||
|
||||
public void setFavorites(ChannelUID channelUID, List<BrowseResult> favorites) {
|
||||
@@ -64,7 +67,6 @@ public class HeosDynamicStateDescriptionProvider extends BaseDynamicStateDescrip
|
||||
|
||||
private Optional<StateOption> getStateOption(Function<BrowseResult, @Nullable String> function,
|
||||
BrowseResult browseResult) {
|
||||
@Nullable
|
||||
String identifier = function.apply(browseResult);
|
||||
if (identifier != null) {
|
||||
return Optional.of(new StateOption(identifier, browseResult.name));
|
||||
|
||||
+1
-12
@@ -72,11 +72,9 @@ public class HeosGroupHandler extends HeosThingBaseHandler {
|
||||
// Only commands from the UNGROUP channel are passed through
|
||||
// to activate the group if it is offline
|
||||
if (gid != null || CH_ID_UNGROUP.equals(channelUID.getId())) {
|
||||
@Nullable
|
||||
HeosChannelHandler channelHandler = getHeosChannelHandler(channelUID);
|
||||
if (channelHandler != null) {
|
||||
try {
|
||||
@Nullable
|
||||
String id = getMaybeId(channelUID, command);
|
||||
channelHandler.handleGroupCommand(command, id, thing.getUID(), this);
|
||||
handleSuccess();
|
||||
@@ -87,8 +85,7 @@ public class HeosGroupHandler extends HeosThingBaseHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getMaybeId(ChannelUID channelUID, Command command) throws HeosNotFoundException {
|
||||
private @Nullable String getMaybeId(ChannelUID channelUID, Command command) throws HeosNotFoundException {
|
||||
if (isCreateGroupRequest(channelUID, command)) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -125,7 +122,6 @@ public class HeosGroupHandler extends HeosThingBaseHandler {
|
||||
|
||||
@Override
|
||||
public String getId() throws HeosNotFoundException {
|
||||
@Nullable
|
||||
String localGroupId = this.gid;
|
||||
if (localGroupId == null) {
|
||||
throw new HeosNotFoundException();
|
||||
@@ -159,11 +155,8 @@ public class HeosGroupHandler extends HeosThingBaseHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String localGid = this.gid;
|
||||
@Nullable
|
||||
String eventGroupId = eventObject.getAttribute(HeosCommunicationAttribute.GROUP_ID);
|
||||
@Nullable
|
||||
String eventPlayerId = eventObject.getAttribute(HeosCommunicationAttribute.PLAYER_ID);
|
||||
if (localGid == null || !(localGid.equals(eventGroupId) || localGid.equals(eventPlayerId))) {
|
||||
return;
|
||||
@@ -185,7 +178,6 @@ public class HeosGroupHandler extends HeosThingBaseHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String localGid = this.gid;
|
||||
if (localGid == null || !localGid.equals(responseObject.getAttribute(HeosCommunicationAttribute.GROUP_ID))) {
|
||||
return;
|
||||
@@ -246,7 +238,6 @@ public class HeosGroupHandler extends HeosThingBaseHandler {
|
||||
}
|
||||
|
||||
private void delayedInitialize() {
|
||||
@Nullable
|
||||
HeosBridgeHandler bridgeHandler = this.bridgeHandler;
|
||||
|
||||
if (bridgeHandler == null) {
|
||||
@@ -262,7 +253,6 @@ public class HeosGroupHandler extends HeosThingBaseHandler {
|
||||
bridgeHandler.addGroupHandlerInformation(this);
|
||||
// Checks if there is a group online with the same group member hash.
|
||||
// If not setting the group offline.
|
||||
@Nullable
|
||||
String groupId = bridgeHandler.getActualGID(HeosGroup.calculateGroupMemberHash(configuration.members));
|
||||
if (groupId == null) {
|
||||
blockInitialization = false;
|
||||
@@ -272,7 +262,6 @@ public class HeosGroupHandler extends HeosThingBaseHandler {
|
||||
refreshPlayState(groupId);
|
||||
|
||||
HeosResponseObject<Group> response = getApiConnection().getGroupInfo(groupId);
|
||||
@Nullable
|
||||
Group group = response.payload;
|
||||
if (group == null) {
|
||||
throw new IllegalStateException("Invalid group response received");
|
||||
|
||||
-1
@@ -60,7 +60,6 @@ public class HeosPlayerHandler extends HeosThingBaseHandler {
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
@Nullable
|
||||
HeosChannelHandler channelHandler = getHeosChannelHandler(channelUID);
|
||||
if (channelHandler != null) {
|
||||
try {
|
||||
|
||||
+13
-20
@@ -16,11 +16,12 @@ import static org.openhab.binding.heos.internal.HeosBindingConstants.*;
|
||||
import static org.openhab.binding.heos.internal.handler.FutureUtil.cancel;
|
||||
import static org.openhab.binding.heos.internal.json.dto.HeosCommandGroup.*;
|
||||
import static org.openhab.binding.heos.internal.json.dto.HeosCommunicationAttribute.*;
|
||||
import static org.openhab.binding.heos.internal.resources.HeosConstants.*;
|
||||
import static org.openhab.core.thing.ThingStatus.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -100,9 +101,7 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
@Nullable
|
||||
Bridge bridge = getBridge();
|
||||
@Nullable
|
||||
HeosBridgeHandler localBridgeHandler;
|
||||
if (bridge != null) {
|
||||
localBridgeHandler = (HeosBridgeHandler) bridge.getHandler();
|
||||
@@ -147,7 +146,6 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
}
|
||||
|
||||
public HeosFacade getApiConnection() throws HeosNotConnectedException {
|
||||
@Nullable
|
||||
HeosBridgeHandler localBridge = bridgeHandler;
|
||||
if (localBridge != null) {
|
||||
return localBridge.getApiConnection();
|
||||
@@ -171,7 +169,6 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
|
||||
@Nullable
|
||||
HeosChannelHandler getHeosChannelHandler(ChannelUID channelUID) {
|
||||
@Nullable
|
||||
HeosChannelHandlerFactory localChannelHandlerFactory = this.channelHandlerFactory;
|
||||
return localChannelHandlerFactory != null ? localChannelHandlerFactory.getChannelHandler(channelUID, this, null)
|
||||
: null;
|
||||
@@ -251,9 +248,9 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
*/
|
||||
public void playURL(String urlStr) throws IOException, ReadException {
|
||||
try {
|
||||
URL url = new URL(urlStr);
|
||||
URL url = new URI(urlStr).toURL();
|
||||
getApiConnection().playURL(getId(), url);
|
||||
} catch (MalformedURLException e) {
|
||||
} catch (URISyntaxException e) {
|
||||
logger.debug("Command '{}' is not a proper URL. Error: {}", urlStr, e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -269,7 +266,6 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
protected void handleThingStateUpdate(HeosEventObject eventObject) {
|
||||
updateStatus(ONLINE, ThingStatusDetail.NONE, "Receiving events");
|
||||
|
||||
@Nullable
|
||||
HeosEvent command = eventObject.command;
|
||||
|
||||
if (command == null) {
|
||||
@@ -284,7 +280,6 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
|
||||
case PLAYER_VOLUME_CHANGED:
|
||||
case GROUP_VOLUME_CHANGED:
|
||||
@Nullable
|
||||
String level = eventObject.getAttribute(LEVEL);
|
||||
if (level != null) {
|
||||
notificationVolume = level;
|
||||
@@ -298,9 +293,7 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
break;
|
||||
|
||||
case PLAYER_NOW_PLAYING_PROGRESS:
|
||||
@Nullable
|
||||
Long position = eventObject.getNumericAttribute(CURRENT_POSITION);
|
||||
@Nullable
|
||||
Long duration = eventObject.getNumericAttribute(DURATION);
|
||||
if (position != null && duration != null) {
|
||||
updateState(CH_ID_CUR_POS, quantityFromMilliSeconds(position));
|
||||
@@ -352,7 +345,6 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
protected <T> void handleThingStateUpdate(HeosResponseObject<T> responseObject) throws HeosFunctionalException {
|
||||
handleResponseError(responseObject);
|
||||
|
||||
@Nullable
|
||||
HeosCommandTuple cmd = responseObject.heosCommand;
|
||||
|
||||
if (cmd == null) {
|
||||
@@ -371,7 +363,6 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
break;
|
||||
|
||||
case GET_VOLUME:
|
||||
@Nullable
|
||||
String level = responseObject.getAttribute(LEVEL);
|
||||
if (level != null) {
|
||||
notificationVolume = level;
|
||||
@@ -399,12 +390,15 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
handlePlayerInfo(player);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logger.trace("Unhandled command {} for command group {}", cmd.command, cmd.commandGroup);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void handleResponseError(HeosResponseObject<T> responseObject) throws HeosFunctionalException {
|
||||
@Nullable
|
||||
HeosError error = responseObject.getError();
|
||||
if (error != null) {
|
||||
throw new HeosFunctionalException(error.code);
|
||||
@@ -412,7 +406,6 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
}
|
||||
|
||||
private void handleRepeatMode(HeosObject eventObject) {
|
||||
@Nullable
|
||||
String repeatMode = eventObject.getAttribute(REPEAT);
|
||||
if (repeatMode == null) {
|
||||
updateState(CH_ID_REPEAT_MODE, UnDefType.NULL);
|
||||
@@ -435,7 +428,6 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
}
|
||||
|
||||
private void playerStateChanged(HeosObject eventObject) {
|
||||
@Nullable
|
||||
String attribute = eventObject.getAttribute(STATE);
|
||||
if (attribute == null) {
|
||||
updateState(CH_ID_CONTROL, UnDefType.NULL);
|
||||
@@ -491,13 +483,13 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
String imageUrl = info.imageUrl;
|
||||
if (imageUrl != null && !imageUrl.isBlank()) {
|
||||
try {
|
||||
URL url = new URL(imageUrl); // checks if String is proper URL
|
||||
URL url = new URI(imageUrl).toURL(); // checks if String is proper URL
|
||||
RawType cover = HttpUtil.downloadImage(url.toString());
|
||||
if (cover != null) {
|
||||
updateState(CH_ID_COVER, cover);
|
||||
return;
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
} catch (URISyntaxException | MalformedURLException e) {
|
||||
logger.debug("Cover can't be loaded. No proper URL: {}", imageUrl, e);
|
||||
}
|
||||
}
|
||||
@@ -513,8 +505,9 @@ public abstract class HeosThingBaseHandler extends BaseThingHandler implements H
|
||||
}
|
||||
|
||||
private void handleSourceId(Media info) {
|
||||
if (info.sourceId == INPUT_SID && info.mediaId != null) {
|
||||
String inputName = info.mediaId.substring(info.mediaId.indexOf("/") + 1);
|
||||
String mediaId = info.mediaId;
|
||||
if (info.sourceId == INPUT_SID && mediaId != null) {
|
||||
String inputName = mediaId.substring(mediaId.indexOf("/") + 1);
|
||||
updateState(CH_ID_INPUTS, StringType.valueOf(inputName));
|
||||
updateState(CH_ID_TYPE, StringType.valueOf(info.station));
|
||||
} else {
|
||||
|
||||
+2
-1
@@ -46,7 +46,7 @@ public class HeosJsonParser {
|
||||
.create();
|
||||
|
||||
public HeosEventObject parseEvent(String jsonBody) {
|
||||
HeosJsonWrapper wrapper = gson.fromJson(jsonBody, HeosJsonWrapper.class);
|
||||
HeosJsonWrapper wrapper = Objects.requireNonNull(gson.fromJson(jsonBody, HeosJsonWrapper.class));
|
||||
|
||||
return postProcess(wrapper.heos);
|
||||
}
|
||||
@@ -61,6 +61,7 @@ public class HeosJsonParser {
|
||||
}
|
||||
|
||||
private <T> HeosResponseObject<T> postProcess(HeosJsonWrapper wrapper, Class<T> clazz) {
|
||||
@Nullable
|
||||
T payload = gson.fromJson(wrapper.payload, clazz);
|
||||
|
||||
return new HeosResponseObject<>(HeosCommandTuple.valueOf(wrapper.heos.command), wrapper.heos.command,
|
||||
|
||||
-1
@@ -41,7 +41,6 @@ public abstract class HeosObject {
|
||||
}
|
||||
|
||||
public @Nullable Long getNumericAttribute(HeosCommunicationAttribute attributeName) {
|
||||
@Nullable
|
||||
String attribute = attributes.get(attributeName.getLabel());
|
||||
|
||||
if (attribute == null) {
|
||||
|
||||
+5
-5
@@ -13,16 +13,16 @@
|
||||
package org.openhab.binding.heos.internal.resources;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.heos.internal.api.HeosEventController;
|
||||
import org.openhab.binding.heos.internal.exception.HeosFunctionalException;
|
||||
import org.openhab.binding.heos.internal.json.dto.HeosEventObject;
|
||||
import org.openhab.binding.heos.internal.json.dto.HeosResponseObject;
|
||||
|
||||
/**
|
||||
* The {@link HeosEventListener } is an Event Listener
|
||||
* for the HEOS network. Handler which wants the get informed
|
||||
* by an HEOS event via the {@link HeosEventController} has to
|
||||
* implement this class and register itself at the {@link HeosEventController}
|
||||
* The {@link HeosEventListener } is an Event Listener for the HEOS network.
|
||||
* Handler which wants the get informed by an HEOS event via the
|
||||
* {@link org.openhab.binding.heos.internal.api.HeosEventController}
|
||||
* has to implement this class and register itself at the
|
||||
* {@link org.openhab.binding.heos.internal.api.HeosEventController}
|
||||
*
|
||||
* @author Johannes Einig - Initial contribution
|
||||
* @author Martin van Wingerden - change handling of stop/pause depending on playing item type
|
||||
|
||||
+5
-5
@@ -15,16 +15,16 @@ package org.openhab.binding.heos.internal.resources;
|
||||
import java.util.EventListener;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.heos.internal.api.HeosEventController;
|
||||
import org.openhab.binding.heos.internal.handler.HeosBridgeHandler;
|
||||
import org.openhab.binding.heos.internal.json.payload.Media;
|
||||
|
||||
/**
|
||||
* The {@link HeosMediaEventListener } is a dedicated Event Listener
|
||||
* for the HEOS media events. Handler which wants the get informed
|
||||
* by an HEOS media event via the {@link HeosEventController} has to
|
||||
* implement this class and register itself either at the
|
||||
* {@link HeosEventController} or at {@link HeosBridgeHandler}
|
||||
* by an HEOS media event via the
|
||||
* {@link org.openhab.binding.heos.internal.api.HeosEventController}
|
||||
* has to implement this class and register itself either at the
|
||||
* {@link org.openhab.binding.heos.internal.api.HeosEventController} or at
|
||||
* {@link org.openhab.binding.heos.internal.handler.HeosBridgeHandler}
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
|
||||
+3
-3
@@ -14,6 +14,7 @@ package org.openhab.binding.heos.internal.resources;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.heos.internal.json.HeosJsonParser;
|
||||
import org.openhab.binding.heos.internal.json.dto.HeosResponseObject;
|
||||
import org.openhab.binding.heos.internal.resources.Telnet.ReadException;
|
||||
@@ -26,6 +27,7 @@ import org.slf4j.LoggerFactory;
|
||||
*
|
||||
* @author Johannes Einig - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HeosSendCommand {
|
||||
private final Logger logger = LoggerFactory.getLogger(HeosSendCommand.class);
|
||||
|
||||
@@ -41,9 +43,7 @@ public class HeosSendCommand {
|
||||
int attempt = 0;
|
||||
|
||||
boolean send = client.send(command);
|
||||
if (clazz == null) {
|
||||
return null;
|
||||
} else if (send) {
|
||||
if (send) {
|
||||
String line = client.readLine();
|
||||
if (line == null) {
|
||||
throw new IOException("No valid input was received");
|
||||
|
||||
+27
-9
@@ -31,6 +31,7 @@ import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.apache.commons.net.io.CRLFLineReader;
|
||||
import org.apache.commons.net.telnet.TelnetClient;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.common.NamedThreadFactory;
|
||||
import org.slf4j.Logger;
|
||||
@@ -42,6 +43,7 @@ import org.slf4j.LoggerFactory;
|
||||
*
|
||||
* @author Johannes Einig - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Telnet {
|
||||
private final Logger logger = LoggerFactory.getLogger(Telnet.class);
|
||||
|
||||
@@ -50,16 +52,16 @@ public class Telnet {
|
||||
|
||||
private final HeosStringPropertyChangeListener eolNotifier = new HeosStringPropertyChangeListener();
|
||||
private final TelnetClient client = new TelnetClient();
|
||||
private ExecutorService timedReaderExecutor;
|
||||
private @Nullable ExecutorService timedReaderExecutor;
|
||||
|
||||
private String ip;
|
||||
private @Nullable String ip;
|
||||
private int port;
|
||||
|
||||
private String readResult = "";
|
||||
|
||||
private InetAddress address;
|
||||
private DataOutputStream outStream;
|
||||
private BufferedInputStream bufferedStream;
|
||||
private @Nullable InetAddress address;
|
||||
private @Nullable DataOutputStream outStream;
|
||||
private @Nullable BufferedInputStream bufferedStream;
|
||||
|
||||
/**
|
||||
* Connects to a host with the specified IP address and port
|
||||
@@ -115,7 +117,8 @@ public class Telnet {
|
||||
* @throws IOException
|
||||
*/
|
||||
private void sendClear(String command) throws IOException {
|
||||
if (!client.isConnected()) {
|
||||
DataOutputStream outStream = this.outStream;
|
||||
if (!client.isConnected() || outStream == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,7 +137,7 @@ public class Telnet {
|
||||
* @throws IOException
|
||||
* @see #readLine(int timeOut)
|
||||
*/
|
||||
public String readLine() throws ReadException, IOException {
|
||||
public @Nullable String readLine() throws ReadException, IOException {
|
||||
return readLine(READ_TIMEOUT);
|
||||
}
|
||||
|
||||
@@ -168,8 +171,10 @@ public class Telnet {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof IOException exception) {
|
||||
throw exception;
|
||||
} else {
|
||||
} else if (cause != null) {
|
||||
throw new ReadException(cause);
|
||||
} else {
|
||||
throw new ReadException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,6 +183,10 @@ public class Telnet {
|
||||
|
||||
private String timedCallable(Callable<String> callable, int timeOut)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
ExecutorService timedReaderExecutor = this.timedReaderExecutor;
|
||||
if (timedReaderExecutor == null) {
|
||||
throw new IllegalStateException("timedReaderExecutor is not initialized");
|
||||
}
|
||||
Future<String> future = timedReaderExecutor.submit(callable);
|
||||
try {
|
||||
return future.get(timeOut, TimeUnit.MILLISECONDS);
|
||||
@@ -194,7 +203,10 @@ public class Telnet {
|
||||
*/
|
||||
public void disconnect() throws IOException {
|
||||
client.disconnect();
|
||||
timedReaderExecutor.shutdown();
|
||||
ExecutorService timedReaderExecutor = this.timedReaderExecutor;
|
||||
if (timedReaderExecutor != null) {
|
||||
timedReaderExecutor.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,6 +228,11 @@ public class Telnet {
|
||||
* available data without any check
|
||||
*/
|
||||
private void inputAvailableRead() {
|
||||
BufferedInputStream bufferedStream = this.bufferedStream;
|
||||
if (bufferedStream == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int i = bufferedStream.available();
|
||||
byte[] buffer = new byte[i];
|
||||
@@ -252,6 +269,7 @@ public class Telnet {
|
||||
* @return true if HEOS is reachable
|
||||
*/
|
||||
public boolean isHostReachable() {
|
||||
InetAddress address = this.address;
|
||||
try {
|
||||
return address != null && address.isReachable(IS_ALIVE_TIMEOUT);
|
||||
} catch (IOException e) {
|
||||
|
||||
+12
-12
@@ -32,7 +32,7 @@ public class HeosJsonParserEventTest {
|
||||
private final HeosJsonParser subject = new HeosJsonParser();
|
||||
|
||||
@Test
|
||||
public void event_now_playing_changed() {
|
||||
public void eventNowPlayingChanged() {
|
||||
HeosEventObject event = subject.parseEvent(
|
||||
"{\"heos\": {\"command\": \"event/player_now_playing_changed\", \"message\": \"pid=1679855527\"}}");
|
||||
|
||||
@@ -42,7 +42,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_now_playing_progress() {
|
||||
public void eventNowPlayingProgress() {
|
||||
HeosEventObject event = subject.parseEvent(
|
||||
"{\"heos\": {\"command\": \"event/player_now_playing_progress\", \"message\": \"pid=1679855527&cur_pos=224848000&duration=0\"}}");
|
||||
|
||||
@@ -54,7 +54,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_state_changed() {
|
||||
public void eventStateChanged() {
|
||||
HeosEventObject event = subject.parseEvent(
|
||||
"{\"heos\": {\"command\": \"event/player_state_changed\", \"message\": \"pid=1679855527&state=play\"}}");
|
||||
|
||||
@@ -65,7 +65,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_playback_error() {
|
||||
public void eventPlaybackError() {
|
||||
HeosEventObject event = subject.parseEvent(
|
||||
"{\"heos\": {\"command\": \"event/player_playback_error\", \"message\": \"pid=1679855527&error=Could Not Download\"}}");
|
||||
|
||||
@@ -76,7 +76,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_volume_changed() {
|
||||
public void eventVolumeChanged() {
|
||||
HeosEventObject event = subject.parseEvent(
|
||||
"{\"heos\": {\"command\": \"event/player_volume_changed\", \"message\": \"pid=1958912779&level=23&mute=off\"}}");
|
||||
|
||||
@@ -88,7 +88,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_shuffle_mode_changed() {
|
||||
public void eventShuffleModeChanged() {
|
||||
HeosEventObject event = subject.parseEvent(
|
||||
"{\"heos\": {\"command\": \"event/shuffle_mode_changed\", \"message\": \"pid=-831584083&shuffle=on\"}}");
|
||||
|
||||
@@ -99,7 +99,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_sources_changed() {
|
||||
public void eventSourcesChanged() {
|
||||
HeosEventObject event = subject.parseEvent("{\"heos\": {\"command\": \"event/sources_changed\"}}");
|
||||
|
||||
assertEquals(HeosEvent.SOURCES_CHANGED, event.command);
|
||||
@@ -107,7 +107,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_user_changed() {
|
||||
public void eventUserChanged() {
|
||||
HeosEventObject event = subject.parseEvent(
|
||||
"{\"heos\": {\"command\": \"event/user_changed\", \"message\": \"signed_in&un=martinvw@mtin.nl\"}}");
|
||||
|
||||
@@ -118,7 +118,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_unknown_event() {
|
||||
public void eventUnknownEvent() {
|
||||
HeosEventObject event = subject.parseEvent("{\"heos\": {\"command\": \"event/does_not_exist\"}}");
|
||||
|
||||
assertNull(event.command);
|
||||
@@ -126,7 +126,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_duplicate_attributes() {
|
||||
public void eventDuplicateAttributes() {
|
||||
HeosEventObject event = subject.parseEvent(
|
||||
"{\"heos\": {\"command\": \"event/does_not_exist\", \"message\": \"signed_in&un=test1&un=test2\"}}");
|
||||
|
||||
@@ -135,7 +135,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_non_numeric() {
|
||||
public void eventNonNumeric() {
|
||||
HeosEventObject event = subject
|
||||
.parseEvent("{\"heos\": {\"command\": \"event/does_not_exist\", \"message\": \"pid=test\"}}");
|
||||
|
||||
@@ -144,7 +144,7 @@ public class HeosJsonParserEventTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event_numeric_missing() {
|
||||
public void eventNumericMissing() {
|
||||
HeosEventObject event = subject.parseEvent("{\"heos\": {\"command\": \"event/does_not_exist\"}}");
|
||||
|
||||
// the first one is ignored but it does not crash
|
||||
|
||||
+113
-66
@@ -21,6 +21,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.heos.internal.json.dto.HeosCommand;
|
||||
import org.openhab.binding.heos.internal.json.dto.HeosCommandGroup;
|
||||
import org.openhab.binding.heos.internal.json.dto.HeosCommandTuple;
|
||||
import org.openhab.binding.heos.internal.json.dto.HeosError;
|
||||
import org.openhab.binding.heos.internal.json.dto.HeosErrorCode;
|
||||
import org.openhab.binding.heos.internal.json.dto.HeosResponseObject;
|
||||
import org.openhab.binding.heos.internal.json.payload.BrowseResult;
|
||||
@@ -42,13 +44,15 @@ public class HeosJsonParserResponseTest {
|
||||
private final HeosJsonParser subject = new HeosJsonParser();
|
||||
|
||||
@Test
|
||||
public void sign_in() {
|
||||
public void signIn() {
|
||||
HeosResponseObject<Void> response = subject.parseResponse(
|
||||
"{\"heos\": {\"command\": \"system/sign_in\", \"result\": \"success\", \"message\": \"signed_in&un=test@example.org\"}}",
|
||||
Void.class);
|
||||
|
||||
assertEquals(HeosCommandGroup.SYSTEM, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.SIGN_IN, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.SYSTEM, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.SIGN_IN, heosCommand.command);
|
||||
assertTrue(response.result);
|
||||
|
||||
assertEquals("test@example.org", response.getAttribute(USERNAME));
|
||||
@@ -56,38 +60,46 @@ public class HeosJsonParserResponseTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sign_in_under_process() {
|
||||
public void signInUnderProcess() {
|
||||
HeosResponseObject<Void> response = subject.parseResponse(
|
||||
"{\"heos\": {\"command\": \"system/sign_in\", \"message\": \"command under process\"}}", Void.class);
|
||||
|
||||
assertEquals(HeosCommandGroup.SYSTEM, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.SIGN_IN, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.SYSTEM, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.SIGN_IN, heosCommand.command);
|
||||
assertFalse(response.result);
|
||||
assertFalse(response.isFinished());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sign_in_failed() {
|
||||
public void signInFailed() {
|
||||
HeosResponseObject<Void> response = subject.parseResponse(
|
||||
"{\"heos\": {\"command\": \"system/sign_in\", \"message\": \"eid=10&text=User not found\"}}",
|
||||
Void.class);
|
||||
|
||||
assertEquals(HeosCommandGroup.SYSTEM, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.SIGN_IN, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.SYSTEM, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.SIGN_IN, heosCommand.command);
|
||||
assertFalse(response.result);
|
||||
assertTrue(response.isFinished());
|
||||
|
||||
assertEquals(HeosErrorCode.USER_NOT_FOUND, response.getError().code);
|
||||
HeosError error = response.getError();
|
||||
assertNotNull(error);
|
||||
assertEquals(HeosErrorCode.USER_NOT_FOUND, error.code);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_mute() {
|
||||
public void getMute() {
|
||||
HeosResponseObject<Void> response = subject.parseResponse(
|
||||
"{\"heos\": {\"command\": \"player/get_mute\", \"result\": \"success\", \"message\": \"pid=1958912779&state=on\"}}",
|
||||
Void.class);
|
||||
|
||||
assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_MUTE, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.PLAYER, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_MUTE, heosCommand.command);
|
||||
assertTrue(response.result);
|
||||
|
||||
assertEquals(Long.valueOf(1958912779), response.getNumericAttribute(PLAYER_ID));
|
||||
@@ -95,26 +107,32 @@ public class HeosJsonParserResponseTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_mute_error() {
|
||||
public void getMuteError() {
|
||||
HeosResponseObject<Void> response = subject.parseResponse(
|
||||
"{\"heos\": {\"command\": \"player/get_mute\", \"result\": \"fail\", \"message\": \"eid=2&text=ID Not Valid&pid=null\"}}",
|
||||
Void.class);
|
||||
|
||||
assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_MUTE, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.PLAYER, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_MUTE, heosCommand.command);
|
||||
assertFalse(response.result);
|
||||
|
||||
assertEquals(HeosErrorCode.INVALID_ID, response.getError().code);
|
||||
HeosError error = response.getError();
|
||||
assertNotNull(error);
|
||||
assertEquals(HeosErrorCode.INVALID_ID, error.code);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void browse_browse_under_process() {
|
||||
public void browseBrowseUnderProcess() {
|
||||
HeosResponseObject<Void> response = subject.parseResponse(
|
||||
"{\"heos\": {\"command\": \"browse/browse\", \"result\": \"success\", \"message\": \"command under process&sid=1025\"}}",
|
||||
Void.class);
|
||||
|
||||
assertEquals(HeosCommandGroup.BROWSE, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.BROWSE, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.BROWSE, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.BROWSE, heosCommand.command);
|
||||
assertTrue(response.result);
|
||||
|
||||
assertEquals(Long.valueOf(1025), response.getNumericAttribute(SOURCE_ID));
|
||||
@@ -122,21 +140,25 @@ public class HeosJsonParserResponseTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incorrect_level() {
|
||||
public void incorrectLevel() {
|
||||
HeosResponseObject<Void> response = subject.parseResponse(
|
||||
"{\"heos\": {\"command\": \"player/set_volume\", \"result\": \"fail\", \"message\": \"eid=9&text=Parameter out of range&pid=-831584083&level=OFF\"}}",
|
||||
Void.class);
|
||||
|
||||
assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.SET_VOLUME, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.PLAYER, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.SET_VOLUME, heosCommand.command);
|
||||
assertFalse(response.result);
|
||||
|
||||
assertEquals(HeosErrorCode.PARAMETER_OUT_OF_RANGE, response.getError().code);
|
||||
assertEquals("#9: Parameter out of range", response.getError().code.toString());
|
||||
HeosError error = response.getError();
|
||||
assertNotNull(error);
|
||||
assertEquals(HeosErrorCode.PARAMETER_OUT_OF_RANGE, error.code);
|
||||
assertEquals("#9: Parameter out of range", error.code.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_players() {
|
||||
public void getPlayers() {
|
||||
HeosResponseObject<Player[]> response = subject.parseResponse(
|
||||
"""
|
||||
{"heos": {"command": "player/get_players", "result": "success", "message": ""}, "payload": [\
|
||||
@@ -145,12 +167,17 @@ public class HeosJsonParserResponseTest {
|
||||
""",
|
||||
Player[].class);
|
||||
|
||||
assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_PLAYERS, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.PLAYER, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_PLAYERS, heosCommand.command);
|
||||
assertTrue(response.result);
|
||||
|
||||
assertEquals(2, response.payload.length);
|
||||
Player player0 = response.payload[0];
|
||||
Player[] payload = response.payload;
|
||||
assertNotNull(payload);
|
||||
assertEquals(2, payload.length);
|
||||
|
||||
Player player0 = payload[0];
|
||||
|
||||
assertEquals("Kantoor HEOS 3", player0.name);
|
||||
assertEquals(-831584083, player0.playerId);
|
||||
@@ -161,7 +188,7 @@ public class HeosJsonParserResponseTest {
|
||||
assertEquals(0, player0.lineout);
|
||||
assertEquals("ACNG9180110887", player0.serial);
|
||||
|
||||
Player player1 = response.payload[1];
|
||||
Player player1 = payload[1];
|
||||
|
||||
assertEquals("HEOS Bar", player1.name);
|
||||
assertEquals(1958912779, player1.playerId);
|
||||
@@ -174,27 +201,31 @@ public class HeosJsonParserResponseTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_player_info() {
|
||||
public void getPlayerInfo() {
|
||||
HeosResponseObject<Player> response = subject.parseResponse(
|
||||
"{\"heos\": {\"command\": \"player/get_player_info\", \"result\": \"success\", \"message\": \"pid=1958912779\"}, \"payload\": {\"name\": \"HEOS Bar\", \"pid\": 1958912779, \"model\": \"HEOS Bar\", \"version\": \"1.520.200\", \"ip\": \"192.168.1.195\", \"network\": \"wired\", \"lineout\": 0, \"serial\": \"ADAG9180917029\"}}",
|
||||
Player.class);
|
||||
|
||||
assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_PLAYER_INFO, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.PLAYER, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_PLAYER_INFO, heosCommand.command);
|
||||
assertTrue(response.result);
|
||||
|
||||
assertEquals("HEOS Bar", response.payload.name);
|
||||
assertEquals(1958912779, response.payload.playerId);
|
||||
assertEquals("HEOS Bar", response.payload.model);
|
||||
assertEquals("1.520.200", response.payload.version);
|
||||
assertEquals("192.168.1.195", response.payload.ip);
|
||||
assertEquals("wired", response.payload.network);
|
||||
assertEquals(0, response.payload.lineout);
|
||||
assertEquals("ADAG9180917029", response.payload.serial);
|
||||
Player payload = response.payload;
|
||||
assertNotNull(payload);
|
||||
assertEquals("HEOS Bar", payload.name);
|
||||
assertEquals(1958912779, payload.playerId);
|
||||
assertEquals("HEOS Bar", payload.model);
|
||||
assertEquals("1.520.200", payload.version);
|
||||
assertEquals("192.168.1.195", payload.ip);
|
||||
assertEquals("wired", payload.network);
|
||||
assertEquals(0, payload.lineout);
|
||||
assertEquals("ADAG9180917029", payload.serial);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_now_playing_media() {
|
||||
public void getNowPlayingMedia() {
|
||||
HeosResponseObject<Media> response = subject.parseResponse(
|
||||
"""
|
||||
{"heos": {"command": "player/get_now_playing_media", "result": "success", "message": "pid=1958912779"}, "payload": \
|
||||
@@ -202,29 +233,33 @@ public class HeosJsonParserResponseTest {
|
||||
""",
|
||||
Media.class);
|
||||
|
||||
assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_NOW_PLAYING_MEDIA, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.PLAYER, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_NOW_PLAYING_MEDIA, heosCommand.command);
|
||||
assertTrue(response.result);
|
||||
|
||||
assertEquals(Long.valueOf(1958912779), response.getNumericAttribute(PLAYER_ID));
|
||||
|
||||
assertEquals("song", response.payload.type);
|
||||
assertEquals("Solo (feat. Demi Lovato)", response.payload.song);
|
||||
assertEquals("What Is Love? (Deluxe)", response.payload.album);
|
||||
assertEquals("Clean Bandit", response.payload.artist);
|
||||
Media payload = response.payload;
|
||||
assertNotNull(payload);
|
||||
assertEquals("song", payload.type);
|
||||
assertEquals("Solo (feat. Demi Lovato)", payload.song);
|
||||
assertEquals("What Is Love? (Deluxe)", payload.album);
|
||||
assertEquals("Clean Bandit", payload.artist);
|
||||
assertEquals(
|
||||
"http://192.168.1.230:8015//m-browsableMediaUri/getImageFromTag/mnt/326C72A3E307501E47DE2B0F47D90EB8/Clean%20Bandit/What%20Is%20Love_%20(Deluxe)/03%20Solo%20(feat.%20Demi%20Lovato).m4a",
|
||||
response.payload.imageUrl);
|
||||
assertEquals("", response.payload.albumId);
|
||||
payload.imageUrl);
|
||||
assertEquals("", payload.albumId);
|
||||
assertEquals(
|
||||
"http://192.168.1.230:8015/m-1c176905-f6c7-d168-dc35-86b4735c5976/Clean+Bandit/What+Is+Love_+(Deluxe)/03+Solo+(feat.+Demi+Lovato).m4a",
|
||||
response.payload.mediaId);
|
||||
assertEquals(1, response.payload.queueId);
|
||||
assertEquals(1024, response.payload.sourceId);
|
||||
payload.mediaId);
|
||||
assertEquals(1, payload.queueId);
|
||||
assertEquals(1024, payload.sourceId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void browse_playlist() {
|
||||
public void browsePlaylist() {
|
||||
HeosResponseObject<BrowseResult[]> response = subject.parseResponse(
|
||||
"""
|
||||
{"heos": {"command": "browse/browse", "result": "success", "message": "sid=1025&returned=6&count=6"}, "payload": [\
|
||||
@@ -237,15 +272,19 @@ public class HeosJsonParserResponseTest {
|
||||
""",
|
||||
BrowseResult[].class);
|
||||
|
||||
assertEquals(HeosCommandGroup.BROWSE, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.BROWSE, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.BROWSE, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.BROWSE, heosCommand.command);
|
||||
assertTrue(response.result);
|
||||
|
||||
assertEquals(Long.valueOf(1025), response.getNumericAttribute(SOURCE_ID));
|
||||
assertEquals(Long.valueOf(6), response.getNumericAttribute(RETURNED));
|
||||
assertEquals(Long.valueOf(6), response.getNumericAttribute(COUNT));
|
||||
|
||||
BrowseResult result = response.payload[5];
|
||||
BrowseResult[] payload = response.payload;
|
||||
assertNotNull(payload);
|
||||
BrowseResult result = payload[5];
|
||||
|
||||
assertEquals(YesNoEnum.YES, result.container);
|
||||
assertEquals(BrowseResultType.PLAYLIST, result.type);
|
||||
@@ -256,7 +295,7 @@ public class HeosJsonParserResponseTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void browse_favorites() {
|
||||
public void browseFavorites() {
|
||||
HeosResponseObject<BrowseResult[]> response = subject.parseResponse(
|
||||
"""
|
||||
{"heos": {"command": "browse/browse", "result": "success", "message": "sid=1028&returned=3&count=3"}, "payload": [\
|
||||
@@ -267,15 +306,19 @@ public class HeosJsonParserResponseTest {
|
||||
""",
|
||||
BrowseResult[].class);
|
||||
|
||||
assertEquals(HeosCommandGroup.BROWSE, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.BROWSE, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.BROWSE, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.BROWSE, heosCommand.command);
|
||||
assertTrue(response.result);
|
||||
|
||||
assertEquals(Long.valueOf(1028), response.getNumericAttribute(SOURCE_ID));
|
||||
assertEquals(Long.valueOf(3), response.getNumericAttribute(RETURNED));
|
||||
assertEquals(Long.valueOf(3), response.getNumericAttribute(COUNT));
|
||||
|
||||
BrowseResult result = response.payload[0];
|
||||
BrowseResult[] payload = response.payload;
|
||||
assertNotNull(payload);
|
||||
BrowseResult result = payload[0];
|
||||
|
||||
assertEquals(YesNoEnum.NO, result.container);
|
||||
assertEquals("s6707", result.mediaId);
|
||||
@@ -288,7 +331,7 @@ public class HeosJsonParserResponseTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_groups() {
|
||||
public void getGroups() {
|
||||
HeosResponseObject<Group[]> response = subject.parseResponse(
|
||||
"""
|
||||
{"heos": {"command": "group/get_groups", "result": "success", "message": ""}, "payload": [ \
|
||||
@@ -297,11 +340,15 @@ public class HeosJsonParserResponseTest {
|
||||
""",
|
||||
Group[].class);
|
||||
|
||||
assertEquals(HeosCommandGroup.GROUP, response.heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_GROUPS, response.heosCommand.command);
|
||||
HeosCommandTuple heosCommand = response.heosCommand;
|
||||
assertNotNull(heosCommand);
|
||||
assertEquals(HeosCommandGroup.GROUP, heosCommand.commandGroup);
|
||||
assertEquals(HeosCommand.GET_GROUPS, heosCommand.command);
|
||||
assertTrue(response.result);
|
||||
|
||||
Group group = response.payload[0];
|
||||
Group[] payload = response.payload;
|
||||
assertNotNull(payload);
|
||||
Group group = payload[0];
|
||||
|
||||
assertEquals("Group 1", group.name);
|
||||
assertEquals("214243242", group.id);
|
||||
|
||||
Reference in New Issue
Block a user