import static org.openhab.binding.nuvo.internal.NuvoBindingConstants.*;
+import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
+import org.openhab.binding.nuvo.internal.configuration.NuvoBindingConfiguration;
import org.openhab.binding.nuvo.internal.handler.NuvoHandler;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.io.transport.serial.SerialPortManager;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
+import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
private final HttpClient httpClient;
+ private final NuvoBindingConfiguration bindingConf;
+
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
@Activate
public NuvoHandlerFactory(final @Reference NuvoStateDescriptionOptionProvider provider,
- final @Reference SerialPortManager serialPortManager,
- final @Reference HttpClientFactory httpClientFactory) {
+ final @Reference SerialPortManager serialPortManager, final @Reference HttpClientFactory httpClientFactory,
+ ComponentContext componentContext, Map<String, Object> config) {
+ super.activate(componentContext);
this.stateDescriptionProvider = provider;
this.serialPortManager = serialPortManager;
this.httpClient = httpClientFactory.getCommonHttpClient();
+ this.bindingConf = new NuvoBindingConfiguration(config);
}
@Override
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
- return new NuvoHandler(thing, stateDescriptionProvider, serialPortManager, httpClient);
+ return new NuvoHandler(thing, stateDescriptionProvider, serialPortManager, httpClient, bindingConf);
}
return null;
import org.openhab.binding.nuvo.internal.communication.NuvoMessageEventListener;
import org.openhab.binding.nuvo.internal.communication.NuvoSerialConnector;
import org.openhab.binding.nuvo.internal.communication.NuvoStatusCodes;
+import org.openhab.binding.nuvo.internal.configuration.NuvoBindingConfiguration;
import org.openhab.binding.nuvo.internal.configuration.NuvoThingConfiguration;
import org.openhab.binding.nuvo.internal.dto.JAXBUtils;
import org.openhab.binding.nuvo.internal.dto.NuvoMenu;
private static final Pattern ART_GUID_PATTERN = Pattern.compile("NowPlayingGuid\",\"value\":\"\\{(.*?)\\}\"\\}");
private final Logger logger = LoggerFactory.getLogger(NuvoHandler.class);
+ private final NuvoBindingConfiguration bindingConf;
private final NuvoStateDescriptionOptionProvider stateDescriptionProvider;
private final SerialPortManager serialPortManager;
private final HttpClient httpClient;
* Constructor
*/
public NuvoHandler(Thing thing, NuvoStateDescriptionOptionProvider stateDescriptionProvider,
- SerialPortManager serialPortManager, HttpClient httpClient) {
+ SerialPortManager serialPortManager, HttpClient httpClient, NuvoBindingConfiguration bindingConf) {
super(thing);
this.stateDescriptionProvider = stateDescriptionProvider;
this.serialPortManager = serialPortManager;
this.httpClient = httpClient;
+ this.bindingConf = bindingConf;
}
@Override
});
// need '1' flag for sources configured as an MPS4 NuvoNet source, but disable openHAB NuvoNet sources
- connector.sendCommand("SNUMBERS" + (nuvoNetSrcMap.get(NuvoEnum.SOURCE1).equals(1) ? ONE : ZERO) + COMMA
- + (nuvoNetSrcMap.get(NuvoEnum.SOURCE2).equals(1) ? ONE : ZERO) + COMMA
- + (nuvoNetSrcMap.get(NuvoEnum.SOURCE3).equals(1) ? ONE : ZERO) + COMMA
- + (nuvoNetSrcMap.get(NuvoEnum.SOURCE4).equals(1) ? ONE : ZERO) + COMMA
- + (nuvoNetSrcMap.get(NuvoEnum.SOURCE5).equals(1) ? ONE : ZERO) + COMMA
- + (nuvoNetSrcMap.get(NuvoEnum.SOURCE6).equals(1) ? ONE : ZERO));
+ connector.sendCommand(
+ "SNUMBERS" + (nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE1, 0).equals(1) ? ONE : ZERO) + COMMA
+ + (nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE2, 0).equals(1) ? ONE : ZERO) + COMMA
+ + (nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE3, 0).equals(1) ? ONE : ZERO) + COMMA
+ + (nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE4, 0).equals(1) ? ONE : ZERO) + COMMA
+ + (nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE5, 0).equals(1) ? ONE : ZERO) + COMMA
+ + (nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE6, 0).equals(1) ? ONE : ZERO));
} catch (NuvoException e) {
logger.debug("Error sending SNUMBERS command to disable NuvoNet sources");
}
String sourceNum = String.valueOf(value / 100);
NuvoEnum source = NuvoEnum.valueOf(SOURCE + sourceNum);
updateChannelState(source, CHANNEL_BUTTON_PRESS,
- PLAY_MUSIC_PRESET + favoriteMap.get(source)[value % 100]);
+ PLAY_MUSIC_PRESET + getFavorite(source, value % 100));
connector.sendCommand(target, NuvoCommand.SOURCE, sourceNum);
// if this zone is in a group, update the other group member's selected source
// if 'albumartid' is present, substitute it with the albumArtId hex string
connector.sendCommand(commandStr.replace(ALBUM_ART_ID,
- (OFFSET_ZERO + Integer.toHexString(albumArtIds.get(source)))));
+ (OFFSET_ZERO + Integer.toHexString(albumArtIds.getOrDefault(source, 0)))));
} else {
connector.sendCommand(commandStr);
}
// re-send the cached DISPINFOTWO message, substituting in the new albumArtId
if (dispInfoCache.get(target) != null) {
- connector.sendCommand(dispInfoCache.get(target).replace(ALBUM_ART_ID,
- (OFFSET_ZERO + Integer.toHexString(albumArtIds.get(target)))));
+ connector.sendCommand(dispInfoCache.getOrDefault(target, BLANK).replace(
+ ALBUM_ART_ID,
+ (OFFSET_ZERO + Integer.toHexString(albumArtIds.getOrDefault(target, 0)))));
}
} else {
albumArtMap.put(target, NO_ART);
break;
case TYPE_NN_MENU_ITEM_SELECTED:
// ignore this update unless openHAB is handling this source
- if (nuvoNetSrcMap.get(source).equals(2)) {
+ if (nuvoNetSrcMap.getOrDefault(source, 0).equals(2)) {
String[] updateDataSplit = updateData.split(COMMA);
String menuId = updateDataSplit[0];
int menuItemIdx = Integer.parseInt(updateDataSplit[1]) - 1;
break;
case TYPE_NN_MENUREQ:
// ignore this update unless openHAB is handling this source
- if (nuvoNetSrcMap.get(source).equals(2)) {
+ if (nuvoNetSrcMap.getOrDefault(source, 0).equals(2)) {
logger.debug("Menu Request: Source: {} - Value: {}", source.getNum(), updateData);
// For now we only support one level deep menus. If second field is '1', indicates go back to main
// menu.
// if this zone is a member of a group (1-4), add the zone's enum to the appropriate group map
if (!ZERO.equals(matcher.group(3))) {
- nuvoGroupMap.get(matcher.group(3)).add(zone);
+ nuvoGroupMap.getOrDefault(matcher.group(3), new HashSet<>()).add(zone);
}
} else {
logger.debug("no match on message: {}", updateData);
break;
case TYPE_NN_ALBUM_ART_REQ:
// ignore this update unless openHAB is handling this source
- if (nuvoNetSrcMap.get(source).equals(2)) {
+ if (nuvoNetSrcMap.getOrDefault(source, 0).equals(2)) {
logger.debug("Album Art Request for Source: {} - Data: {}", source.getNum(), updateData);
// 0x620FD879,80,80,2,0x00C0C0C0,0,0,0,0,1
String[] albumArtReq = updateData.split(COMMA);
albumArtIds.put(source, Integer.decode(albumArtReq[0]));
try {
- if (albumArtMap.get(source).length > 1) {
- connector.sendCommand(source.getId() + ALBUM_ART_AVAILABLE + albumArtIds.get(source) + COMMA
- + albumArtMap.get(source).length);
+ if (albumArtMap.getOrDefault(source, NO_ART).length > 1) {
+ connector.sendCommand(
+ source.getId() + ALBUM_ART_AVAILABLE + albumArtIds.getOrDefault(source, 0) + COMMA
+ + albumArtMap.getOrDefault(source, NO_ART).length);
} else {
connector.sendCommand(source.getId() + ALBUM_ART_AVAILABLE + ZERO_COMMA);
}
break;
case TYPE_NN_ALBUM_ART_FRAG_REQ:
// ignore this update unless openHAB is handling this source
- if (nuvoNetSrcMap.get(source).equals(2)) {
+ if (nuvoNetSrcMap.getOrDefault(source, 0).equals(2)) {
logger.debug("Album Art Fragment Request for Source: {} - Data: {}", source.getNum(), updateData);
// 0x620FD879,0,750 (id, requested offset from start of image, byte length requested)
String[] albumArtFragReq = updateData.split(COMMA);
break;
case TYPE_NN_FAVORITE_REQ:
// ignore this update unless openHAB is handling this source
- if (nuvoNetSrcMap.get(source).equals(2)) {
+ if (nuvoNetSrcMap.getOrDefault(source, 0).equals(2)) {
logger.debug("Favorite request for source: {} - favoriteId: {}", source.getNum(), updateData);
try {
int playlistIdx = Integer.parseInt(updateData, 16) - 1000;
updateChannelState(source, CHANNEL_BUTTON_PRESS,
- PLAY_MUSIC_PRESET + favoriteMap.get(source)[playlistIdx]);
+ PLAY_MUSIC_PRESET + getFavorite(source, playlistIdx));
} catch (NumberFormatException nfe) {
logger.debug("Unable to parse favoriteId: {}", updateData);
}
try {
// set '1' flag for each source configured as an MPS4 NuvoNet source or openHAB NuvoNet source
- connector.sendCommand("SNUMBERS" + nuvoNetSrcMap.get(NuvoEnum.SOURCE1).compareTo(0) + COMMA
- + nuvoNetSrcMap.get(NuvoEnum.SOURCE2).compareTo(0) + COMMA
- + nuvoNetSrcMap.get(NuvoEnum.SOURCE3).compareTo(0) + COMMA
- + nuvoNetSrcMap.get(NuvoEnum.SOURCE4).compareTo(0) + COMMA
- + nuvoNetSrcMap.get(NuvoEnum.SOURCE5).compareTo(0) + COMMA
- + nuvoNetSrcMap.get(NuvoEnum.SOURCE6).compareTo(0));
+ connector.sendCommand("SNUMBERS" + nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE1, 0).compareTo(0) + COMMA
+ + nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE2, 0).compareTo(0) + COMMA
+ + nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE3, 0).compareTo(0) + COMMA
+ + nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE4, 0).compareTo(0) + COMMA
+ + nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE5, 0).compareTo(0) + COMMA
+ + nuvoNetSrcMap.getOrDefault(NuvoEnum.SOURCE6, 0).compareTo(0));
Thread.sleep(SLEEP_BETWEEN_CMD_MS);
} catch (NuvoException | InterruptedException e) {
logger.debug("Error sending SNUMBERS command");
if (matcher.find()) {
final String nowPlayingGuid = matcher.group(1);
- // If streaming (NowPlayingType=Radio), always retrieve because the same NowPlayingGuid can
+ // If streaming (not local mp3 or flac) always retrieve because the same NowPlayingGuid can
// get a different image written to it by Gracenote when the track changes
- if (!mps4ArtGuids.get(source).equals(nowPlayingGuid)
- || json.contains("NowPlayingType\",\"value\":\"Radio\"}")) {
+ if (!mps4ArtGuids.getOrDefault(source, BLANK).equals(nowPlayingGuid)
+ || !(json.contains("NowPlayingSrce\",\"value\":\"WMP\"")
+ || json.contains("NowPlayingSrce\",\"value\":\"Flac\""))) {
ContentResponse artResponse = httpClient
- .newRequest(String.format(GET_MCS_ART, mps4Host, nowPlayingGuid, instance)).method(GET)
- .timeout(10, TimeUnit.SECONDS).send();
+ .newRequest(String.format(GET_MCS_ART, mps4Host, nowPlayingGuid, instance,
+ bindingConf.imageHeight, bindingConf.imageWidth))
+ .method(GET).timeout(10, TimeUnit.SECONDS).send();
if (artResponse.getStatus() == OK_200) {
logger.debug("Retrieved album art for guid: {}", nowPlayingGuid);
logger.debug("Got error response {} when sending json command url: {}", commandResp.getStatus(), commandUrl);
return BLANK;
}
+
+ private String getFavorite(NuvoEnum source, int playlistIdx) {
+ final String[] favoritesArr = favoriteMap.get(source);
+ return favoritesArr != null ? favoritesArr[playlistIdx] : BLANK;
+ }
}