diff --git a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/AmplifierModel.java b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/AmplifierModel.java index 70ccfb5d68660..1c030f19518bf 100644 --- a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/AmplifierModel.java +++ b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/AmplifierModel.java @@ -12,11 +12,13 @@ */ package org.openhab.binding.monopriceaudio.internal.communication; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.IntStream; import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.monopriceaudio.internal.configuration.MonopriceAudioThingConfiguration; @@ -82,7 +84,7 @@ public List getSourceLabels(MonopriceAudioThingConfiguration config 2, false, List.of("1", "2", "3", "4", "5", "6")) { @Override public MonopriceAudioZoneDTO getZoneData(String newZoneData) { - MonopriceAudioZoneDTO zoneData = new MonopriceAudioZoneDTO(); + final MonopriceAudioZoneDTO zoneData = new MonopriceAudioZoneDTO(); Matcher matcher = MONOPRICE70_PATTERN.matcher(newZoneData); if (matcher.find()) { @@ -127,8 +129,8 @@ public List getSourceLabels(MonopriceAudioThingConfiguration config false, List.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16")) { @Override public MonopriceAudioZoneDTO getZoneData(String newZoneData) { - MonopriceAudioZoneDTO zoneData = new MonopriceAudioZoneDTO(); - Matcher matcher = XANTECH_PATTERN.matcher(newZoneData); + final MonopriceAudioZoneDTO zoneData = new MonopriceAudioZoneDTO(); + final Matcher matcher = XANTECH_PATTERN.matcher(newZoneData); if (matcher.find()) { zoneData.setZone(matcher.group(1)); @@ -156,8 +158,8 @@ public List getSourceLabels(MonopriceAudioThingConfiguration config // Used by 10761/DAX66 and DAX88 private static MonopriceAudioZoneDTO getMonopriceZoneData(String newZoneData) { - MonopriceAudioZoneDTO zoneData = new MonopriceAudioZoneDTO(); - Matcher matcher = MONOPRICE_PATTERN.matcher(newZoneData); + final MonopriceAudioZoneDTO zoneData = new MonopriceAudioZoneDTO(); + final Matcher matcher = MONOPRICE_PATTERN.matcher(newZoneData); if (matcher.find()) { zoneData.setZone(matcher.group(1)); @@ -191,31 +193,31 @@ private static MonopriceAudioZoneDTO getMonopriceZoneData(String newZoneData) { private static final Pattern XANTECH_PATTERN = Pattern.compile( "^#(\\d{1,2})ZS PR(\\d{1}) SS(\\d{1}) VO(\\d{1,2}) MU(\\d{1}) TR(\\d{1,2}) BS(\\d{1,2}) BA(\\d{1,2}) LS(\\d{1}) PS(\\d{1})+"); - private String cmdPrefix; - private String cmdSuffix; - private String queryPrefix; - private String querySuffix; - private String respPrefix; - private String powerCmd; - private String sourceCmd; - private String volumeCmd; - private String muteCmd; - private String trebleCmd; - private String bassCmd; - private String balanceCmd; - private String dndCmd; - private int maxVol; - private int minTone; - private int maxTone; - private int toneOffset; - private int minBal; - private int maxBal; - private int balOffset; - private int maxZones; - private int numSources; - private boolean padNumbers; - private List zoneIds; - private Map zoneIdMap = new HashMap<>(); + private final String cmdPrefix; + private final String cmdSuffix; + private final String queryPrefix; + private final String querySuffix; + private final String respPrefix; + private final String powerCmd; + private final String sourceCmd; + private final String volumeCmd; + private final String muteCmd; + private final String trebleCmd; + private final String bassCmd; + private final String balanceCmd; + private final String dndCmd; + private final int maxVol; + private final int minTone; + private final int maxTone; + private final int toneOffset; + private final int minBal; + private final int maxBal; + private final int balOffset; + private final int maxZones; + private final int numSources; + private final boolean padNumbers; + private final List zoneIds; + private final Map zoneIdMap; private static final String ON_STR = "1"; private static final String OFF_STR = "0"; @@ -256,11 +258,10 @@ private static MonopriceAudioZoneDTO getMonopriceZoneData(String newZoneData) { this.padNumbers = padNumbers; this.zoneIds = zoneIds; - int i = 1; - for (String zoneId : zoneIds) { - zoneIdMap.put(zoneId, "zone" + i); - i++; - } + // Build a map between the amp's physical zone IDs and the thing's logical zone names + final Map zoneIdMap = new HashMap<>(); + IntStream.range(0, zoneIds.size()).forEach(i -> zoneIdMap.put(zoneIds.get(i), "zone" + (i + 1))); + this.zoneIdMap = Collections.unmodifiableMap(zoneIdMap); } public abstract MonopriceAudioZoneDTO getZoneData(String newZoneData); @@ -378,26 +379,14 @@ public List getZoneIds() { } public String getFormattedValue(Integer value) { - if (padNumbers) { - return String.format("%02d", value); - } else { - return value.toString(); - } + return padNumbers ? String.format("%02d", value) : value.toString(); } public String getOnStr() { - if (padNumbers) { - return ON_STR_PAD; - } else { - return ON_STR; - } + return padNumbers ? ON_STR_PAD : ON_STR; } public String getOffStr() { - if (padNumbers) { - return OFF_STR_PAD; - } else { - return OFF_STR; - } + return padNumbers ? OFF_STR_PAD : OFF_STR; } } diff --git a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioConnector.java b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioConnector.java index 8b7c2c161d197..c6e8d03381b0e 100644 --- a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioConnector.java +++ b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioConnector.java @@ -52,7 +52,7 @@ public abstract class MonopriceAudioConnector { private boolean connected; private boolean pingResponseOnly; - private @Nullable AmplifierModel amp; + protected AmplifierModel amp = AmplifierModel.MONOPRICE; private @Nullable Thread readerThread; @@ -77,15 +77,6 @@ protected void setConnected(boolean connected) { this.pingResponseOnly = false; } - /** - * Set the AmplifierModel - * - * @param amp the AmplifierModel being used - */ - protected void setAmplifierModel(AmplifierModel amp) { - this.amp = amp; - } - /** * Set the thread that handles the feedback messages * @@ -177,7 +168,7 @@ protected int readInput(byte[] dataBuffer) throws MonopriceAudioException { public void sendPing() throws MonopriceAudioException { pingResponseOnly = true; // poll zone 1 status only to see if the amp responds - queryZone(amp.getZoneIds().get(0)); + queryZone(amp.getZoneIds().iterator().next()); } /** diff --git a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioDefaultConnector.java b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioDefaultConnector.java deleted file mode 100644 index 4b2202b1759b6..0000000000000 --- a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioDefaultConnector.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2010-2024 Contributors to the openHAB project - * - * See the NOTICE file(s) distributed with this work for additional - * information. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.openhab.binding.monopriceaudio.internal.communication; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.monopriceaudio.internal.MonopriceAudioException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class to create a default MonopriceAudioConnector before initialization is complete. - * - * @author Laurent Garnier - Initial contribution - * @author Michael Lobstein - Adapted for the MonopriceAudio binding - */ -@NonNullByDefault -public class MonopriceAudioDefaultConnector extends MonopriceAudioConnector { - - private final Logger logger = LoggerFactory.getLogger(MonopriceAudioDefaultConnector.class); - - @Override - public void open() throws MonopriceAudioException { - logger.warn( - "MonopriceAudio binding incorrectly configured. Please configure for Serial or IP over serial connection"); - setConnected(false); - } - - @Override - public void close() { - setConnected(false); - } - - @Override - public void sendCommand(@Nullable String zone, String cmd, @Nullable Integer value) { - logger.warn( - "MonopriceAudio binding incorrectly configured. Please configure for Serial or IP over serial connection"); - setConnected(false); - } -} diff --git a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioIpConnector.java b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioIpConnector.java index 5eea9d8d722d2..c72d6ac14908e 100644 --- a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioIpConnector.java +++ b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioIpConnector.java @@ -54,7 +54,16 @@ public MonopriceAudioIpConnector(@Nullable String address, int port, String uid, this.address = address; this.port = port; this.uid = uid; - setAmplifierModel(amp); + super.amp = amp; + } + + /** + * Default constructor for temporary connector object that gets replaced during initialize() + */ + public MonopriceAudioIpConnector() { + this.address = ""; + this.port = -1; + this.uid = ""; } @Override diff --git a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioSerialConnector.java b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioSerialConnector.java index f731548efaf66..e4914c46ae487 100644 --- a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioSerialConnector.java +++ b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/communication/MonopriceAudioSerialConnector.java @@ -58,7 +58,7 @@ public MonopriceAudioSerialConnector(SerialPortManager serialPortManager, String this.serialPortManager = serialPortManager; this.serialPortName = serialPortName; this.uid = uid; - setAmplifierModel(amp); + super.amp = amp; } @Override diff --git a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/handler/MonopriceAudioHandler.java b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/handler/MonopriceAudioHandler.java index b5506f1db04fb..b03f8bcdc22ae 100644 --- a/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/handler/MonopriceAudioHandler.java +++ b/bundles/org.openhab.binding.monopriceaudio/src/main/java/org/openhab/binding/monopriceaudio/internal/handler/MonopriceAudioHandler.java @@ -32,7 +32,6 @@ import org.openhab.binding.monopriceaudio.internal.MonopriceAudioStateDescriptionOptionProvider; import org.openhab.binding.monopriceaudio.internal.communication.AmplifierModel; import org.openhab.binding.monopriceaudio.internal.communication.MonopriceAudioConnector; -import org.openhab.binding.monopriceaudio.internal.communication.MonopriceAudioDefaultConnector; import org.openhab.binding.monopriceaudio.internal.communication.MonopriceAudioIpConnector; import org.openhab.binding.monopriceaudio.internal.communication.MonopriceAudioMessageEvent; import org.openhab.binding.monopriceaudio.internal.communication.MonopriceAudioMessageEventListener; @@ -87,7 +86,7 @@ public class MonopriceAudioHandler extends BaseThingHandler implements Monoprice private @Nullable ScheduledFuture reconnectJob; private @Nullable ScheduledFuture pollingJob; - private MonopriceAudioConnector connector = new MonopriceAudioDefaultConnector(); + private MonopriceAudioConnector connector = new MonopriceAudioIpConnector(); private Map zoneDataMap = Map.of(ZONE, new MonopriceAudioZoneDTO()); private Set ignoreZones = new HashSet<>(); @@ -214,11 +213,11 @@ public void dispose() { @Override public void handleCommand(ChannelUID channelUID, Command command) { - String channel = channelUID.getId(); - String[] channelSplit = channel.split(CHANNEL_DELIMIT); - String channelType = channelSplit[1]; - String zoneName = channelSplit[0]; - String zoneId = amp.getZoneIdFromZoneName(zoneName); + final String channel = channelUID.getId(); + final String[] channelSplit = channel.split(CHANNEL_DELIMIT); + final String channelType = channelSplit[1]; + final String zoneName = channelSplit[0]; + final String zoneId = amp.getZoneIdFromZoneName(zoneName); if (getThing().getStatus() != ThingStatus.ONLINE) { logger.debug("Thing is not ONLINE; command {} from channel {} is ignored", command, channel); @@ -237,166 +236,192 @@ public void handleCommand(ChannelUID channelUID, Command command) { return; } - Stream zoneStream = amp.getZoneIds().stream().limit(numZones); try { - switch (channelType) { - case CHANNEL_TYPE_POWER: - if (command instanceof OnOffType) { - connector.sendCommand(zoneId, amp.getPowerCmd(), command == OnOffType.ON ? ONE : ZERO); - zoneDataMap.get(zoneId) - .setPower(command == OnOffType.ON ? amp.getOnStr() : amp.getOffStr()); - } - break; - case CHANNEL_TYPE_SOURCE: - if (command instanceof DecimalType decimalCommand) { - final int value = decimalCommand.intValue(); - if (value >= ONE && value <= amp.getNumSources()) { - logger.debug("Got source command {} zone {}", value, zoneId); - connector.sendCommand(zoneId, amp.getSourceCmd(), value); - zoneDataMap.get(zoneId).setSource(amp.getFormattedValue(value)); + if (!"all".equals(zoneName)) { + MonopriceAudioZoneDTO dto = zoneDataMap.get(zoneId); + if (dto == null) { + logger.debug("no zoneData for zoneId: {}", zoneId); + return; + } + + switch (channelType) { + case CHANNEL_TYPE_POWER: + if (command instanceof OnOffType) { + connector.sendCommand(zoneId, amp.getPowerCmd(), command == OnOffType.ON ? ONE : ZERO); + dto.setPower(command == OnOffType.ON ? amp.getOnStr() : amp.getOffStr()); } - } - break; - case CHANNEL_TYPE_VOLUME: - if (command instanceof PercentType percentCommand) { - final int value = (int) Math - .round(percentCommand.doubleValue() / 100.0 * (amp.getMaxVol() - MIN_VOLUME)) - + MIN_VOLUME; - logger.debug("Got volume command {} zone {}", value, zoneId); - connector.sendCommand(zoneId, amp.getVolumeCmd(), value); - zoneDataMap.get(zoneId).setVolume(value); - } - break; - case CHANNEL_TYPE_MUTE: - if (command instanceof OnOffType) { - connector.sendCommand(zoneId, amp.getMuteCmd(), command == OnOffType.ON ? ONE : ZERO); - zoneDataMap.get(zoneId).setMute(command == OnOffType.ON ? amp.getOnStr() : amp.getOffStr()); - } - break; - case CHANNEL_TYPE_TREBLE: - if (command instanceof DecimalType decimalCommand) { - final int value = decimalCommand.intValue(); - if (value >= amp.getMinTone() && value <= amp.getMaxTone()) { - logger.debug("Got treble command {} zone {}", value, zoneId); - connector.sendCommand(zoneId, amp.getTrebleCmd(), value + amp.getToneOffset()); - zoneDataMap.get(zoneId).setTreble(value + amp.getToneOffset()); + break; + case CHANNEL_TYPE_SOURCE: + if (command instanceof DecimalType decimalCommand) { + final int value = decimalCommand.intValue(); + if (value >= ONE && value <= amp.getNumSources()) { + logger.debug("Got source command {} zone {}", value, zoneId); + connector.sendCommand(zoneId, amp.getSourceCmd(), value); + dto.setSource(amp.getFormattedValue(value)); + } } - } - break; - case CHANNEL_TYPE_BASS: - if (command instanceof DecimalType decimalCommand) { - final int value = decimalCommand.intValue(); - if (value >= amp.getMinTone() && value <= amp.getMaxTone()) { - logger.debug("Got bass command {} zone {}", value, zoneId); - connector.sendCommand(zoneId, amp.getBassCmd(), value + amp.getToneOffset()); - zoneDataMap.get(zoneId).setBass(value + amp.getToneOffset()); + break; + case CHANNEL_TYPE_VOLUME: + if (command instanceof PercentType percentCommand) { + final int value = (int) Math + .round(percentCommand.doubleValue() / 100.0 * (amp.getMaxVol() - MIN_VOLUME)) + + MIN_VOLUME; + logger.debug("Got volume command {} zone {}", value, zoneId); + connector.sendCommand(zoneId, amp.getVolumeCmd(), value); + dto.setVolume(value); } - } - break; - case CHANNEL_TYPE_BALANCE: - if (command instanceof DecimalType decimalCommand) { - final int value = decimalCommand.intValue(); - if (value >= amp.getMinBal() && value <= amp.getMaxBal()) { - logger.debug("Got balance command {} zone {}", value, zoneId); - connector.sendCommand(zoneId, amp.getBalanceCmd(), value + amp.getBalOffset()); - zoneDataMap.get(zoneId).setBalance(value + amp.getBalOffset()); + break; + case CHANNEL_TYPE_MUTE: + if (command instanceof OnOffType) { + connector.sendCommand(zoneId, amp.getMuteCmd(), command == OnOffType.ON ? ONE : ZERO); + dto.setMute(command == OnOffType.ON ? amp.getOnStr() : amp.getOffStr()); } - } - break; - case CHANNEL_TYPE_DND: - if (command instanceof OnOffType) { - connector.sendCommand(zoneId, amp.getDndCmd(), command == OnOffType.ON ? ONE : ZERO); - zoneDataMap.get(zoneId).setDnd(command == OnOffType.ON ? amp.getOnStr() : amp.getOffStr()); - } - break; - case CHANNEL_TYPE_ALLPOWER: - if (command instanceof OnOffType) { - final int cmd = command == OnOffType.ON ? ONE : ZERO; - zoneStream.forEach((streamZoneId) -> { - if (command == OnOffType.OFF || !ignoreZones.contains(amp.getZoneName(streamZoneId))) { - try { - connector.sendCommand(streamZoneId, amp.getPowerCmd(), cmd); - zoneDataMap.get(streamZoneId).setPower(amp.getFormattedValue(cmd)); - updateChannelState(streamZoneId, CHANNEL_TYPE_POWER); - - if (command == OnOffType.ON) { - // reset the volume of each zone to allVolume - connector.sendCommand(streamZoneId, amp.getVolumeCmd(), allVolume); - zoneDataMap.get(streamZoneId).setVolume(allVolume); - updateChannelState(streamZoneId, CHANNEL_TYPE_VOLUME); - } - } catch (MonopriceAudioException e) { - logger.debug("Error Turning All Zones On: {}", e.getMessage()); - } + break; + case CHANNEL_TYPE_TREBLE: + if (command instanceof DecimalType decimalCommand) { + final int value = decimalCommand.intValue(); + if (value >= amp.getMinTone() && value <= amp.getMaxTone()) { + logger.debug("Got treble command {} zone {}", value, zoneId); + connector.sendCommand(zoneId, amp.getTrebleCmd(), value + amp.getToneOffset()); + dto.setTreble(value + amp.getToneOffset()); + } + } + break; + case CHANNEL_TYPE_BASS: + if (command instanceof DecimalType decimalCommand) { + final int value = decimalCommand.intValue(); + if (value >= amp.getMinTone() && value <= amp.getMaxTone()) { + logger.debug("Got bass command {} zone {}", value, zoneId); + connector.sendCommand(zoneId, amp.getBassCmd(), value + amp.getToneOffset()); + dto.setBass(value + amp.getToneOffset()); } + } + break; + case CHANNEL_TYPE_BALANCE: + if (command instanceof DecimalType decimalCommand) { + final int value = decimalCommand.intValue(); + if (value >= amp.getMinBal() && value <= amp.getMaxBal()) { + logger.debug("Got balance command {} zone {}", value, zoneId); + connector.sendCommand(zoneId, amp.getBalanceCmd(), value + amp.getBalOffset()); + dto.setBalance(value + amp.getBalOffset()); + } + } + break; + case CHANNEL_TYPE_DND: + if (command instanceof OnOffType) { + connector.sendCommand(zoneId, amp.getDndCmd(), command == OnOffType.ON ? ONE : ZERO); + dto.setDnd(command == OnOffType.ON ? amp.getOnStr() : amp.getOffStr()); + } + break; + default: + success = false; + logger.debug("Command {} from channel {} failed: unexpected command", command, channel); + break; + } + } else { + Stream zoneStream = amp.getZoneIds().stream().limit(numZones); - }); - } - break; - case CHANNEL_TYPE_ALLSOURCE: - if (command instanceof DecimalType decimalCommand) { - final int value = decimalCommand.intValue(); - if (value >= ONE && value <= amp.getNumSources()) { + switch (channelType) { + case CHANNEL_TYPE_ALLPOWER: + if (command instanceof OnOffType) { + final int cmd = command == OnOffType.ON ? ONE : ZERO; zoneStream.forEach((streamZoneId) -> { - if (!ignoreZones.contains(amp.getZoneName(streamZoneId))) { + if (command == OnOffType.OFF + || !ignoreZones.contains(amp.getZoneName(streamZoneId))) { try { - connector.sendCommand(streamZoneId, amp.getSourceCmd(), value); - if (zoneDataMap.get(streamZoneId).isPowerOn() - && !zoneDataMap.get(streamZoneId).isMuted()) { - zoneDataMap.get(streamZoneId).setSource(amp.getFormattedValue(value)); - updateChannelState(streamZoneId, CHANNEL_TYPE_SOURCE); + MonopriceAudioZoneDTO streamDto = zoneDataMap.get(streamZoneId); + if (streamDto != null) { + connector.sendCommand(streamZoneId, amp.getPowerCmd(), cmd); + streamDto.setPower(amp.getFormattedValue(cmd)); + updateChannelState(streamZoneId, CHANNEL_TYPE_POWER); + + if (command == OnOffType.ON) { + // reset the volume of each zone to allVolume + connector.sendCommand(streamZoneId, amp.getVolumeCmd(), allVolume); + streamDto.setVolume(allVolume); + updateChannelState(streamZoneId, CHANNEL_TYPE_VOLUME); + } } } catch (MonopriceAudioException e) { - logger.debug("Error Setting Source for All Zones: {}", e.getMessage()); + logger.debug("Error Turning All Zones On: {}", e.getMessage()); } } + }); } - } - break; - case CHANNEL_TYPE_ALLVOLUME: - if (command instanceof PercentType percentCommand) { - allVolume = (int) Math - .round(percentCommand.doubleValue() / 100.0 * (amp.getMaxVol() - MIN_VOLUME)) - + MIN_VOLUME; - zoneStream.forEach((streamZoneId) -> { - if (!ignoreZones.contains(amp.getZoneName(streamZoneId))) { - try { - connector.sendCommand(streamZoneId, amp.getVolumeCmd(), allVolume); - if (zoneDataMap.get(streamZoneId).isPowerOn() - && !zoneDataMap.get(streamZoneId).isMuted()) { - zoneDataMap.get(streamZoneId).setVolume(allVolume); - updateChannelState(streamZoneId, CHANNEL_TYPE_VOLUME); + break; + case CHANNEL_TYPE_ALLSOURCE: + if (command instanceof DecimalType decimalCommand) { + final int value = decimalCommand.intValue(); + if (value >= ONE && value <= amp.getNumSources()) { + zoneStream.forEach((streamZoneId) -> { + if (!ignoreZones.contains(amp.getZoneName(streamZoneId))) { + try { + MonopriceAudioZoneDTO streamDto = zoneDataMap.get(streamZoneId); + if (streamDto != null) { + connector.sendCommand(streamZoneId, amp.getSourceCmd(), value); + if (streamDto.isPowerOn() && !streamDto.isMuted()) { + streamDto.setSource(amp.getFormattedValue(value)); + updateChannelState(streamZoneId, CHANNEL_TYPE_SOURCE); + } + } + } catch (MonopriceAudioException e) { + logger.debug("Error Setting Source for All Zones: {}", e.getMessage()); + } } - } catch (MonopriceAudioException e) { - logger.debug("Error Setting Volume for All Zones: {}", e.getMessage()); - } + }); } - }); - } - break; - case CHANNEL_TYPE_ALLMUTE: - if (command instanceof OnOffType) { - final int cmd = command == OnOffType.ON ? ONE : ZERO; - zoneStream.forEach((streamZoneId) -> { - if (!ignoreZones.contains(amp.getZoneName(streamZoneId))) { - try { - connector.sendCommand(streamZoneId, amp.getMuteCmd(), cmd); - if (zoneDataMap.get(streamZoneId).isPowerOn()) { - zoneDataMap.get(streamZoneId).setMute(amp.getFormattedValue(cmd)); - updateChannelState(streamZoneId, CHANNEL_TYPE_MUTE); + } + break; + case CHANNEL_TYPE_ALLVOLUME: + if (command instanceof PercentType percentCommand) { + allVolume = (int) Math + .round(percentCommand.doubleValue() / 100.0 * (amp.getMaxVol() - MIN_VOLUME)) + + MIN_VOLUME; + zoneStream.forEach((streamZoneId) -> { + if (!ignoreZones.contains(amp.getZoneName(streamZoneId))) { + try { + MonopriceAudioZoneDTO streamDto = zoneDataMap.get(streamZoneId); + if (streamDto != null) { + connector.sendCommand(streamZoneId, amp.getVolumeCmd(), allVolume); + if (streamDto.isPowerOn() && !streamDto.isMuted()) { + streamDto.setVolume(allVolume); + updateChannelState(streamZoneId, CHANNEL_TYPE_VOLUME); + } + } + } catch (MonopriceAudioException e) { + logger.debug("Error Setting Volume for All Zones: {}", e.getMessage()); } - } catch (MonopriceAudioException e) { - logger.debug("Error Setting Mute for All Zones: {}", e.getMessage()); } - } - }); - } - break; - default: - success = false; - logger.debug("Command {} from channel {} failed: unexpected command", command, channel); - break; + }); + } + break; + case CHANNEL_TYPE_ALLMUTE: + if (command instanceof OnOffType) { + final int cmd = command == OnOffType.ON ? ONE : ZERO; + zoneStream.forEach((streamZoneId) -> { + if (!ignoreZones.contains(amp.getZoneName(streamZoneId))) { + try { + MonopriceAudioZoneDTO streamDto = zoneDataMap.get(streamZoneId); + if (streamDto != null) { + connector.sendCommand(streamZoneId, amp.getMuteCmd(), cmd); + if (streamDto.isPowerOn()) { + streamDto.setMute(amp.getFormattedValue(cmd)); + updateChannelState(streamZoneId, CHANNEL_TYPE_MUTE); + } + } + } catch (MonopriceAudioException e) { + logger.debug("Error Setting Mute for All Zones: {}", e.getMessage()); + } + } + }); + } + break; + default: + success = false; + logger.debug("Command {} from all channel {} failed: unexpected command", command, channel); + break; + } } if (success) { @@ -442,9 +467,8 @@ private synchronized void closeConnection() { @Override public void onNewMessageEvent(MonopriceAudioMessageEvent evt) { updateStatus(ThingStatus.ONLINE); - String key = evt.getKey(); - switch (key) { + switch (evt.getKey()) { case MonopriceAudioConnector.KEY_ZONE_UPDATE: MonopriceAudioZoneDTO newZoneData = amp.getZoneData(evt.getValue()); MonopriceAudioZoneDTO zoneData = zoneDataMap.get(newZoneData.getZone()); @@ -455,7 +479,7 @@ public void onNewMessageEvent(MonopriceAudioMessageEvent evt) { processZoneUpdate(zoneData, newZoneData); } } else { - logger.debug("invalid event: {} for key: {} or zone data null", evt.getValue(), key); + logger.debug("invalid event: {} for key: {} or zone data null", evt.getValue(), evt.getKey()); } break; @@ -464,7 +488,7 @@ public void onNewMessageEvent(MonopriceAudioMessageEvent evt) { break; default: - logger.debug("onNewMessageEvent: unhandled key {}", key); + logger.debug("onNewMessageEvent: unhandled key {}", evt.getKey()); break; } }