diff --git a/bundles/org.openhab.binding.nuvo/README.md b/bundles/org.openhab.binding.nuvo/README.md index e705a9c37f6..72c60c788f0 100644 --- a/bundles/org.openhab.binding.nuvo/README.md +++ b/bundles/org.openhab.binding.nuvo/README.md @@ -160,8 +160,8 @@ String nuvo_s1_display_line2 "Line 2: [%s]" { channel="nuvo:amplifier:myamp:sour String nuvo_s1_display_line3 "Line 3: [%s]" { channel="nuvo:amplifier:myamp:source1#display_line3" } String nuvo_s1_display_line4 "Line 4: [%s]" { channel="nuvo:amplifier:myamp:source1#display_line4" } String nuvo_s1_play_mode "Play Mode: [%s]" { channel="nuvo:amplifier:myamp:source1#play_mode" } -Number:Time nuvo_s1_track_length "Track Length: [%s s]" { channel="nuvo:amplifier:myamp:source1#track_length" } -Number:Time nuvo_s1_track_position "Track Position: [%s s]" { channel="nuvo:amplifier:myamp:source1#track_position" } +Number:Time nuvo_s1_track_length "Track Length: [%d %unit%]" { channel="nuvo:amplifier:myamp:source1#track_length" } +Number:Time nuvo_s1_track_position "Track Position: [%d %unit%]" { channel="nuvo:amplifier:myamp:source1#track_position" } String nuvo_s1_button_press "Button: [%s]" { channel="nuvo:amplifier:myamp:source1#button_press" } // String nuvo_s1_art_url "URL: [%s]" { channel="nuvo:amplifier:myamp:source1#art_url" } // Image nuvo_s1_album_art { channel="nuvo:amplifier:myamp:source1#album_art" } @@ -171,8 +171,8 @@ String nuvo_s2_display_line2 "Line 2: [%s]" { channel="nuvo:amplifier:myamp:sour String nuvo_s2_display_line3 "Line 3: [%s]" { channel="nuvo:amplifier:myamp:source2#display_line3" } String nuvo_s2_display_line4 "Line 4: [%s]" { channel="nuvo:amplifier:myamp:source2#display_line4" } String nuvo_s2_play_mode "Play Mode: [%s]" { channel="nuvo:amplifier:myamp:source2#play_mode" } -Number:Time nuvo_s2_track_length "Track Length: [%s s]" { channel="nuvo:amplifier:myamp:source2#track_length" } -Number:Time nuvo_s2_track_position "Track Position: [%s s]" { channel="nuvo:amplifier:myamp:source2#track_position" } +Number:Time nuvo_s2_track_length "Track Length: [%d %unit%]" { channel="nuvo:amplifier:myamp:source2#track_length" } +Number:Time nuvo_s2_track_position "Track Position: [%d %unit%]" { channel="nuvo:amplifier:myamp:source2#track_position" } String nuvo_s2_button_press "Button: [%s]" { channel="nuvo:amplifier:myamp:source2#button_press" } // String nuvo_s2_art_url "URL: [%s]" { channel="nuvo:amplifier:myamp:source2#art_url" } // Image nuvo_s2_album_art { channel="nuvo:amplifier:myamp:source2#album_art" } @@ -182,8 +182,8 @@ String nuvo_s3_display_line2 "Line 2: [%s]" { channel="nuvo:amplifier:myamp:sour String nuvo_s3_display_line3 "Line 3: [%s]" { channel="nuvo:amplifier:myamp:source3#display_line3" } String nuvo_s3_display_line4 "Line 4: [%s]" { channel="nuvo:amplifier:myamp:source3#display_line4" } String nuvo_s3_play_mode "Play Mode: [%s]" { channel="nuvo:amplifier:myamp:source3#play_mode" } -Number:Time nuvo_s3_track_length "Track Length: [%s s]" { channel="nuvo:amplifier:myamp:source3#track_length" } -Number:Time nuvo_s3_track_position "Track Position: [%s s]" { channel="nuvo:amplifier:myamp:source3#track_position" } +Number:Time nuvo_s3_track_length "Track Length: [%d %unit%]" { channel="nuvo:amplifier:myamp:source3#track_length" } +Number:Time nuvo_s3_track_position "Track Position: [%d %unit%]" { channel="nuvo:amplifier:myamp:source3#track_position" } String nuvo_s3_button_press "Button: [%s]" { channel="nuvo:amplifier:myamp:source3#button_press" } // String nuvo_s3_art_url "URL: [%s]" { channel="nuvo:amplifier:myamp:source3#art_url" } // Image nuvo_s3_album_art { channel="nuvo:amplifier:myamp:source3#album_art" } @@ -193,8 +193,8 @@ String nuvo_s4_display_line2 "Line 2: [%s]" { channel="nuvo:amplifier:myamp:sour String nuvo_s4_display_line3 "Line 3: [%s]" { channel="nuvo:amplifier:myamp:source4#display_line3" } String nuvo_s4_display_line4 "Line 4: [%s]" { channel="nuvo:amplifier:myamp:source4#display_line4" } String nuvo_s4_play_mode "Play Mode: [%s]" { channel="nuvo:amplifier:myamp:source4#play_mode" } -Number:Time nuvo_s4_track_length "Track Length: [%s s]" { channel="nuvo:amplifier:myamp:source4#track_length" } -Number:Time nuvo_s4_track_position "Track Position: [%s s]" { channel="nuvo:amplifier:myamp:source4#track_position" } +Number:Time nuvo_s4_track_length "Track Length: [%d %unit%]" { channel="nuvo:amplifier:myamp:source4#track_length" } +Number:Time nuvo_s4_track_position "Track Position: [%d %unit%]" { channel="nuvo:amplifier:myamp:source4#track_position" } String nuvo_s4_button_press "Button: [%s]" { channel="nuvo:amplifier:myamp:source4#button_press" } // String nuvo_s4_art_url "URL: [%s]" { channel="nuvo:amplifier:myamp:source4#art_url" } // Image nuvo_s4_album_art { channel="nuvo:amplifier:myamp:source4#album_art" } @@ -204,8 +204,8 @@ String nuvo_s5_display_line2 "Line 2: [%s]" { channel="nuvo:amplifier:myamp:sour String nuvo_s5_display_line3 "Line 3: [%s]" { channel="nuvo:amplifier:myamp:source5#display_line3" } String nuvo_s5_display_line4 "Line 4: [%s]" { channel="nuvo:amplifier:myamp:source5#display_line4" } String nuvo_s5_play_mode "Play Mode: [%s]" { channel="nuvo:amplifier:myamp:source5#play_mode" } -Number:Time nuvo_s5_track_length "Track Length: [%s s]" { channel="nuvo:amplifier:myamp:source5#track_length" } -Number:Time nuvo_s5_track_position "Track Position: [%s s]" { channel="nuvo:amplifier:myamp:source5#track_position" } +Number:Time nuvo_s5_track_length "Track Length: [%d %unit%]" { channel="nuvo:amplifier:myamp:source5#track_length" } +Number:Time nuvo_s5_track_position "Track Position: [%d %unit%]" { channel="nuvo:amplifier:myamp:source5#track_position" } String nuvo_s5_button_press "Button: [%s]" { channel="nuvo:amplifier:myamp:source5#button_press" } // String nuvo_s5_art_url "URL: [%s]" { channel="nuvo:amplifier:myamp:source5#art_url" } // Image nuvo_s5_album_art { channel="nuvo:amplifier:myamp:source5#album_art" } @@ -215,8 +215,8 @@ String nuvo_s6_display_line2 "Line 2: [%s]" { channel="nuvo:amplifier:myamp:sour String nuvo_s6_display_line3 "Line 3: [%s]" { channel="nuvo:amplifier:myamp:source6#display_line3" } String nuvo_s6_display_line4 "Line 4: [%s]" { channel="nuvo:amplifier:myamp:source6#display_line4" } String nuvo_s6_play_mode "Play Mode: [%s]" { channel="nuvo:amplifier:myamp:source6#play_mode" } -Number:Time nuvo_s6_track_length "Track Length: [%s s]" { channel="nuvo:amplifier:myamp:source6#track_length" } -Number:Time nuvo_s6_track_position "Track Position: [%s s]" { channel="nuvo:amplifier:myamp:source6#track_position" } +Number:Time nuvo_s6_track_length "Track Length: [%d %unit%]" { channel="nuvo:amplifier:myamp:source6#track_length" } +Number:Time nuvo_s6_track_position "Track Position: [%d %unit%]" { channel="nuvo:amplifier:myamp:source6#track_position" } String nuvo_s6_button_press "Button: [%s]" { channel="nuvo:amplifier:myamp:source6#button_press" } // String nuvo_s6_art_url "URL: [%s]" { channel="nuvo:amplifier:myamp:source6#art_url" } // Image nuvo_s6_album_art { channel="nuvo:amplifier:myamp:source6#album_art" } @@ -234,7 +234,7 @@ sitemap nuvo label="Audio Control" { } Frame label="Zone 1" { - Switch item=nuvo_z1_power visibility=[nuvo_z1_lock!="1"] + Switch item=nuvo_z1_power visibility=[nuvo_z1_lock!="OPEN"] // OPEN = Zone Locked // Selection item=nuvo_z1_source visibility=[nuvo_z1_power==ON] icon="player" // Volume can be a Setpoint also Slider item=nuvo_z1_volume minValue=0 maxValue=100 step=1 visibility=[nuvo_z1_power==ON] icon="soundvolume" @@ -304,7 +304,7 @@ sitemap nuvo label="Audio Control" { Switch item=nuvo_z1_dnd Switch item=nuvo_z1_party } - Text item=nuvo_z1_lock label="Zone Locked: [%s]" icon="lock" visibility=[nuvo_z1_lock=="1"] + Text item=nuvo_z1_lock label="Zone Locked: [%s]" icon="lock" visibility=[nuvo_z1_lock=="OPEN"] // Image item=nuvo_s1_album_art visibility=[nuvo_z1_source=="1"] // Image item=nuvo_s2_album_art visibility=[nuvo_z1_source=="2"] @@ -585,6 +585,10 @@ then sendCommand(music_Music_Repeat, ON) } } + // ALLOFF is sent by the amplifier 5 minutes after all zones are switched off + case "ALLOFF": { + sendCommand(music_Music_Control, PAUSE) + } // Handle menu item selections case "Top menu 1|menu1 a": { logInfo("nuvo src 6", "'Top menu 1, menu 1 a' was selected") diff --git a/bundles/org.openhab.binding.nuvo/src/main/java/org/openhab/binding/nuvo/internal/NuvoBindingConstants.java b/bundles/org.openhab.binding.nuvo/src/main/java/org/openhab/binding/nuvo/internal/NuvoBindingConstants.java index 92550304020..e0c78e2be7b 100644 --- a/bundles/org.openhab.binding.nuvo/src/main/java/org/openhab/binding/nuvo/internal/NuvoBindingConstants.java +++ b/bundles/org.openhab.binding.nuvo/src/main/java/org/openhab/binding/nuvo/internal/NuvoBindingConstants.java @@ -84,6 +84,7 @@ public class NuvoBindingConstants { // misc public static final String ON = "ON"; public static final String OFF = "OFF"; + public static final String ALLOFF = "ALLOFF"; public static final String TWO = "2"; public static final String ONE = "1"; public static final String ZERO = "0"; diff --git a/bundles/org.openhab.binding.nuvo/src/main/java/org/openhab/binding/nuvo/internal/handler/NuvoHandler.java b/bundles/org.openhab.binding.nuvo/src/main/java/org/openhab/binding/nuvo/internal/handler/NuvoHandler.java index dd666c46ada..f74cd282aac 100644 --- a/bundles/org.openhab.binding.nuvo/src/main/java/org/openhab/binding/nuvo/internal/handler/NuvoHandler.java +++ b/bundles/org.openhab.binding.nuvo/src/main/java/org/openhab/binding/nuvo/internal/handler/NuvoHandler.java @@ -157,7 +157,7 @@ public class NuvoHandler extends BaseThingHandler implements NuvoMessageEventLis private boolean isAnyOhNuvoNet = false; private NuvoMenu nuvoMenus = new NuvoMenu(); - private HashMap> nuvoGroupMap = new HashMap>(); + private HashMap> nuvoGroupMap = new HashMap>(); private HashMap nuvoNetSrcMap = new HashMap(); private HashMap favPrefixMap = new HashMap(); private HashMap favoriteMap = new HashMap(); @@ -234,10 +234,10 @@ public class NuvoHandler extends BaseThingHandler implements NuvoMessageEventLis nuvoNetSrcMap.put("5", config.nuvoNetSrc5); nuvoNetSrcMap.put("6", config.nuvoNetSrc6); - nuvoGroupMap.put("1", new HashSet()); - nuvoGroupMap.put("2", new HashSet()); - nuvoGroupMap.put("3", new HashSet()); - nuvoGroupMap.put("4", new HashSet()); + nuvoGroupMap.put("1", new HashSet()); + nuvoGroupMap.put("2", new HashSet()); + nuvoGroupMap.put("3", new HashSet()); + nuvoGroupMap.put("4", new HashSet()); if (this.isMps4) { logger.debug("Port set to {} configuring binding for MPS4 compatability", MPS4_PORT); @@ -427,6 +427,9 @@ public class NuvoHandler extends BaseThingHandler implements NuvoMessageEventLis if (value >= 1 && value <= MAX_SRC) { logger.debug("Got source command {} zone {}", value, target); connector.sendCommand(target, NuvoCommand.SOURCE, String.valueOf(value)); + + // update the other group member's selected source + updateSrcForZoneGroup(target, String.valueOf(value)); } } break; @@ -685,6 +688,13 @@ public class NuvoHandler extends BaseThingHandler implements NuvoMessageEventLis activeZones.forEach(zoneNum -> { updateChannelState(NuvoEnum.valueOf(ZONE + zoneNum), CHANNEL_TYPE_POWER, OFF); }); + + // Publish the ALLOFF event to all button channels for awareness in source rules + updateChannelState(NuvoEnum.SYSTEM, CHANNEL_TYPE_BUTTONPRESS, ZERO + COMMA + ALLOFF); + NuvoEnum.VALID_SOURCES.forEach(source -> { + updateChannelState(NuvoEnum.valueOf(source), CHANNEL_TYPE_BUTTONPRESS, ALLOFF); + }); + break; case TYPE_ALLMUTE: updateChannelState(NuvoEnum.SYSTEM, CHANNEL_TYPE_ALLMUTE, ONE.equals(updateData) ? ON : OFF); @@ -742,17 +752,8 @@ public class NuvoHandler extends BaseThingHandler implements NuvoMessageEventLis 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)); - } - }); - } - }); + // update the other group member's selected source + updateSrcForZoneGroup(targetZone, matcher.group(1)); if (MUTE.equals(matcher.group(2))) { updateChannelState(targetZone, CHANNEL_TYPE_MUTE, ON); @@ -885,9 +886,9 @@ public class NuvoHandler extends BaseThingHandler implements NuvoMessageEventLis 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 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(zoneId); + nuvoGroupMap.get(matcher.group(3)).add(NuvoEnum.valueOf(ZONE + zoneId)); } } else { logger.debug("no match on message: {}", updateData); @@ -1379,6 +1380,25 @@ public class NuvoHandler extends BaseThingHandler implements NuvoMessageEventLis updateState(channel, state); } + /** + * For grouped zones, update the source channel for all group members + * + * @param zoneEnum the zone where the source was changed + * @param srcId the new source number that was selected + */ + private void updateSrcForZoneGroup(NuvoEnum zoneEnum, String srcId) { + // 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(zoneEnum)) { + groupZones.forEach(z -> { + if (!zoneEnum.equals(z)) { + updateChannelState(z, CHANNEL_TYPE_SOURCE, srcId); + } + }); + } + }); + } + /** * Handle a button press from a UI Player item *