Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[rotel] New channels tcbypass, balance, speakera and speakerb #12447

Merged
merged 17 commits into from
Mar 22, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion bundles/org.openhab.binding.rotel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,18 @@ The following channels are available:
| 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 balnce | value |
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
| 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 |
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
| a14 | power, source, volume, mute, bass, treble, frequency, brightness |
| 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 |
Expand Down Expand Up @@ -221,6 +225,8 @@ Thing rotel:rsp1570:preamp "RSP-1570" [ serialPort="COM2" ]
Thing rotel:ra1592:preamp "RA-1592" [ serialPort="COM3" ]

Thing rotel:cd14:cd "CD14" [ serialPort="COM4" ]

Thing rotel:a14:amp "A14" [ serialPort="ttyUSB0" ]
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
```

example.things using serial over IP connection:
Expand Down Expand Up @@ -282,6 +288,11 @@ Number amp_bass "Bass Adjustment [%d]" { channel="rotel:ra1592:preamp:bass" }
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" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ public class RotelBindingConstants {
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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public enum RotelModel {
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),
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),
Expand Down Expand Up @@ -118,6 +118,8 @@ public enum RotelModel {
private boolean charsBeforeFlags;
private RotelFlagsMapping flagsMapping;
private byte[][] specialCharacters;
private @Nullable Integer balanceLevelMax;
private boolean getSpeakerGroupsAvailable;

/**
* Constructor
Expand All @@ -144,8 +146,8 @@ private RotelModel(String name, int baudRate, int sourceCategory, int nbAddition
@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);
}

Expand All @@ -170,11 +172,40 @@ private RotelModel(String name, int baudRate, int sourceCategory, @Nullable Inte
@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
*
Expand All @@ -187,10 +218,12 @@ private RotelModel(String name, int baudRate, int sourceCategory, @Nullable Inte
* @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
Expand All @@ -203,8 +236,9 @@ private RotelModel(String name, int baudRate, int sourceCategory, @Nullable Inte
*/
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;
Expand All @@ -216,10 +250,12 @@ private RotelModel(String name, int baudRate, RotelCommand powerStateCmd, int so
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;
Expand Down Expand Up @@ -386,6 +422,25 @@ public int getToneLevelMax() {
return toneLevelMax != null ? toneLevelMax.intValue() : 0;
}

/**
* 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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,27 @@ public enum RotelCommand {
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?"),
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
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"),
TCBYPASS_TOGGLE("Mute Toggle", RotelConnector.PRIMARY_CMD, (byte) 0x00, "bypass", "bypass"),
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
TCBYPASS_ON("Bypass On", "bypass_on", "bypass_on"),
TCBYPASS_OFF("Bypass Off", "bypass_off", "bypass_off"),
TCBYPASS("Request current tone bypass state", "get_bypass_status", "bypass?"),
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
BALANCE_RIGHT("Balance Right", RotelConnector.PRIMARY_CMD, (byte) 0x00, "balance_r", "balance_r"),
BALANCE_LEFT("Balance Left", RotelConnector.PRIMARY_CMD, (byte) 0x00, "balance_l", "balance_l"),
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
BALANCE_SET("Set Balance to level", "balance_", "balance_"),
BALANCE("Request current balance setting", "get_current_balance", "balance?"),
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
SPEAKER_A_TOGGLE("Toggle Speaker A Output", RotelConnector.PRIMARY_CMD, (byte) 0x00, "speaker_a", "speaker_a"),
SPEAKER_A_ON("Set Speaker A Output", RotelConnector.PRIMARY_CMD, (byte) 0x00, "speaker_a_on", "speaker_a_on"),
SPEAKER_A_OFF("Unset Speaker A Output", RotelConnector.PRIMARY_CMD, (byte) 0x00, "speaker_a_off", "speaker_a_off"),
SPEAKER_B_TOGGLE("Toggle Speaker B Output", RotelConnector.PRIMARY_CMD, (byte) 0x00, "speaker_b", "speaker_b"),
SPEAKER_B_ON("Set Speaker B Output", RotelConnector.PRIMARY_CMD, (byte) 0x00, "speaker_b_on", "speaker_b_on"),
SPEAKER_B_OFF("Unset Speaker B Output", RotelConnector.PRIMARY_CMD, (byte) 0x00, "speaker_b_off", "speaker_b_off"),
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
SPEAKER("Request current active speaker outputs", "get_current_speaker", "speaker?");

public static final byte PRIMARY_COMMAND = (byte) 0x10;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ public abstract class RotelConnector {
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_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";
Expand Down Expand Up @@ -171,6 +174,9 @@ public abstract class RotelConnector {
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;
Expand Down Expand Up @@ -458,6 +464,15 @@ public void sendCommand(RotelCommand cmd, @Nullable Integer value) throws RotelE
messageStr += String.format("-%02d", -value);
}
break;
case BALANCE_SET:
if (value == 0) {
messageStr += "000";
} else if (value > 0) {
messageStr += String.format("r%02d", value);
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
} else {
messageStr += String.format("l%02d", -value);
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
}
break;
case DIMMER_LEVEL_SET:
if (value > 0 && model.getDimmerLevelMin() < 0) {
messageStr += String.format("+%d", value);
Expand Down
Loading