diff --git a/bundles/org.openhab.binding.rotel/README.md b/bundles/org.openhab.binding.rotel/README.md index edc946d4c8ad6..c63bd6576f527 100644 --- a/bundles/org.openhab.binding.rotel/README.md +++ b/bundles/org.openhab.binding.rotel/README.md @@ -163,6 +163,8 @@ The following channels are available: | treble, mainZone#treble | Treble Adjustment | Number | Adjust the treble | INCREASE, DECREASE, value | | playControl | Playback Control | Player | Control the playback | PLAY, PAUSE, NEXT, PREVIOUS | | track | Current Track | Number | The current CD track number | | +| random | Random Mode | Switch | The current random mode | | +| repeat | Repeat Mode | String | The current repeat mode | TRACK, DISC, OFF | | mainZone#line1 | Front Panel Line 1 | String | The first line displayed on the device front panel | | | mainZone#line2 | Front Panel Line 2 | String | The second line displayed on the device front panel | | | frequency | Current Frequency | Number | The current frequency (in kHz) for digital source input | | @@ -179,8 +181,8 @@ Here are the list of channels available for each thing type: | a11 | power, source, volume, mute, bass, treble, brightness, tcbypass, balance, speakera, speakerb | | a12 | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance, speakera, speakerb | | a14 | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance, speakera, speakerb | -| cd11 | power, playControl, track, brightness | -| cd14 | power, playControl, track, brightness | +| cd11 | power, playControl, track, random, repeat, brightness | +| cd14 | power, playControl, track, random, repeat, brightness | | m8 | power, brightness | | p5 | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance | | ra11 | power, source, volume, mute, bass, treble, playControl, frequency, brightness, tcbypass, balance | @@ -193,7 +195,7 @@ Here are the list of channels available for each thing type: | rc1572 | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance | | rc1590 | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance | | rcd1570 | power, playControl, brightness | -| rcd1572 | power, playControl, track, brightness | +| rcd1572 | power, playControl, track, random, repeat, brightness | | rcx1500 | power, source, volume, mute, playControl | | rdd1580 | power, source, playControl, frequency | | rdg1520 | power, source, playControl | diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelBindingConstants.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelBindingConstants.java index 8f2169fbe2801..78e94b802eefe 100644 --- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelBindingConstants.java +++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelBindingConstants.java @@ -136,6 +136,8 @@ public class RotelBindingConstants { public static final String CHANNEL_TREBLE = "treble"; public static final String CHANNEL_PLAY_CONTROL = "playControl"; public static final String CHANNEL_TRACK = "track"; + public static final String CHANNEL_RANDOM = "random"; + public static final String CHANNEL_REPEAT = "repeat"; public static final String CHANNEL_FREQUENCY = "frequency"; public static final String CHANNEL_LINE1 = "mainZone#line1"; public static final String CHANNEL_LINE2 = "mainZone#line2"; @@ -259,6 +261,8 @@ public class RotelBindingConstants { public static final String KEY1_PLAY_STATUS = "play_status"; public static final String KEY2_PLAY_STATUS = "status"; public static final String KEY_TRACK = "track"; + public static final String KEY_RANDOM = "rnd"; + public static final String KEY_REPEAT = "rpt"; public static final String KEY_DIMMER = "dimmer"; public static final String KEY_FREQ = "freq"; public static final String KEY_FREQ_ZONE1 = "freq_zone1"; @@ -306,6 +310,8 @@ public class RotelBindingConstants { public static final String PLAY = "play"; public static final String PAUSE = "pause"; public static final String STOP = "stop"; + public static final String TRACK = "track"; + public static final String DISC = "disc"; public static final int MAX_NUMBER_OF_ZONES = 4; } diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelRepeatMode.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelRepeatMode.java new file mode 100644 index 0000000000000..96419af540dda --- /dev/null +++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelRepeatMode.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2010-2022 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.rotel.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * Represents the different repeat modes + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +public enum RotelRepeatMode { + TRACK, + DISC, + OFF; + + /** + * Get the repeat mode from its name + * + * @param name the searched name (case is ignored) + * + * @return the repeat mode associated to the searched name + * + * @throws RotelException - If no repeat mode is associated to the searched name + */ + public static RotelRepeatMode getFromName(String name) throws RotelException { + for (RotelRepeatMode value : RotelRepeatMode.values()) { + if (value.name().equalsIgnoreCase(name)) { + return value; + } + } + throw new RotelException("Invalid name for a repeat mode: " + name); + } +} diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelCommand.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelCommand.java index 48cce171f789c..742e9fe108bfa 100644 --- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelCommand.java +++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelCommand.java @@ -267,6 +267,10 @@ public enum RotelCommand { PAUSE("Pause Source", PRIMARY_CMD, (byte) 0x05, "pause", "pause"), CD_PLAY_STATUS("Request CD play status", "get_cd_play_status", null), PLAY_STATUS("Request source play status", "get_play_status", "status?"), + RANDOM_TOGGLE("Random Play Mode Toggle", PRIMARY_CMD, (byte) 0x25, "random", "rnd"), + RANDOM_MODE("Request current random play mode", null, "rnd?"), + REPEAT_TOGGLE("Repeat Play Mode Toggle", PRIMARY_CMD, (byte) 0x26, "repeat", "rpt"), + REPEAT_MODE("Request current repeat play mode", null, "rpt?"), TRACK_FORWARD("Track Forward", PRIMARY_CMD, (byte) 0x09, "track_fwd", "trkf"), TRACK_BACKWORD("Track Backward", PRIMARY_CMD, (byte) 0x08, "track_back", "trkb"), TRACK("Request current CD track number", null, "track?"), diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSimuConnector.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSimuConnector.java index 1821d0294cf8a..6e210d21fb371 100644 --- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSimuConnector.java +++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSimuConnector.java @@ -28,6 +28,7 @@ import org.openhab.binding.rotel.internal.RotelException; import org.openhab.binding.rotel.internal.RotelModel; import org.openhab.binding.rotel.internal.RotelPlayStatus; +import org.openhab.binding.rotel.internal.RotelRepeatMode; import org.openhab.binding.rotel.internal.protocol.RotelAbstractProtocolHandler; import org.openhab.binding.rotel.internal.protocol.RotelProtocol; import org.openhab.binding.rotel.internal.protocol.hex.RotelHexProtocolHandler; @@ -71,6 +72,8 @@ public class RotelSimuConnector extends RotelConnector { private boolean speakerB = false; private RotelPlayStatus playStatus = RotelPlayStatus.STOPPED; private int track = 1; + private boolean randomMode; + private RotelRepeatMode repeatMode = RotelRepeatMode.OFF; private boolean selectingRecord; private int showZone; private int dimmer; @@ -780,6 +783,30 @@ public void buildFeedbackMessage(RotelCommand cmd, @Nullable Integer value) { case TRACK: textAscii = buildTrackAsciiResponse(); break; + case RANDOM_TOGGLE: + randomMode = !randomMode; + textAscii = buildRandomModeAsciiResponse(); + break; + case RANDOM_MODE: + textAscii = buildRandomModeAsciiResponse(); + break; + case REPEAT_TOGGLE: + switch (repeatMode) { + case TRACK: + repeatMode = RotelRepeatMode.DISC; + break; + case DISC: + repeatMode = RotelRepeatMode.OFF; + break; + case OFF: + repeatMode = RotelRepeatMode.TRACK; + break; + } + textAscii = buildRepeatModeAsciiResponse(); + break; + case REPEAT_MODE: + textAscii = buildRepeatModeAsciiResponse(); + break; case SOURCE_MULTI_INPUT: multiinput = !multiinput; text = "MULTI IN " + (multiinput ? "ON" : "OFF"); @@ -1174,6 +1201,26 @@ private String buildTrackAsciiResponse() { return buildAsciiResponse(KEY_TRACK, String.format("%03d", track)); } + private String buildRandomModeAsciiResponse() { + return buildAsciiResponse(KEY_RANDOM, randomMode); + } + + private String buildRepeatModeAsciiResponse() { + String mode = ""; + switch (repeatMode) { + case TRACK: + mode = TRACK; + break; + case DISC: + mode = DISC; + break; + case OFF: + mode = MSG_VALUE_OFF; + break; + } + return buildAsciiResponse(KEY_REPEAT, mode); + } + private String buildSourceAsciiResponse() { if (model.getNumberOfZones() > 1) { StringJoiner sj = new StringJoiner(","); diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/handler/RotelHandler.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/handler/RotelHandler.java index 6a2d2392b4ed2..518cc6a026dba 100644 --- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/handler/RotelHandler.java +++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/handler/RotelHandler.java @@ -29,6 +29,7 @@ import org.openhab.binding.rotel.internal.RotelException; import org.openhab.binding.rotel.internal.RotelModel; import org.openhab.binding.rotel.internal.RotelPlayStatus; +import org.openhab.binding.rotel.internal.RotelRepeatMode; import org.openhab.binding.rotel.internal.RotelStateDescriptionOptionProvider; import org.openhab.binding.rotel.internal.communication.RotelCommand; import org.openhab.binding.rotel.internal.communication.RotelConnector; @@ -112,6 +113,8 @@ public class RotelHandler extends BaseThingHandler implements RotelMessageEventL private int[] trebles = { 0, 0, 0, 0, 0 }; private RotelPlayStatus playStatus = RotelPlayStatus.STOPPED; private int track; + private boolean randomMode; + private RotelRepeatMode repeatMode = RotelRepeatMode.OFF; private double[] frequencies = { 0.0, 0.0, 0.0, 0.0, 0.0 }; private String frontPanelLine1 = ""; private String frontPanelLine2 = ""; @@ -790,6 +793,48 @@ public void handleCommand(ChannelUID channelUID, Command command) { logger.debug("Command {} from channel {} failed: invalid command value", command, channel); } break; + case CHANNEL_RANDOM: + if (!isPowerOn()) { + success = false; + logger.debug("Command {} from channel {} ignored: device in standby", command, channel); + } else if (command instanceof OnOffType) { + sendCommand(RotelCommand.RANDOM_TOGGLE); + } else { + success = false; + logger.debug("Command {} from channel {} failed: invalid command value", command, channel); + } + break; + case CHANNEL_REPEAT: + if (!isPowerOn()) { + success = false; + logger.debug("Command {} from channel {} ignored: device in standby", command, channel); + } else { + RotelRepeatMode currentMode = repeatMode; + RotelRepeatMode mode = RotelRepeatMode.OFF; + try { + mode = RotelRepeatMode.getFromName(command.toString()); + if (mode == currentMode) { + success = false; + logger.debug("Command {} from channel {} ignored: no change requested", command, + channel); + } + } catch (RotelException e) { + success = false; + logger.debug("Command {} from channel {} failed: invalid command value", command, + channel); + } + if (success) { + // Toggle TRACK -> DISC -> OFF + sendCommand(RotelCommand.REPEAT_TOGGLE); + if ((mode == RotelRepeatMode.OFF && currentMode == RotelRepeatMode.TRACK) + || (mode == RotelRepeatMode.TRACK && currentMode == RotelRepeatMode.DISC) + || (mode == RotelRepeatMode.DISC && currentMode == RotelRepeatMode.OFF)) { + Thread.sleep(SLEEP_INTV); + sendCommand(RotelCommand.REPEAT_TOGGLE); + } + } + } + break; case CHANNEL_BRIGHTNESS: case CHANNEL_ALL_BRIGHTNESS: if (!isPowerOn()) { @@ -1455,6 +1500,31 @@ public void onNewMessageEvent(EventObject event) { updateChannelState(CHANNEL_TRACK); } break; + case KEY_RANDOM: + if (MSG_VALUE_ON.equalsIgnoreCase(value)) { + randomMode = true; + updateChannelState(CHANNEL_RANDOM); + } else if (MSG_VALUE_OFF.equalsIgnoreCase(value)) { + randomMode = false; + updateChannelState(CHANNEL_RANDOM); + } else { + throw new RotelException("Invalid value"); + } + break; + case KEY_REPEAT: + if (TRACK.equalsIgnoreCase(value)) { + repeatMode = RotelRepeatMode.TRACK; + updateChannelState(CHANNEL_REPEAT); + } else if (DISC.equalsIgnoreCase(value)) { + repeatMode = RotelRepeatMode.DISC; + updateChannelState(CHANNEL_REPEAT); + } else if (MSG_VALUE_OFF.equalsIgnoreCase(value)) { + repeatMode = RotelRepeatMode.OFF; + updateChannelState(CHANNEL_REPEAT); + } else { + throw new RotelException("Invalid value"); + } + break; case KEY_FREQ: case KEY_FREQ_ZONE1: case KEY_FREQ_ZONE2: @@ -1596,6 +1666,8 @@ private void handlePowerOff() { updateChannelState(CHANNEL_TREBLE); updateChannelState(CHANNEL_PLAY_CONTROL); updateChannelState(CHANNEL_TRACK); + updateChannelState(CHANNEL_RANDOM); + updateChannelState(CHANNEL_REPEAT); updateChannelState(CHANNEL_FREQUENCY); updateChannelState(CHANNEL_BRIGHTNESS); updateChannelState(CHANNEL_TCBYPASS); @@ -1837,6 +1909,10 @@ private void schedulePowerOnJob() { if (source != null && source.getName().equals("CD") && !model.hasSourceControl()) { sendCommand(RotelCommand.TRACK); Thread.sleep(SLEEP_INTV); + sendCommand(RotelCommand.RANDOM_MODE); + Thread.sleep(SLEEP_INTV); + sendCommand(RotelCommand.REPEAT_MODE); + Thread.sleep(SLEEP_INTV); } } if (model.hasDspControl()) { @@ -2114,6 +2190,16 @@ private void updateChannelState(String channel) { state = new DecimalType(track); } break; + case CHANNEL_RANDOM: + if (isPowerOn()) { + state = OnOffType.from(randomMode); + } + break; + case CHANNEL_REPEAT: + if (isPowerOn()) { + state = new StringType(repeatMode.name()); + } + break; case CHANNEL_PLAY_CONTROL: if (isPowerOn()) { switch (playStatus) { diff --git a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/i18n/rotel.properties b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/i18n/rotel.properties index 8005555167065..c60d8d3d6cf36 100644 --- a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/i18n/rotel.properties +++ b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/i18n/rotel.properties @@ -11,6 +11,8 @@ thing-type.rotel.a12.label = A12 Integrated Amplifier thing-type.rotel.a12.description = Connection to the Rotel A12 or A12MKII integrated amplifier thing-type.rotel.a14.label = A14 Integrated Amplifier thing-type.rotel.a14.description = Connection to the Rotel A14 or A14MKII integrated amplifier +thing-type.rotel.c8.label = C8 Distribution Amplifier +thing-type.rotel.c8.description = Connection to the Rotel C8 or C8+ distribution amplifier thing-type.rotel.cd11.label = CD11 CD Player thing-type.rotel.cd11.description = Connection to the Rotel CD11 CD player thing-type.rotel.cd14.label = CD14 CD Player @@ -112,8 +114,15 @@ channel-type.rotel.frequency.label = Current Frequency channel-type.rotel.frequency.description = The current frequency (in kHz) for digital source input channel-type.rotel.frontPanelLine.label = Front Panel Line channel-type.rotel.frontPanelLine.description = The line content displayed on the device front panel +channel-type.rotel.random.label = Random Mode +channel-type.rotel.random.description = The current random mode channel-type.rotel.recordSource.label = Record Source channel-type.rotel.recordSource.description = Select the source to be recorded +channel-type.rotel.repeat.label = Repeat Mode +channel-type.rotel.repeat.description = The current repeat mode +channel-type.rotel.repeat.state.option.TRACK = Track +channel-type.rotel.repeat.state.option.DISC = Disc +channel-type.rotel.repeat.state.option.OFF = Off channel-type.rotel.source.label = Source Input channel-type.rotel.source.description = Select the source input channel-type.rotel.speakera.label = Speaker-A Adjustment diff --git a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/cd11.xml b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/cd11.xml index 6a401b1d28d7d..634fa228cb655 100644 --- a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/cd11.xml +++ b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/cd11.xml @@ -13,6 +13,8 @@ + + diff --git a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/cd14.xml b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/cd14.xml index 4d0a2b9079329..416501567112d 100644 --- a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/cd14.xml +++ b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/cd14.xml @@ -13,6 +13,8 @@ + + diff --git a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/channels.xml b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/channels.xml index 8cdfe8a9ee491..b0132fea9566e 100644 --- a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/channels.xml +++ b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/channels.xml @@ -205,6 +205,26 @@ + + Switch + + The current random mode + + + + + String + + The current repeat mode + + + + + + + + + Number diff --git a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/rcd1572.xml b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/rcd1572.xml index 34932be3e25aa..4a2ac1d8eaabc 100644 --- a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/rcd1572.xml +++ b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/rcd1572.xml @@ -13,6 +13,8 @@ + +