Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nuvo] Auto update source channel for grouped zones #14012

Merged
merged 2 commits into from
Dec 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions bundles/org.openhab.binding.nuvo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Up to 20 keypad zones can be controlled when zone expansion modules are used (if

The binding supports three different kinds of connections:

- serial connection,
- serial over IP connection,
- serial port connection
- serial over IP connection
- direct IP connection via a Nuvo MPS4 music server

For users without a serial connector on the server side, you can use a USB to serial adapter.
Expand All @@ -27,11 +27,6 @@ It has the `amplifier` id.
Discovery is not supported.
You have to add all things manually.

## Binding Configuration

There are no overall binding configuration settings that need to be set.
All settings are through thing configuration parameters.

## Thing Configuration

The thing has the following configuration parameters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public enum NuvoCommand {
PAGE_OFF("PAGE0"),
CFGTIME("CFGTIME"),
STATUS("STATUS"),
STATUS_QUERY("STATUS?"),
EQ_QUERY("EQ?"),
DISPINFO("DISPINFO"),
DISPLINE("DISPLINE"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ public class NuvoHandler extends BaseThingHandler implements NuvoMessageEventLis
private static final Pattern DISP_PATTERN = Pattern.compile("^DISPLINE(\\d{1}),\"(.*)\"$");
private static final Pattern DISP_INFO_PATTERN = Pattern
.compile("^DISPINFO,DUR(\\d{1,6}),POS(\\d{1,6}),STATUS(\\d{1,2})$");
private static final Pattern ZONE_CFG_PATTERN = Pattern.compile("^BASS(.*),TREB(.*),BAL(.*),LOUDCMP([0-1])$");
private static final Pattern ZONE_CFG_EQ_PATTERN = Pattern.compile("^BASS(.*),TREB(.*),BAL(.*),LOUDCMP([0-1])$");
private static final Pattern ZONE_CFG_PATTERN = Pattern.compile(
"^ENABLE1,NAME\"(.*)\",SLAVETO(.*),GROUP([0-4]),SOURCES(.*),XSRC(.*),IR(.*),DND(.*),LOCKED(.*),SLAVEEQ(.*)$");

private final Logger logger = LoggerFactory.getLogger(NuvoHandler.class);
private final NuvoStateDescriptionOptionProvider stateDescriptionProvider;
Expand All @@ -155,6 +157,7 @@ public class NuvoHandler extends BaseThingHandler implements NuvoMessageEventLis

private boolean isAnyOhNuvoNet = false;
private NuvoMenu nuvoMenus = new NuvoMenu();
private HashMap<String, Set<String>> nuvoGroupMap = new HashMap<String, Set<String>>();
private HashMap<String, Integer> nuvoNetSrcMap = new HashMap<String, Integer>();
private HashMap<String, String> favPrefixMap = new HashMap<String, String>();
private HashMap<String, String[]> favoriteMap = new HashMap<String, String[]>();
Expand Down Expand Up @@ -231,6 +234,11 @@ public void initialize() {
nuvoNetSrcMap.put("5", config.nuvoNetSrc5);
nuvoNetSrcMap.put("6", config.nuvoNetSrc6);

nuvoGroupMap.put("1", new HashSet<String>());
nuvoGroupMap.put("2", new HashSet<String>());
nuvoGroupMap.put("3", new HashSet<String>());
nuvoGroupMap.put("4", new HashSet<String>());

if (this.isMps4) {
logger.debug("Port set to {} configuring binding for MPS4 compatability", MPS4_PORT);

Expand Down Expand Up @@ -734,6 +742,18 @@ public void onNewMessageEvent(NuvoMessageEvent evt) {
updateChannelState(targetZone, CHANNEL_TYPE_POWER, ON);
updateChannelState(targetZone, CHANNEL_TYPE_SOURCE, matcher.group(1));

// check if this zone is in a group, if so update the other group member's selected source
nuvoGroupMap.forEach((groupId, groupZones) -> {
if (groupZones.contains(zoneId)) {
groupZones.forEach(z -> {
if (!zoneId.equals(z)) {
updateChannelState(NuvoEnum.valueOf(ZONE + z), CHANNEL_TYPE_SOURCE,
matcher.group(1));
}
});
}
});

if (MUTE.equals(matcher.group(2))) {
updateChannelState(targetZone, CHANNEL_TYPE_MUTE, ON);
} else {
Expand Down Expand Up @@ -851,7 +871,7 @@ public void onNewMessageEvent(NuvoMessageEvent evt) {
case TYPE_ZONE_CONFIG:
logger.debug("Zone Configuration: Zone: {} - Value: {}", zoneId, updateData);
// example: BASS1,TREB-2,BALR2,LOUDCMP1
Matcher matcher = ZONE_CFG_PATTERN.matcher(updateData);
Matcher matcher = ZONE_CFG_EQ_PATTERN.matcher(updateData);
if (matcher.find()) {
updateChannelState(NuvoEnum.valueOf(ZONE + zoneId), CHANNEL_TYPE_BASS, matcher.group(1));
updateChannelState(NuvoEnum.valueOf(ZONE + zoneId), CHANNEL_TYPE_TREBLE, matcher.group(2));
Expand All @@ -860,7 +880,18 @@ public void onNewMessageEvent(NuvoMessageEvent evt) {
updateChannelState(NuvoEnum.valueOf(ZONE + zoneId), CHANNEL_TYPE_LOUDNESS,
ONE.equals(matcher.group(4)) ? ON : OFF);
} else {
logger.debug("no match on message: {}", updateData);
matcher = ZONE_CFG_PATTERN.matcher(updateData);
// example: ENABLE1,NAME"Great Room",SLAVETO0,GROUP1,SOURCES63,XSRC0,IR1,DND0,LOCKED0,SLAVEEQ0
if (matcher.find()) {
// TODO: utilize other info such as zone name, available sources bitmask, etc.

// if this zone is a member of a group (1-4), add the zone's id to the appropriate group map
if (!ZERO.equals(matcher.group(3))) {
nuvoGroupMap.get(matcher.group(3)).add(zoneId);
}
} else {
logger.debug("no match on message: {}", updateData);
}
}
break;
case TYPE_NN_ALBUM_ART_REQ:
Expand Down Expand Up @@ -1145,6 +1176,8 @@ private void pollStatus() {
try {
connector.sendQuery(NuvoEnum.valueOf(ZONE + zoneNum), NuvoCommand.STATUS);
Thread.sleep(SLEEP_BETWEEN_CMD_MS);
connector.sendCfgCommand(NuvoEnum.valueOf(ZONE + zoneNum), NuvoCommand.STATUS_QUERY, BLANK);
Thread.sleep(SLEEP_BETWEEN_CMD_MS);
connector.sendCfgCommand(NuvoEnum.valueOf(ZONE + zoneNum), NuvoCommand.EQ_QUERY, BLANK);
Thread.sleep(SLEEP_BETWEEN_CMD_MS);
} catch (NuvoException | InterruptedException e) {
Expand Down