| 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 | |
| brightness | Front Panel Display Brightness | Dimmer | The backlight brightness level (in %) of the device front panel | |
+| tcbypass | Tone Control Bypass | Switch | The user's bass-/treble-settings are bypassed | ON, OFF |
+| balance | Stereo Balance Adjustment | Number | Adjust the balance | INCREASE, DECREASE, value |
+| speakera | Speaker-A Adjustment | Switch | Turn on/off the speaker group A | ON, OFF |
+| speakerb | Speaker-B Adjustment | Switch | Turn on/off the speaker group B | ON, OFF |
Here are the list of channels available for each thing type:
-| Thing Type | Available channels |
-|------------|---------------------------------------------------------------------------------------|
-| a11 | power, source, volume, mute, bass, treble, brightness |
-| a12 | power, source, volume, mute, bass, treble, frequency, brightness |
-| a14 | power, source, volume, mute, bass, treble, frequency, brightness |
-| cd11 | power, playControl, track, brightness |
-| cd14 | power, playControl, track, brightness |
-| ra11 | power, source, volume, mute, bass, treble, playControl, frequency, brightness |
-| ra12 | power, source, volume, mute, bass, treble, playControl, frequency, brightness |
-| ra1570 | power, source, volume, mute, bass, treble, playControl, frequency, brightness |
-| ra1572 | power, source, volume, mute, bass, treble, frequency, brightness |
-| ra1592 | power, source, volume, mute, bass, treble, frequency, brightness |
-| rap1580 | power, source, dsp, volume, mute, brightness |
-| rc1570 | power, source, volume, mute, bass, treble, playControl, frequency, brightness |
-| rc1572 | power, source, volume, mute, bass, treble, frequency, brightness |
-| rc1590 | power, source, volume, mute, bass, treble, frequency, brightness |
-| rcd1570 | power, playControl, brightness |
-| rcd1572 | power, playControl, track, brightness |
-| rcx1500 | power, source, volume, mute, playControl |
-| rdd1580 | power, source, playControl, frequency |
-| rdg1520 | power, source, playControl |
+| Thing Type | Available channels |
+|------------|---------------------------------------------------------------------------------------------------------|
+| 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 |
+| ra11 | power, source, volume, mute, bass, treble, playControl, frequency, brightness, tcbypass, balance |
+| ra12 | power, source, volume, mute, bass, treble, playControl, frequency, brightness, tcbypass, balance |
+| ra1570 | power, source, volume, mute, bass, treble, playControl, frequency, brightness, tcbypass, balance, speakera, speakerb |
+| ra1572 | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance, speakera, speakerb |
+| ra1592 | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance, speakera, speakerb |
+| rap1580 | power, source, dsp, volume, mute, brightness |
+| rc1570 | power, source, volume, mute, bass, treble, playControl, frequency, brightness, tcbypass, balance |
+| 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 |
+| rcx1500 | power, source, volume, mute, playControl |
+| rdd1580 | power, source, playControl, frequency |
+| rdg1520 | power, source, playControl |
| rsp1066 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volumeUpDown, mainZone#mute, mainZone#bass, mainZone#treble, mainZone#line1, zone2#power, zone2#source, zone2#volumeUpDown |
| rsp1068 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volume, mainZone#mute, mainZone#bass, mainZone#treble, mainZone#line1, mainZone#line2, zone2#power, zone2#source, zone2#volume, zone2#mute, zone3#power, zone3#source, zone3#volume, zone3#mute, zone4#power, zone4#source, zone4#volume, zone4#mute |
| rsp1069 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volume, mainZone#mute, mainZone#bass, mainZone#treble, mainZone#line1, mainZone#line2, zone2#power, zone2#source, zone2#volume, zone2#mute, zone3#power, zone3#source, zone3#volume, zone3#mute, zone4#power, zone4#source, zone4#volume, zone4#mute |
| rsp1098 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volume, mainZone#mute, mainZone#bass, mainZone#treble, mainZone#line1, zone2#power, zone2#source, zone2#volume, zone2#mute |
| rsp1570 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volume, mainZone#mute, mainZone#bass, mainZone#treble, mainZone#line1, mainZone#line2, zone2#power, zone2#source, zone2#volume, zone2#mute, zone3#power, zone3#source, zone3#volume, zone3#mute, zone4#power, zone4#source, zone4#volume, zone4#mute |
| rsp1572 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volume, mainZone#mute, mainZone#line1, mainZone#line2, zone2#power, zone2#source, zone2#volume, zone2#mute, zone3#power, zone3#source, zone3#volume, zone3#mute, zone4#power, zone4#source, zone4#volume, zone4#mute |
-| rsp1576 | power, source, dsp, volume, mute, brightness |
-| rsp1582 | power, source, dsp, volume, mute, brightness |
+| rsp1576 | power, source, dsp, volume, mute, brightness |
+| rsp1582 | power, source, dsp, volume, mute, brightness |
| rsx1055 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volumeUpDown, mainZone#mute, mainZone#bass, mainZone#treble, mainZone#line1, zone2#power, zone2#source, zone2#volumeUpDown |
| rsx1056 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volume, mainZone#mute, mainZone#bass, mainZone#treble, mainZone#line1, zone2#power, zone2#source, zone2#volume, zone2#mute |
| rsx1057 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volume, mainZone#mute, mainZone#bass, mainZone#treble, mainZone#line1, zone2#power, zone2#source, zone2#volume, zone2#mute |
| rsx1550 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volume, mainZone#mute, mainZone#bass, mainZone#treble, mainZone#line1, zone2#power, zone2#source, zone2#volume, zone2#mute, zone3#power, zone3#source, zone3#volume, zone3#mute, zone4#power, zone4#source, zone4#volume, zone4#mute |
| rsx1560 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volume, mainZone#mute, mainZone#bass, mainZone#treble, mainZone#line1, mainZone#line2, zone2#power, zone2#source, zone2#volume, zone2#mute, zone3#power, zone3#source, zone3#volume, zone3#mute, zone4#power, zone4#source, zone4#volume, zone4#mute |
| rsx1562 | mainZone#power, mainZone#source, mainZone#recordSource, mainZone#dsp, mainZone#volume, mainZone#mute, mainZone#line1, mainZone#line2, zone2#power, zone2#source, zone2#volume, zone2#mute, zone3#power, zone3#source, zone3#volume, zone3#mute, zone4#power, zone4#source, zone4#volume, zone4#mute |
-| rt09 | power, source, playControl, brightness |
-| rt11 | power, source, brightness |
-| rt1570 | power, source, brightness |
-| t11 | power, source, brightness |
-| t14 | power, source, brightness |
+| rt09 | power, source, playControl, brightness |
+| rt11 | power, source, brightness |
+| rt1570 | power, source, brightness |
+| t11 | power, source, brightness |
+| t14 | power, source, brightness |
## Full Example
Thing rotel:ra1592:preamp "RA-1592" [ serialPort="COM3" ]
Thing rotel:cd14:cd "CD14" [ serialPort="COM4" ]
+
+Thing rotel:a14:amp "A14" [ serialPort="/dev/ttyUSB0" ]
```
example.things using serial over IP connection:
Number amp_treble "Treble Adjustment [%d]" { channel="rotel:ra1592:preamp:treble" }
Dimmer amp_brightness "Display brightness" { channel="rotel:ra1592:preamp:brightness" }
+Switch amp_bypass "TCBypass" { channel="rotel:a14:amp:tcbypass" }
+Number amp_balance "Balance Adjustment [%d]" { channel="rotel:a14:amp:balance" }
+Switch amp_speakera "Speaker A" { channel="rotel:a14:amp:speakera" }
+Switch amp_speakerb "Speaker B" { channel="rotel:a14:amp:speakerb" }
+
Switch cd_power "Power" { channel="rotel:cd14:cd:power" }
Player cd_control "Playback" { channel="rotel:cd14:cd:power" }
Number cd_track "Track [%d]" { channel="rotel:cd14:cd:power" }
public static final String CHANNEL_ZONE4_SOURCE = "zone4#source";
public static final String CHANNEL_ZONE4_VOLUME = "zone4#volume";
public static final String CHANNEL_ZONE4_MUTE = "zone4#mute";
+ public static final String CHANNEL_TCBYPASS = "tcbypass";
+ public static final String CHANNEL_BALANCE = "balance";
+ public static final String CHANNEL_SPEAKER_A = "speakera";
+ public static final String CHANNEL_SPEAKER_B = "speakerb";
// List of all properties
public static final String PROPERTY_PROTOCOL = "protocol";
5, true, RotelFlagsMapping.MAPPING5),
RSX1562("RSX-1562", 115200, 2, 3, true, 96, true, null, false, RotelCommand.RECORD_FONCTION_SELECT, 4, (byte) 0xCC,
42, 5, true, RotelFlagsMapping.MAPPING5),
- A11("A11", 115200, 4, 96, true, 10, false, -1, false, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
- A12("A12", 115200, 5, 96, true, 10, false, -1, true, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
- A14("A14", 115200, 5, 96, true, 10, false, -1, true, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
+ A11("A11", 115200, 4, 96, true, 10, 15, false, -1, false, true, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
+ A12("A12", 115200, 5, 96, true, 10, 15, false, -1, true, true, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
+ A14("A14", 115200, 5, 96, true, 10, 15, false, -1, true, true, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
CD11("CD11", 57600, 0, null, false, null, true, -1, false, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
CD14("CD14", 57600, 0, null, false, null, true, -1, false, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
- RA11("RA-11", 115200, 6, 96, true, 10, true, -1, true, false, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
- RA12("RA-12", 115200, 6, 96, true, 10, true, -1, true, false, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
- RA1570("RA-1570", 115200, 7, 96, true, 10, true, -1, true, false, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
- RA1572("RA-1572", 115200, 8, 96, true, 10, false, -1, true, true, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
- RA1592("RA-1592", 115200, 9, 96, true, 10, false, -1, true, true, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
+ RA11("RA-11", 115200, 6, 96, true, 10, 15, true, -1, true, false, false, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
+ RA12("RA-12", 115200, 6, 96, true, 10, 15, true, -1, true, false, false, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
+ RA1570("RA-1570", 115200, 7, 96, true, 10, 15, true, -1, true, true, false, 6, 0,
+ RotelConnector.SPECIAL_CHARACTERS),
+ RA1572("RA-1572", 115200, 8, 96, true, 10, 15, false, -1, true, true, true, 6, 0,
+ RotelConnector.SPECIAL_CHARACTERS),
+ RA1592("RA-1592", 115200, 9, 96, true, 10, 15, false, -1, true, true, true, 6, 0,
+ RotelConnector.SPECIAL_CHARACTERS),
RAP1580("RAP-1580", 115200, 11, 96, true, null, false, 5, false, false, -10, 10,
RotelConnector.NO_SPECIAL_CHARACTERS),
- RC1570("RC-1570", 115200, 7, 96, true, 10, true, -1, true, false, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
- RC1572("RC-1572", 115200, 8, 96, true, 10, false, -1, true, true, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
- RC1590("RC-1590", 115200, 9, 96, true, 10, false, -1, true, true, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
+ RC1570("RC-1570", 115200, 7, 96, true, 10, 15, true, -1, true, false, false, 6, 0,
+ RotelConnector.SPECIAL_CHARACTERS),
+ RC1572("RC-1572", 115200, 8, 96, true, 10, 15, false, -1, true, false, true, 6, 0,
+ RotelConnector.SPECIAL_CHARACTERS),
+ RC1590("RC-1590", 115200, 9, 96, true, 10, 15, false, -1, true, false, true, 6, 0,
+ RotelConnector.SPECIAL_CHARACTERS),
RCD1570("RCD-1570", 115200, 0, null, false, null, true, -1, false, true, 6, 0, RotelConnector.SPECIAL_CHARACTERS),
RCD1572("RCD-1572", 57600, 0, null, false, null, true, -1, false, true, 6, 0,
RotelConnector.SPECIAL_CHARACTERS_RCD1572),
private boolean charsBeforeFlags;
private RotelFlagsMapping flagsMapping;
private byte[][] specialCharacters;
+ private @Nullable Integer balanceLevelMax;
+ private boolean getSpeakerGroupsAvailable;
/**
* Constructor
@Nullable RotelCommand zoneSelectCmd, int dspCategory, byte deviceId, int respNbChars, int respNbFlags,
boolean charsBeforeFlags, RotelFlagsMapping flagsMapping) {
this(name, baudRate, RotelCommand.DISPLAY_REFRESH, sourceCategory, nbAdditionalZones, additionalCommands,
- volumeMax, directVolume, toneLevelMax, playControl, zoneSelectCmd, dspCategory, false, false, null,
- null, deviceId, respNbChars, respNbFlags, charsBeforeFlags, flagsMapping,
+ volumeMax, directVolume, toneLevelMax, null, playControl, zoneSelectCmd, dspCategory, false, false,
+ false, null, null, deviceId, respNbChars, respNbFlags, charsBeforeFlags, flagsMapping,
RotelConnector.NO_SPECIAL_CHARACTERS);
}
@Nullable Integer toneLevelMax, boolean playControl, int dspCategory, boolean getFrequencyAvailable,
boolean getDimmerLevelAvailable, @Nullable Integer diummerLevelMin, @Nullable Integer diummerLevelMax,
byte[][] specialCharacters) {
- this(name, baudRate, RotelCommand.POWER, sourceCategory, 0, false, volumeMax, directVolume, toneLevelMax,
- playControl, null, dspCategory, getFrequencyAvailable, getDimmerLevelAvailable, diummerLevelMin,
+ this(name, baudRate, RotelCommand.POWER, sourceCategory, 0, false, volumeMax, directVolume, toneLevelMax, null,
+ playControl, null, dspCategory, getFrequencyAvailable, false, getDimmerLevelAvailable, diummerLevelMin,
diummerLevelMax, (byte) 0, 0, 0, false, RotelFlagsMapping.NO_MAPPING, specialCharacters);
}
+ /**
+ * Constructor
+ *
+ * @param name the model name
+ * @param baudRate the baud rate to be used for the RS232 communication
+ * @param sourceCategory the category from {@link RotelSource}
+ * @param volumeMax the maximum volume or null if no volume management is available
+ * @param directVolume true if a command to set the volume with a value is available
+ * @param toneLevelMax the maximum tone level or null if no bass/treble management is available
+ * @param balanceLevelMax the maximum balance level or null if no balance management is available
+ * @param playControl true if control of source playback is available
+ * @param dspCategory the category from {@link RotelDsp}
+ * @param getFrequencyAvailable true if the command to get the frequency for digital source input is available
+ * @param getSpeakerGroupsAvailable true if the command to switch speaker groups is available
+ * @param getDimmerLevelAvailable true if the command to get the front display dimmer level is available
+ * @param diummerLevelMin the minimum front display dimmer level or null if dimmer control is unavailable
+ * @param diummerLevelMax the maximum front display dimmer level or null if dimmer control is unavailable
+ * @param specialCharacters the table of special characters that can be found in the standard response message
+ */
+ private RotelModel(String name, int baudRate, int sourceCategory, @Nullable Integer volumeMax, boolean directVolume,
+ @Nullable Integer toneLevelMax, @Nullable Integer balanceLevelMax, boolean playControl, int dspCategory,
+ boolean getFrequencyAvailable, boolean getSpeakerGroupsAvailable, boolean getDimmerLevelAvailable,
+ @Nullable Integer diummerLevelMin, @Nullable Integer diummerLevelMax, byte[][] specialCharacters) {
+ this(name, baudRate, RotelCommand.POWER, sourceCategory, 0, false, volumeMax, directVolume, toneLevelMax,
+ balanceLevelMax, playControl, null, dspCategory, getFrequencyAvailable, getSpeakerGroupsAvailable,
+ getDimmerLevelAvailable, diummerLevelMin, diummerLevelMax, (byte) 0, 0, 0, false,
+ RotelFlagsMapping.NO_MAPPING, specialCharacters);
+ }
+
/**
* Constructor
*
* @param volumeMax the maximum volume or null if no volume management is available
* @param directVolume true if a command to set the volume with a value is available
* @param toneLevelMax the maximum tone level or null if no bass/treble management is available
+ * @param balanceLevelMax the maximum balance level or null if no balance management is available
* @param playControl true if control of source playback is available
* @param zoneSelectCmd the command to be used to select a zone
* @param dspCategory the category from {@link RotelDsp}
* @param getFrequencyAvailable true if the command to get the frequency for digital source input is available
+ * @param getSpeakerGroupsAvailable true if the command to switch speaker groups is available
* @param getDimmerLevelAvailable true if the command to get the front display dimmer level is available
* @param diummerLevelMin the minimum front display dimmer level or null if dimmer control is unavailable
* @param diummerLevelMax the maximum front display dimmer level or null if dimmer control is unavailable
*/
private RotelModel(String name, int baudRate, RotelCommand powerStateCmd, int sourceCategory, int nbAdditionalZones,
boolean additionalCommands, @Nullable Integer volumeMax, boolean directVolume,
- @Nullable Integer toneLevelMax, boolean playControl, @Nullable RotelCommand zoneSelectCmd, int dspCategory,
- boolean getFrequencyAvailable, boolean getDimmerLevelAvailable, @Nullable Integer diummerLevelMin,
+ @Nullable Integer toneLevelMax, @Nullable Integer balanceLevelMax, boolean playControl,
+ @Nullable RotelCommand zoneSelectCmd, int dspCategory, boolean getFrequencyAvailable,
+ boolean getSpeakerGroupsAvailable, boolean getDimmerLevelAvailable, @Nullable Integer diummerLevelMin,
@Nullable Integer diummerLevelMax, byte deviceId, int respNbChars, int respNbFlags,
boolean charsBeforeFlags, RotelFlagsMapping flagsMapping, byte[][] specialCharacters) {
this.name = name;
this.volumeMax = volumeMax;
this.directVolume = directVolume;
this.toneLevelMax = toneLevelMax;
+ this.balanceLevelMax = balanceLevelMax;
this.playControl = playControl;
this.zoneSelectCmd = zoneSelectCmd;
this.dspCategory = dspCategory;
this.getFrequencyAvailable = getFrequencyAvailable;
+ this.getSpeakerGroupsAvailable = getSpeakerGroupsAvailable;
this.getDimmerLevelAvailable = getDimmerLevelAvailable;
this.diummerLevelMin = diummerLevelMin;
this.diummerLevelMax = diummerLevelMax;
return toneLevelMax != null ? toneLevelMax.intValue() : 0;
}
+ /**
+ * Inform whether balance control is available
+ *
+ * @return true if balance control is available
+ */
+ public boolean hasBalanceControl() {
+ return balanceLevelMax != null;
+ }
+
+ /**
+ * Get the maximum balance level
+ *
+ * @return the maximum balance level or 0
+ */
+ public int getBalanceLevelMax() {
+ Integer balanceLevelMax = this.balanceLevelMax;
+ return balanceLevelMax != null ? balanceLevelMax.intValue() : 0;
+ }
+
+ /**
+ * Inform whether the command to switch speaker groups is available
+ *
+ * @return true if the command is available
+ */
+ public boolean hasSpeakerGroups() {
+ return getSpeakerGroupsAvailable;
+ }
+
/**
* Inform whether the command to get the current frequency for digital source input is available
*
TRACK_FORWARD("Track Forward", RotelConnector.PRIMARY_CMD, (byte) 0x09, "track_fwd", "trkf"),
TRACK_BACKWORD("Track Backward", RotelConnector.PRIMARY_CMD, (byte) 0x08, "track_back", "trkb"),
TRACK("Request current CD track number", null, "track"),
- FREQUENCY("Request current frequency for digital source input", "get_current_freq", "freq"),
+ FREQUENCY("Request current frequency for digital source input", "get_current_freq", "freq?"),
DISPLAY_REFRESH("Display Refresh", RotelConnector.PRIMARY_CMD, (byte) 0xFF),
- DIMMER_LEVEL_GET("Request current front display dimmer level", "get_current_dimmer", "dimmer"),
+ DIMMER_LEVEL_GET("Request current front display dimmer level", "get_current_dimmer", "dimmer?"),
DIMMER_LEVEL_SET("Set front display dimmer to level", "dimmer_", "dimmer_"),
UPDATE_AUTO("Set Update to Auto", "display_update_auto", "rs232_update_on"),
- UPDATE_MANUAL("Set Update to Manual", "display_update_manual", "rs232_update_off");
+ UPDATE_MANUAL("Set Update to Manual", "display_update_manual", "rs232_update_off"),
+ TONE_CONTROLS_ON("Tone Controls On", "tone_on", null),
+ TONE_CONTROLS_OFF("Tone Controls Off", "tone_off", null),
+ TONE_CONTROLS("Request current tone control state", "get_tone", null),
+ TCBYPASS_ON("Bypass On", null, "bypass_on"),
+ TCBYPASS_OFF("Bypass Off", null, "bypass_off"),
+ TCBYPASS("Request current tone bypass state", null, "bypass?"),
+ BALANCE_RIGHT("Balance Right", "balance_right", "balance_r"),
+ BALANCE_LEFT("Balance Left", "balance_left", "balance_l"),
+ BALANCE_SET("Set Balance to level", "balance_", "balance_"),
+ BALANCE_SET_FIX("Set Balance to level", "balance_", "balance_"),
+ BALANCE("Request current balance setting", "get_balance", "balance?"),
+ SPEAKER_A_TOGGLE("Toggle Speaker A Output", RotelConnector.PRIMARY_CMD, (byte) 0x50, "speaker_a", "speaker_a"),
+ SPEAKER_A_ON("Set Speaker A Output", "speaker_a_on", "speaker_a_on"),
+ SPEAKER_A_OFF("Unset Speaker A Output", "speaker_a_off", "speaker_a_off"),
+ SPEAKER_B_TOGGLE("Toggle Speaker B Output", RotelConnector.PRIMARY_CMD, (byte) 0x51, "speaker_b", "speaker_b"),
+ SPEAKER_B_ON("Set Speaker B Output", "speaker_b_on", "speaker_b_on"),
+ SPEAKER_B_OFF("Unset Speaker B Output", "speaker_b_off", "speaker_b_off"),
+ SPEAKER("Request current active speaker outputs", "get_current_speaker", "speaker?");
public static final byte PRIMARY_COMMAND = (byte) 0x10;
public static final String KEY_DSP_MODE = "dsp_mode";
public static final String KEY_DIMMER = "dimmer";
public static final String KEY_FREQ = "freq";
+ public static final String KEY_TONE = "tone";
+ public static final String KEY_TCBYPASS = "bypass";
+ public static final String KEY_BALANCE = "balance";
+ public static final String KEY_SPEAKER = "speaker";
// Special keys used by the binding
public static final String KEY_LINE1 = "line1";
public static final String PAUSE = "pause";
public static final String STOP = "stop";
private static final String SOURCE = "source";
+ public static final String MSG_VALUE_SPEAKER_A = "a";
+ public static final String MSG_VALUE_SPEAKER_B = "b";
+ public static final String MSG_VALUE_SPEAKER_AB = "a_b";
private RotelModel model;
private RotelProtocol protocol;
messageStr += String.format("-%02d", -value);
}
break;
+ case BALANCE_SET:
+ if (value == 0) {
+ messageStr += "000";
+ } else if (value > 0) {
+ messageStr += String.format("R%02d", value);
+ } else {
+ messageStr += String.format("L%02d", -value);
+ }
+ break;
+ case BALANCE_SET_FIX:
+ // Firmware for models A1x does not follow strictly the Rotel specification
+ // The firmware expects values like r05 or l04 while the specification mentions
+ // R05 and L04
+ if (value == 0) {
+ messageStr += "000";
+ } else if (value > 0) {
+ messageStr += String.format("r%02d", value);
+ } else {
+ messageStr += String.format("l%02d", -value);
+ }
+ break;
case DIMMER_LEVEL_SET:
if (value > 0 && model.getDimmerLevelMin() < 0) {
messageStr += String.format("+%d", value);
private static final RotelModel DEFAULT_MODEL = RotelModel.RSP1066;
private static final long POLLING_INTERVAL = TimeUnit.SECONDS.toSeconds(60);
private static final boolean USE_SIMULATED_DEVICE = false;
+ private static final int SLEEP_INTV = 30;
private @Nullable ScheduledFuture<?> reconnectJob;
private @Nullable ScheduledFuture<?> powerOnJob;
private String frontPanelLine1 = "";
private String frontPanelLine2 = "";
private int brightness;
+ private boolean tcbypass;
+ private int balance;
+ private int minBalanceLevel;
+ private int maxBalanceLevel;
+ private boolean speakera;
+ private boolean speakerb;
+ private boolean useFixedBalanceCmd;
private Object sequenceLock = new Object();
break;
case THING_TYPE_ID_A11:
rotelModel = RotelModel.A11;
+ useFixedBalanceCmd = true;
break;
case THING_TYPE_ID_A12:
rotelModel = RotelModel.A12;
+ useFixedBalanceCmd = true;
break;
case THING_TYPE_ID_A14:
rotelModel = RotelModel.A14;
+ useFixedBalanceCmd = true;
break;
case THING_TYPE_ID_CD11:
rotelModel = RotelModel.CD11;
"Set minValue to {} and maxValue to {} for your sitemap widget attached to your bass or treble item.",
minToneLevel, maxToneLevel);
}
+ if (rotelModel.hasBalanceControl()) {
+ maxBalanceLevel = rotelModel.getBalanceLevelMax();
+ minBalanceLevel = -maxBalanceLevel;
+ logger.info("Set minValue to {} and maxValue to {} for your sitemap widget attached to your balance item.",
+ minBalanceLevel, maxBalanceLevel);
+ }
// Check configuration settings
String configError = null;
: src.getCommand();
if (cmd != null) {
connector.sendCommand(cmd);
+ if (connector.getModel().canGetFrequency()) {
+ // send <new-source> returns
+ // 1.) the selected <new-source>
+ // 2.) the used frequency
+ // BUT:
+ // at response-time the frequency has the value of <old-source>
+ // so we must wait a short moment to get the frequency of <new-source>
+ Thread.sleep(1000);
+ connector.sendCommand(RotelCommand.FREQUENCY);
+ Thread.sleep(100);
+ updateChannelState(CHANNEL_FREQUENCY);
+ }
} else {
success = false;
logger.debug("Command {} from channel {} failed: undefined source command", command,
if (!isPowerOn()) {
success = false;
logger.debug("Command {} from channel {} ignored: device in standby", command, channel);
+ } else if (tcbypass) {
+ logger.debug("Command {} from channel {} ignored: tone control bypass is ON", command,
+ channel);
+ updateChannelState(CHANNEL_BASS);
} else {
handleToneCmd(bass, channel, command, 2, RotelCommand.BASS_UP, RotelCommand.BASS_DOWN,
RotelCommand.BASS_SET);
if (!isPowerOn()) {
success = false;
logger.debug("Command {} from channel {} ignored: device in standby", command, channel);
+ } else if (tcbypass) {
+ logger.debug("Command {} from channel {} ignored: tone control bypass is ON", command,
+ channel);
+ updateChannelState(CHANNEL_TREBLE);
} else {
handleToneCmd(treble, channel, command, 1, RotelCommand.TREBLE_UP, RotelCommand.TREBLE_DOWN,
RotelCommand.TREBLE_SET);
&& connector.getModel() != RotelModel.RCD1570
&& connector.getModel() != RotelModel.RCD1572
&& connector.getModel() != RotelModel.RCX1500) {
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
connector.sendCommand(RotelCommand.PLAY_STATUS);
}
} else if (command instanceof NextPreviousType && command == NextPreviousType.NEXT) {
logger.debug("Command {} from channel {} failed: invalid command value", command, channel);
}
break;
+ case CHANNEL_TCBYPASS:
+ if (!isPowerOn()) {
+ success = false;
+ logger.debug("Command {} from channel {} ignored: device in standby", command, channel);
+ } else if (!connector.getModel().hasToneControl()
+ || connector.getProtocol() == RotelProtocol.HEX) {
+ success = false;
+ logger.debug("Command {} from channel {} failed: unavailable feature", command, channel);
+ } else {
+ handleTcbypassCmd(channel, command,
+ connector.getProtocol() == RotelProtocol.ASCII_V1 ? RotelCommand.TONE_CONTROLS_OFF
+ : RotelCommand.TCBYPASS_ON,
+ connector.getProtocol() == RotelProtocol.ASCII_V1 ? RotelCommand.TONE_CONTROLS_ON
+ : RotelCommand.TCBYPASS_OFF);
+ }
+ break;
+ case CHANNEL_BALANCE:
+ if (!isPowerOn()) {
+ success = false;
+ logger.debug("Command {} from channel {} ignored: device in standby", command, channel);
+ } else if (!connector.getModel().hasBalanceControl()
+ || connector.getProtocol() == RotelProtocol.HEX) {
+ success = false;
+ logger.debug("Command {} from channel {} failed: unavailable feature", command, channel);
+ } else {
+ handleBalanceCmd(channel, command, RotelCommand.BALANCE_LEFT, RotelCommand.BALANCE_RIGHT,
+ useFixedBalanceCmd ? RotelCommand.BALANCE_SET_FIX : RotelCommand.BALANCE_SET);
+ }
+ break;
+ case CHANNEL_SPEAKER_A:
+ if (!isPowerOn()) {
+ success = false;
+ logger.debug("Command {} from channel {} ignored: device in standby", command, channel);
+ } else {
+ handleSpeakerCmd(connector.getProtocol() == RotelProtocol.HEX, channel, command,
+ RotelCommand.SPEAKER_A_ON, RotelCommand.SPEAKER_A_OFF,
+ RotelCommand.SPEAKER_A_TOGGLE);
+ }
+ break;
+ case CHANNEL_SPEAKER_B:
+ if (!isPowerOn()) {
+ success = false;
+ logger.debug("Command {} from channel {} ignored: device in standby", command, channel);
+ } else {
+ handleSpeakerCmd(connector.getProtocol() == RotelProtocol.HEX, channel, command,
+ RotelCommand.SPEAKER_B_ON, RotelCommand.SPEAKER_B_OFF,
+ RotelCommand.SPEAKER_B_TOGGLE);
+ }
+ break;
default:
success = false;
logger.debug("Command {} from channel {} failed: nnexpected command", command, channel);
}
}
+ /**
+ * Handle a tcbypass command (only for ASCII protocol)
+ *
+ * @param channel the channel
+ * @param command the received channel command (OnOffType)
+ * @param onCmd the command to be sent to the device to bypass_on
+ * @param offCmd the command to be sent to the device to bypass_off
+ *
+ * @throws RotelException in case of communication error with the device
+ */
+ private void handleTcbypassCmd(String channel, Command command, RotelCommand onCmd, RotelCommand offCmd)
+ throws RotelException, InterruptedException {
+ if (command instanceof OnOffType) {
+ if (command == OnOffType.ON) {
+ connector.sendCommand(onCmd);
+ bass = 0;
+ treble = 0;
+ updateChannelState(CHANNEL_BASS);
+ updateChannelState(CHANNEL_TREBLE);
+ } else if (command == OnOffType.OFF) {
+ connector.sendCommand(offCmd);
+ Thread.sleep(200);
+ connector.sendCommand(RotelCommand.BASS);
+ Thread.sleep(200);
+ connector.sendCommand(RotelCommand.TREBLE);
+ }
+ } else {
+ logger.debug("Command {} from channel {} failed: invalid command value", command, channel);
+ }
+ }
+
+ /**
+ * Handle a speaker command
+ *
+ * @param onlyToggle true if only the toggle command must be used
+ * @param channel the channel
+ * @param command the received channel command (OnOffType)
+ * @param onCmd the command to be sent to the device to speaker_x_on
+ * @param offCmd the command to be sent to the device to speaker_x_off
+ * @param toggleCmd the command to be sent to the device to toggle the speaker_x state
+ *
+ * @throws RotelException in case of communication error with the device
+ */
+ private void handleSpeakerCmd(boolean onlyToggle, String channel, Command command, RotelCommand onCmd,
+ RotelCommand offCmd, RotelCommand toggleCmd) throws RotelException {
+ if (command instanceof OnOffType) {
+ if (onlyToggle) {
+ connector.sendCommand(toggleCmd);
+ } else if (command == OnOffType.ON) {
+ connector.sendCommand(onCmd);
+ } else if (command == OnOffType.OFF) {
+ connector.sendCommand(offCmd);
+ }
+ } else {
+ logger.debug("Command {} from channel {} failed: invalid command value", command, channel);
+ }
+ }
+
+ /**
+ * Handle a tone balance adjustment command (left or right) (only for ASCII protocol)
+ *
+ * @param channel the channel
+ * @param command the received channel command (IncreaseDecreaseType or DecimalType)
+ * @param rightCmd the command to be sent to the device to "increase" balance (shift to the right side)
+ * @param leftCmd the command to be sent to the device to "decrease" balance (shift to the left side)
+ * @param setCmd the command to be sent to the device to set the balance at a value
+ *
+ * @throws RotelException in case of communication error with the device
+ * @throws InterruptedException in case of interruption during a thread sleep
+ */
+ private void handleBalanceCmd(String channel, Command command, RotelCommand leftCmd, RotelCommand rightCmd,
+ RotelCommand setCmd) throws RotelException, InterruptedException {
+ if (command instanceof IncreaseDecreaseType && command == IncreaseDecreaseType.INCREASE) {
+ connector.sendCommand(rightCmd);
+ } else if (command instanceof IncreaseDecreaseType && command == IncreaseDecreaseType.DECREASE) {
+ connector.sendCommand(leftCmd);
+ } else if (command instanceof DecimalType) {
+ int value = ((DecimalType) command).intValue();
+ if (value >= minBalanceLevel && value <= maxBalanceLevel) {
+ connector.sendCommand(setCmd, value);
+ }
+ } else {
+ logger.debug("Command {} from channel {} failed: invalid command value", command, channel);
+ }
+ }
+
/**
* Run a sequence of commands to display the current tone level (bass or treble) on the device front panel
*
case RotelConnector.KEY_UPDATE_MODE:
case RotelConnector.KEY_DISPLAY_UPDATE:
break;
+ case RotelConnector.KEY_TONE:
+ if (RotelConnector.MSG_VALUE_ON.equalsIgnoreCase(value)) {
+ tcbypass = false;
+ updateChannelState(CHANNEL_TCBYPASS);
+ } else if (RotelConnector.MSG_VALUE_OFF.equalsIgnoreCase(value)) {
+ tcbypass = true;
+ updateChannelState(CHANNEL_TCBYPASS);
+ } else {
+ throw new RotelException("Invalid value");
+ }
+ break;
+ case RotelConnector.KEY_TCBYPASS:
+ if (RotelConnector.MSG_VALUE_ON.equalsIgnoreCase(value)) {
+ tcbypass = true;
+ updateChannelState(CHANNEL_TCBYPASS);
+ } else if (RotelConnector.MSG_VALUE_OFF.equalsIgnoreCase(value)) {
+ tcbypass = false;
+ updateChannelState(CHANNEL_TCBYPASS);
+ } else {
+ throw new RotelException("Invalid value");
+ }
+ break;
+ case RotelConnector.KEY_BALANCE:
+ if (RotelConnector.MSG_VALUE_MIN.equalsIgnoreCase(value)) {
+ balance = minBalanceLevel;
+ } else if (RotelConnector.MSG_VALUE_MAX.equalsIgnoreCase(value)) {
+ balance = maxBalanceLevel;
+ } else if (value.toUpperCase().startsWith("L")) {
+ balance = -Integer.parseInt(value.substring(1));
+ } else if (value.toLowerCase().startsWith("R")) {
+ balance = Integer.parseInt(value.substring(1));
+ } else {
+ balance = Integer.parseInt(value);
+ }
+ updateChannelState(CHANNEL_BALANCE);
+ break;
+ case RotelConnector.KEY_SPEAKER:
+ if (RotelConnector.MSG_VALUE_SPEAKER_A.equalsIgnoreCase(value)) {
+ speakera = true;
+ speakerb = false;
+ updateChannelState(CHANNEL_SPEAKER_A);
+ updateChannelState(CHANNEL_SPEAKER_B);
+ } else if (RotelConnector.MSG_VALUE_SPEAKER_B.equalsIgnoreCase(value)) {
+ speakera = false;
+ speakerb = true;
+ updateChannelState(CHANNEL_SPEAKER_A);
+ updateChannelState(CHANNEL_SPEAKER_B);
+ } else if (RotelConnector.MSG_VALUE_SPEAKER_AB.equalsIgnoreCase(value)) {
+ speakera = true;
+ speakerb = true;
+ updateChannelState(CHANNEL_SPEAKER_A);
+ updateChannelState(CHANNEL_SPEAKER_B);
+ } else if (RotelConnector.MSG_VALUE_OFF.equalsIgnoreCase(value)) {
+ speakera = false;
+ speakerb = false;
+ updateChannelState(CHANNEL_SPEAKER_A);
+ updateChannelState(CHANNEL_SPEAKER_B);
+ } else {
+ throw new RotelException("Invalid value");
+ }
+ break;
default:
logger.debug("onNewMessageEvent: unhandled key {}", key);
break;
updateChannelState(CHANNEL_TRACK);
updateChannelState(CHANNEL_FREQUENCY);
updateChannelState(CHANNEL_BRIGHTNESS);
+ updateChannelState(CHANNEL_TCBYPASS);
+ updateChannelState(CHANNEL_BALANCE);
+ updateChannelState(CHANNEL_SPEAKER_A);
+ updateChannelState(CHANNEL_SPEAKER_B);
}
/**
&& connector.getModel() != RotelModel.RSP1576
&& connector.getModel() != RotelModel.RSP1582) {
connector.sendCommand(RotelCommand.UPDATE_AUTO);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
if (connector.getModel().hasSourceControl()) {
connector.sendCommand(RotelCommand.SOURCE);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
if (connector.getModel().hasVolumeControl() || connector.getModel().hasToneControl()) {
if (connector.getModel().hasVolumeControl()
&& connector.getModel() != RotelModel.RSP1576
&& connector.getModel() != RotelModel.RSP1582) {
connector.sendCommand(RotelCommand.VOLUME_GET_MIN);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
connector.sendCommand(RotelCommand.VOLUME_GET_MAX);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
if (connector.getModel().hasToneControl()) {
connector.sendCommand(RotelCommand.TONE_MAX);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
// Wait enough to be sure to get the min/max values requested just before
Thread.sleep(250);
if (connector.getModel().hasVolumeControl()) {
connector.sendCommand(RotelCommand.VOLUME_GET);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
if (connector.getModel() != RotelModel.RA11
&& connector.getModel() != RotelModel.RA12
&& connector.getModel() != RotelModel.RCX1500) {
connector.sendCommand(RotelCommand.MUTE);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
}
if (connector.getModel().hasToneControl()) {
connector.sendCommand(RotelCommand.BASS);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
connector.sendCommand(RotelCommand.TREBLE);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
+ connector.sendCommand(RotelCommand.TONE_CONTROLS);
+ Thread.sleep(SLEEP_INTV);
}
}
+ if (connector.getModel().hasBalanceControl()) {
+ connector.sendCommand(RotelCommand.BALANCE);
+ Thread.sleep(SLEEP_INTV);
+ }
if (connector.getModel().hasPlayControl()) {
if (connector.getModel() != RotelModel.RCD1570
&& connector.getModel() != RotelModel.RCD1572
&& (connector.getModel() != RotelModel.RCX1500
|| !source.getName().equals("CD"))) {
connector.sendCommand(RotelCommand.PLAY_STATUS);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
} else {
connector.sendCommand(RotelCommand.CD_PLAY_STATUS);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
}
if (connector.getModel().hasDspControl()) {
connector.sendCommand(RotelCommand.DSP_MODE);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
if (connector.getModel().canGetFrequency()) {
connector.sendCommand(RotelCommand.FREQUENCY);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
if (connector.getModel().hasDimmerControl() && connector.getModel().canGetDimmerLevel()) {
connector.sendCommand(RotelCommand.DIMMER_LEVEL_GET);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
+ }
+ if (connector.getModel().hasSpeakerGroups()) {
+ connector.sendCommand(RotelCommand.SPEAKER);
+ Thread.sleep(SLEEP_INTV);
}
break;
case ASCII_V2:
connector.sendCommand(RotelCommand.UPDATE_AUTO);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
if (connector.getModel().hasSourceControl()) {
connector.sendCommand(RotelCommand.SOURCE);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
if (connector.getModel().hasVolumeControl()) {
connector.sendCommand(RotelCommand.VOLUME_GET);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
connector.sendCommand(RotelCommand.MUTE);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
if (connector.getModel().hasToneControl()) {
connector.sendCommand(RotelCommand.BASS);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
connector.sendCommand(RotelCommand.TREBLE);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
+ connector.sendCommand(RotelCommand.TCBYPASS);
+ Thread.sleep(SLEEP_INTV);
+ }
+ if (connector.getModel().hasBalanceControl()) {
+ connector.sendCommand(RotelCommand.BALANCE);
+ Thread.sleep(SLEEP_INTV);
}
if (connector.getModel().hasPlayControl()) {
connector.sendCommand(RotelCommand.PLAY_STATUS);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
if (source.getName().equals("CD") && !connector.getModel().hasSourceControl()) {
connector.sendCommand(RotelCommand.TRACK);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
}
if (connector.getModel().hasDspControl()) {
connector.sendCommand(RotelCommand.DSP_MODE);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
if (connector.getModel().canGetFrequency()) {
connector.sendCommand(RotelCommand.FREQUENCY);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
}
if (connector.getModel().hasDimmerControl() && connector.getModel().canGetDimmerLevel()) {
connector.sendCommand(RotelCommand.DIMMER_LEVEL_GET);
- Thread.sleep(50);
+ Thread.sleep(SLEEP_INTV);
+ }
+ if (connector.getModel().hasSpeakerGroups()) {
+ connector.sendCommand(RotelCommand.SPEAKER);
+ Thread.sleep(SLEEP_INTV);
}
break;
}
switch (channel) {
case CHANNEL_POWER:
case CHANNEL_MAIN_POWER:
- if (power != null) {
- state = power ? OnOffType.ON : OnOffType.OFF;
+ Boolean po = power;
+ if (po != null) {
+ state = OnOffType.from(po.booleanValue());
}
break;
case CHANNEL_ZONE2_POWER:
- state = powerZone2 ? OnOffType.ON : OnOffType.OFF;
+ state = OnOffType.from(powerZone2);
break;
case CHANNEL_ZONE3_POWER:
- state = powerZone3 ? OnOffType.ON : OnOffType.OFF;
+ state = OnOffType.from(powerZone3);
break;
case CHANNEL_ZONE4_POWER:
- state = powerZone4 ? OnOffType.ON : OnOffType.OFF;
+ state = OnOffType.from(powerZone4);
break;
case CHANNEL_SOURCE:
case CHANNEL_MAIN_SOURCE:
case CHANNEL_MUTE:
case CHANNEL_MAIN_MUTE:
if (isPowerOn()) {
- state = mute ? OnOffType.ON : OnOffType.OFF;
+ state = OnOffType.from(mute);
}
break;
case CHANNEL_ZONE2_MUTE:
if (powerZone2) {
- state = muteZone2 ? OnOffType.ON : OnOffType.OFF;
+ state = OnOffType.from(muteZone2);
}
break;
case CHANNEL_ZONE3_MUTE:
if (powerZone3) {
- state = muteZone3 ? OnOffType.ON : OnOffType.OFF;
+ state = OnOffType.from(muteZone3);
}
break;
case CHANNEL_ZONE4_MUTE:
if (powerZone4) {
- state = muteZone4 ? OnOffType.ON : OnOffType.OFF;
+ state = OnOffType.from(muteZone4);
}
break;
case CHANNEL_BASS:
state = new PercentType(BigDecimal.valueOf(dimmerPct));
}
break;
+ case CHANNEL_TCBYPASS:
+ if (isPowerOn()) {
+ state = OnOffType.from(tcbypass);
+ }
+ break;
+ case CHANNEL_BALANCE:
+ if (isPowerOn()) {
+ state = new DecimalType(balance);
+ }
+ break;
+ case CHANNEL_SPEAKER_A:
+ if (isPowerOn()) {
+ state = OnOffType.from(speakera);
+ }
+ break;
+ case CHANNEL_SPEAKER_B:
+ if (isPowerOn()) {
+ state = OnOffType.from(speakerb);
+ }
+ break;
default:
break;
}
<description>@text/config.inputLabelMulti.description</description>
</parameter>
</config-description>
+
</config-description:config-descriptions>
channel-type.rotel.treble.description = Adjust the treble
channel-type.rotel.volumeUpDown.label = Volume
channel-type.rotel.volumeUpDown.description = Increase or decrease the volume
+channel-type.rotel.tcbypass.label = Tone Control Bypass
+channel-type.rotel.tcbypass.description = The user's bass-/treble-settings are bypassed
+channel-type.rotel.balance.label = Balance Adjustment
+channel-type.rotel.balance.description = Adjust the speakers left-right balance
+channel-type.rotel.speakera.label = Speaker-A Adjustment
+channel-type.rotel.speakera.description = Turn on/off the speaker group A
+channel-type.rotel.speakerb.label = Speaker-B Adjustment
+channel-type.rotel.speakerb.description = Turn on/off the speaker group B
# thing type configuration
<channel id="bass" typeId="bass"/>
<channel id="treble" typeId="treble"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
+ <channel id="speakera" typeId="speakera"/>
+ <channel id="speakerb" typeId="speakerb"/>
</channels>
<properties>
<channel id="treble" typeId="treble"/>
<channel id="frequency" typeId="frequency"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
+ <channel id="speakera" typeId="speakera"/>
+ <channel id="speakerb" typeId="speakerb"/>
</channels>
<properties>
<channel id="treble" typeId="treble"/>
<channel id="frequency" typeId="frequency"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
+ <channel id="speakera" typeId="speakera"/>
+ <channel id="speakerb" typeId="speakerb"/>
</channels>
<properties>
<description>The backlight brightness level (in %) of the device front panel</description>
</channel-type>
+ <channel-type id="tcbypass" advanced="true">
+ <item-type>Switch</item-type>
+ <label>Tone Control Bypass</label>
+ <description>The user's bass-/treble-settings are bypassed</description>
+ </channel-type>
+
+ <channel-type id="balance" advanced="true">
+ <item-type>Number</item-type>
+ <label>Balance Adjustment</label>
+ <description>Adjust the speakers left-right balance</description>
+ </channel-type>
+
+ <channel-type id="speakera" advanced="true">
+ <item-type>Switch</item-type>
+ <label>Speaker-A Adjustment</label>
+ <description>Turn on/off the speaker group A</description>
+ </channel-type>
+
+ <channel-type id="speakerb" advanced="true">
+ <item-type>Switch</item-type>
+ <label>Speaker-B Adjustment</label>
+ <description>Turn on/off the speaker group B</description>
+ </channel-type>
</thing:thing-descriptions>
<channel id="playControl" typeId="system.media-control"/>
<channel id="frequency" typeId="frequency"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
</channels>
<properties>
<channel id="playControl" typeId="system.media-control"/>
<channel id="frequency" typeId="frequency"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
</channels>
<properties>
<channel id="playControl" typeId="system.media-control"/>
<channel id="frequency" typeId="frequency"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
+ <channel id="speakera" typeId="speakera"/>
+ <channel id="speakerb" typeId="speakerb"/>
</channels>
<properties>
<channel id="treble" typeId="treble"/>
<channel id="frequency" typeId="frequency"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
+ <channel id="speakera" typeId="speakera"/>
+ <channel id="speakerb" typeId="speakerb"/>
</channels>
<config-description-ref uri="thing-type:rotel:serialandipandprotocol"/>
<channel id="treble" typeId="treble"/>
<channel id="frequency" typeId="frequency"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
+ <channel id="speakera" typeId="speakera"/>
+ <channel id="speakerb" typeId="speakerb"/>
</channels>
<config-description-ref uri="thing-type:rotel:serialandipandprotocol"/>
<channel id="playControl" typeId="system.media-control"/>
<channel id="frequency" typeId="frequency"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
</channels>
<properties>
<channel id="treble" typeId="treble"/>
<channel id="frequency" typeId="frequency"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
</channels>
<config-description-ref uri="thing-type:rotel:serialandipandprotocol"/>
<channel id="treble" typeId="treble"/>
<channel id="frequency" typeId="frequency"/>
<channel id="brightness" typeId="brightness"/>
+ <channel id="tcbypass" typeId="tcbypass"/>
+ <channel id="balance" typeId="balance"/>
</channels>
<config-description-ref uri="thing-type:rotel:serialandipandprotocol"/>