From 1734d6ed8245efb2b6636cb39d860d2cba795eb7 Mon Sep 17 00:00:00 2001
From: lolodomo <lg.hc@free.fr>
Date: Sat, 26 Mar 2022 21:17:40 +0100
Subject: [PATCH] [rotel] Support added for Michi models (P5, X3 and X5)
 (#12524)

Also fix command to set balance (different syntax in ASCII V1 and V2)

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
---
 bundles/org.openhab.binding.rotel/README.md   |  6 +++
 .../rotel/internal/RotelBindingConstants.java |  6 +++
 .../rotel/internal/RotelHandlerFactory.java   |  3 +-
 .../binding/rotel/internal/RotelModel.java    |  5 +-
 .../internal/communication/RotelCommand.java  |  3 +-
 .../communication/RotelConnector.java         | 21 ++++-----
 .../internal/communication/RotelSource.java   | 47 ++++++++++++++++++-
 .../rotel/internal/handler/RotelHandler.java  | 15 ++++--
 .../resources/OH-INF/i18n/rotel.properties    | 24 ++++++----
 .../src/main/resources/OH-INF/thing/p5.xml    | 32 +++++++++++++
 .../src/main/resources/OH-INF/thing/x3.xml    | 32 +++++++++++++
 .../src/main/resources/OH-INF/thing/x5.xml    | 32 +++++++++++++
 12 files changed, 197 insertions(+), 29 deletions(-)
 create mode 100644 bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/p5.xml
 create mode 100644 bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/x3.xml
 create mode 100644 bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/x5.xml

diff --git a/bundles/org.openhab.binding.rotel/README.md b/bundles/org.openhab.binding.rotel/README.md
index ad3a2703e5c..2a48a6ec1fc 100644
--- a/bundles/org.openhab.binding.rotel/README.md
+++ b/bundles/org.openhab.binding.rotel/README.md
@@ -35,6 +35,7 @@ This binding supports the following thing types:
 | a14        | Connection to the Rotel A14 integrated amplifier              |
 | cd11       | Connection to the Rotel CD11 CD player                        |
 | cd14       | Connection to the Rotel CD14 CD player                        |
+| p5         | Connection to the Rotel Michi P5 stereo preamplifier          |
 | ra11       | Connection to the Rotel RA-11 integrated amplifier            |
 | ra12       | Connection to the Rotel RA-12 integrated amplifier            |
 | ra1570     | Connection to the Rotel RA-1570 integrated amplifier          |
@@ -71,6 +72,8 @@ This binding supports the following thing types:
 | rt1570     | Connection to the Rotel RT-1570 tuner                         |
 | t11        | Connection to the Rotel T11 tuner                             |
 | t14        | Connection to the Rotel T14 tuner                             |
+| x3         | Connection to the Rotel Michi X3 integrated amplifier         |
+| x5         | Connection to the Rotel Michi X5 integrated amplifier         |
 
 ## Discovery
 
@@ -176,6 +179,7 @@ Here are the list of channels available for each thing type:
 | a14        | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance, speakera, speakerb |
 | cd11       | power, playControl, track, brightness                                                                   |
 | cd14       | power, playControl, track, brightness                                                                   |
+| p5         | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance                     |
 | 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 |
@@ -212,6 +216,8 @@ Here are the list of channels available for each thing type:
 | rt1570     | power, source, brightness                                                                               |
 | t11        | power, source, brightness                                                                               |
 | t14        | power, source, brightness                                                                               |
+| x3         | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance                     |
+| x5         | power, source, volume, mute, bass, treble, frequency, brightness, tcbypass, balance                     |
 
 ## Full Example
 
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 651296b705e..8096e62277b 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
@@ -68,6 +68,9 @@ public class RotelBindingConstants {
     public static final String THING_TYPE_ID_RT1570 = "rt1570";
     public static final String THING_TYPE_ID_T11 = "t11";
     public static final String THING_TYPE_ID_T14 = "t14";
+    public static final String THING_TYPE_ID_P5 = "p5";
+    public static final String THING_TYPE_ID_X3 = "x3";
+    public static final String THING_TYPE_ID_X5 = "x5";
 
     // List of all Thing Type UIDs
     public static final ThingTypeUID THING_TYPE_RSP1066 = new ThingTypeUID(BINDING_ID, THING_TYPE_ID_RSP1066);
@@ -111,6 +114,9 @@ public class RotelBindingConstants {
     public static final ThingTypeUID THING_TYPE_RT1570 = new ThingTypeUID(BINDING_ID, THING_TYPE_ID_RT1570);
     public static final ThingTypeUID THING_TYPE_T11 = new ThingTypeUID(BINDING_ID, THING_TYPE_ID_T11);
     public static final ThingTypeUID THING_TYPE_T14 = new ThingTypeUID(BINDING_ID, THING_TYPE_ID_T14);
+    public static final ThingTypeUID THING_TYPE_P5 = new ThingTypeUID(BINDING_ID, THING_TYPE_ID_P5);
+    public static final ThingTypeUID THING_TYPE_X3 = new ThingTypeUID(BINDING_ID, THING_TYPE_ID_X3);
+    public static final ThingTypeUID THING_TYPE_X5 = new ThingTypeUID(BINDING_ID, THING_TYPE_ID_X5);
 
     // List of all Channel ids
     public static final String CHANNEL_POWER = "power";
diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelHandlerFactory.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelHandlerFactory.java
index dcd07d06863..8485518f530 100644
--- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelHandlerFactory.java
+++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelHandlerFactory.java
@@ -50,7 +50,8 @@ public class RotelHandlerFactory extends BaseThingHandlerFactory {
                     THING_TYPE_RA12, THING_TYPE_RA1570, THING_TYPE_RA1572, THING_TYPE_RA1592, THING_TYPE_RAP1580,
                     THING_TYPE_RC1570, THING_TYPE_RC1572, THING_TYPE_RC1590, THING_TYPE_RCD1570, THING_TYPE_RCD1572,
                     THING_TYPE_RCX1500, THING_TYPE_RDD1580, THING_TYPE_RDG1520, THING_TYPE_RSP1576, THING_TYPE_RSP1582,
-                    THING_TYPE_RT09, THING_TYPE_RT11, THING_TYPE_RT1570, THING_TYPE_T11, THING_TYPE_T14)
+                    THING_TYPE_RT09, THING_TYPE_RT11, THING_TYPE_RT1570, THING_TYPE_T11, THING_TYPE_T14, THING_TYPE_P5,
+                    THING_TYPE_X3, THING_TYPE_X5)
             .collect(Collectors.toSet()));
 
     private final SerialPortManager serialPortManager;
diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelModel.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelModel.java
index ec7c236c12a..23c5f794d34 100644
--- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelModel.java
+++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/RotelModel.java
@@ -100,7 +100,10 @@ public enum RotelModel {
     RT1570("RT-1570", 115200, 14, null, false, null, false, -1, false, true, 6, 0,
             RotelConnector.NO_SPECIAL_CHARACTERS),
     T11("T11", 115200, 12, null, false, null, false, -1, false, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
-    T14("T14", 115200, 13, null, false, null, false, -1, false, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS);
+    T14("T14", 115200, 13, null, false, null, false, -1, false, true, 6, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
+    P5("P5", 115200, 20, 96, true, 10, 10, false, -1, true, false, true, 4, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
+    X3("X3", 115200, 18, 96, true, 10, 10, false, -1, true, false, true, 4, 0, RotelConnector.NO_SPECIAL_CHARACTERS),
+    X5("X5", 115200, 19, 96, true, 10, 10, false, -1, true, false, true, 4, 0, RotelConnector.NO_SPECIAL_CHARACTERS);
 
     private String name;
     private int baudRate;
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 bfbefd1abd2..2f59fa642bf 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
@@ -103,6 +103,8 @@ public enum RotelCommand {
     SOURCE_BLUETOOTH("Source Bluetooth", "bluetooth", "bluetooth"),
     SOURCE_ROTEL_CD("Source Rotel CD", "rcd", null),
     SOURCE_XLR("Source XLR", "bal_xlr", "bal_xlr"),
+    SOURCE_XLR1("Source XLR 1", "bal_xlr1", "bal_xlr1"),
+    SOURCE_XLR2("Source XLR 2", "bal_xlr2", "bal_xlr2"),
     SOURCE_FM("Source FM", "fm", "fm"),
     SOURCE_DAB("Source DAB", "dab", "dab"),
     SOURCE_PLAYFI("Source PlayFi", "playfi", "playfi"),
@@ -242,7 +244,6 @@ public enum RotelCommand {
     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"),
diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelConnector.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelConnector.java
index fec2effc271..06fbdd916b2 100644
--- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelConnector.java
+++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelConnector.java
@@ -426,6 +426,15 @@ public abstract class RotelConnector {
                                     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 DIMMER_LEVEL_SET:
                                 if (value > 0 && model.getDimmerLevelMin() < 0) {
                                     messageStr += String.format("+%d", value);
@@ -466,18 +475,6 @@ public abstract class RotelConnector {
                                 }
                                 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) {
diff --git a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSource.java b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSource.java
index 46a452c92f0..fb5a82906b9 100644
--- a/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSource.java
+++ b/bundles/org.openhab.binding.rotel/src/main/java/org/openhab/binding/rotel/internal/communication/RotelSource.java
@@ -256,7 +256,52 @@ public enum RotelSource {
     CAT17_AUX2(17, "AUX2", "Aux 2", RotelCommand.SOURCE_AUX2),
     CAT17_FM(17, "FM", "FM", RotelCommand.SOURCE_FM),
     CAT17_DAB(17, "DAB", "DAB", RotelCommand.SOURCE_DAB),
-    CAT17_USB(17, "USB", "USB", RotelCommand.SOURCE_USB);
+    CAT17_USB(17, "USB", "USB", RotelCommand.SOURCE_USB),
+
+    CAT18_CD(18, "CD", "CD", RotelCommand.SOURCE_CD),
+    CAT18_COAX1(18, "COAX1", "Coax 1", RotelCommand.SOURCE_COAX1),
+    CAT18_COAX2(18, "COAX2", "Coax 2", RotelCommand.SOURCE_COAX2),
+    CAT18_COAX3(18, "COAX3", "Coax 3", RotelCommand.SOURCE_COAX3),
+    CAT18_OPTICAL1(18, "OPTICAL1", "Optical 1", RotelCommand.SOURCE_OPT1),
+    CAT18_OPTICAL2(18, "OPTICAL2", "Optical 2", RotelCommand.SOURCE_OPT2),
+    CAT18_OPTICAL3(18, "OPTICAL3", "Optical 3", RotelCommand.SOURCE_OPT3),
+    CAT18_AUX(18, "AUX", "Aux", RotelCommand.SOURCE_AUX),
+    CAT18_TUNER(18, "TUNER", "Tuner", RotelCommand.SOURCE_TUNER),
+    CAT18_PHONO(18, "PHONO", "Phono", RotelCommand.SOURCE_PHONO),
+    CAT18_BLUETOOTH(18, "BLUETOOTH", "Bluetooth", RotelCommand.SOURCE_BLUETOOTH),
+    CAT18_XLR(18, "XLR", "XLR", RotelCommand.SOURCE_XLR),
+    CAT18_PCUSB(18, "PCUSB", "PC USB", RotelCommand.SOURCE_PCUSB),
+
+    CAT19_CD(19, "CD", "CD", RotelCommand.SOURCE_CD),
+    CAT19_COAX1(19, "COAX1", "Coax 1", RotelCommand.SOURCE_COAX1),
+    CAT19_COAX2(19, "COAX2", "Coax 2", RotelCommand.SOURCE_COAX2),
+    CAT19_COAX3(19, "COAX3", "Coax 3", RotelCommand.SOURCE_COAX3),
+    CAT19_OPTICAL1(19, "OPTICAL1", "Optical 1", RotelCommand.SOURCE_OPT1),
+    CAT19_OPTICAL2(19, "OPTICAL2", "Optical 2", RotelCommand.SOURCE_OPT2),
+    CAT19_OPTICAL3(19, "OPTICAL3", "Optical 3", RotelCommand.SOURCE_OPT3),
+    CAT19_AUX1(19, "AUX1", "Aux 1", RotelCommand.SOURCE_AUX1),
+    CAT19_AUX2(19, "AUX2", "Aux 2", RotelCommand.SOURCE_AUX2),
+    CAT19_TUNER(19, "TUNER", "Tuner", RotelCommand.SOURCE_TUNER),
+    CAT19_PHONO(19, "PHONO", "Phono", RotelCommand.SOURCE_PHONO),
+    CAT19_BLUETOOTH(19, "BLUETOOTH", "Bluetooth", RotelCommand.SOURCE_BLUETOOTH),
+    CAT19_XLR(19, "XLR", "XLR", RotelCommand.SOURCE_XLR),
+    CAT19_PCUSB(19, "PCUSB", "PC USB", RotelCommand.SOURCE_PCUSB),
+
+    CAT20_CD(20, "CD", "CD", RotelCommand.SOURCE_CD),
+    CAT20_COAX1(20, "COAX1", "Coax 1", RotelCommand.SOURCE_COAX1),
+    CAT20_COAX2(20, "COAX2", "Coax 2", RotelCommand.SOURCE_COAX2),
+    CAT20_COAX3(20, "COAX3", "Coax 3", RotelCommand.SOURCE_COAX3),
+    CAT20_OPTICAL1(20, "OPTICAL1", "Optical 1", RotelCommand.SOURCE_OPT1),
+    CAT20_OPTICAL2(20, "OPTICAL2", "Optical 2", RotelCommand.SOURCE_OPT2),
+    CAT20_OPTICAL3(20, "OPTICAL3", "Optical 3", RotelCommand.SOURCE_OPT3),
+    CAT20_AUX1(20, "AUX1", "Aux 1", RotelCommand.SOURCE_AUX1),
+    CAT20_AUX2(20, "AUX2", "Aux 2", RotelCommand.SOURCE_AUX2),
+    CAT20_TUNER(20, "TUNER", "Tuner", RotelCommand.SOURCE_TUNER),
+    CAT20_PHONO(20, "PHONO", "Phono", RotelCommand.SOURCE_PHONO),
+    CAT20_BLUETOOTH(20, "BLUETOOTH", "Bluetooth", RotelCommand.SOURCE_BLUETOOTH),
+    CAT20_XLR1(20, "XLR1", "XLR 1", RotelCommand.SOURCE_XLR1),
+    CAT20_XLR2(20, "XLR2", "XLR 2", RotelCommand.SOURCE_XLR1),
+    CAT20_PCUSB(20, "PCUSB", "PC USB", RotelCommand.SOURCE_PCUSB);
 
     private int category;
     private String name;
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 01c8ed0554e..bb64cb32838 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
@@ -132,7 +132,6 @@ public class RotelHandler extends BaseThingHandler implements RotelMessageEventL
     private int maxBalanceLevel;
     private boolean speakera;
     private boolean speakerb;
-    private boolean useFixedBalanceCmd;
 
     private Object sequenceLock = new Object();
 
@@ -199,15 +198,12 @@ public class RotelHandler extends BaseThingHandler implements RotelMessageEventL
                 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;
@@ -276,6 +272,15 @@ public class RotelHandler extends BaseThingHandler implements RotelMessageEventL
             case THING_TYPE_ID_T14:
                 rotelModel = RotelModel.T14;
                 break;
+            case THING_TYPE_ID_P5:
+                rotelModel = RotelModel.P5;
+                break;
+            case THING_TYPE_ID_X3:
+                rotelModel = RotelModel.X3;
+                break;
+            case THING_TYPE_ID_X5:
+                rotelModel = RotelModel.X5;
+                break;
             default:
                 rotelModel = DEFAULT_MODEL;
                 break;
@@ -908,7 +913,7 @@ public class RotelHandler extends BaseThingHandler implements RotelMessageEventL
                             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);
+                                    RotelCommand.BALANCE_SET);
                         }
                         break;
                     case CHANNEL_SPEAKER_A:
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 ae086f42882..2af3cf7a4eb 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
@@ -15,6 +15,8 @@ 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
 thing-type.rotel.cd14.description = Connection to the Rotel CD14 CD player
+thing-type.rotel.p5.label = P5 Stereo Preamplifier
+thing-type.rotel.p5.description = Connection to the Rotel Michi P5 stereo preamplifier
 thing-type.rotel.ra11.label = RA-11 Integrated Amplifier
 thing-type.rotel.ra11.description = Connection to the Rotel RA-11 integrated amplifier
 thing-type.rotel.ra12.label = RA-12 Integrated Amplifier
@@ -87,9 +89,15 @@ thing-type.rotel.t11.label = T11 Tuner
 thing-type.rotel.t11.description = Connection to the Rotel T11 tuner
 thing-type.rotel.t14.label = T14 Tuner
 thing-type.rotel.t14.description = Connection to the Rotel T14 tuner
+thing-type.rotel.x3.label = X3 Integrated Amplifier
+thing-type.rotel.x3.description = Connection to the Rotel Michi X3 integrated amplifier
+thing-type.rotel.x5.label = X5 Integrated Amplifier
+thing-type.rotel.x5.description = Connection to the Rotel Michi X5 integrated amplifier
 
 # channel types
 
+channel-type.rotel.balance.label = Balance Adjustment
+channel-type.rotel.balance.description = Adjust the speakers left-right balance
 channel-type.rotel.bass.label = Bass Adjustment
 channel-type.rotel.bass.description = Adjust the bass
 channel-type.rotel.brightness.label = Front Panel Display Brightness
@@ -104,20 +112,18 @@ channel-type.rotel.recordSource.label = Record Source
 channel-type.rotel.recordSource.description = Select the source to be recorded
 channel-type.rotel.source.label = Source Input
 channel-type.rotel.source.description = Select the source input
+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
+channel-type.rotel.tcbypass.label = Tone Control Bypass
+channel-type.rotel.tcbypass.description = The user's bass-/treble-settings are bypassed
 channel-type.rotel.track.label = Current Track
 channel-type.rotel.track.description = The current CD track number
 channel-type.rotel.treble.label = Treble Adjustment
 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
 
@@ -242,6 +248,8 @@ source.PCUSB = PC USB
 source.BLUETOOTH = Bluetooth
 source.MULTI = MULTI
 source.XLR = XLR
+source.XLR1 = XLR 1
+source.XLR2 = XLR 2
 source.MAIN = Follow Main Zone Source
 source.RCD = Rotel CD
 source.FM = FM
diff --git a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/p5.xml b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/p5.xml
new file mode 100644
index 00000000000..cd70e6c5ef1
--- /dev/null
+++ b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/p5.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="rotel"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+	xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+	<!-- Rotel P5 Connection Thing Type -->
+	<thing-type id="p5">
+		<label>P5 Stereo Preamplifier</label>
+		<description>Connection to the Rotel Michi P5 stereo preamplifier</description>
+
+		<channels>
+			<channel id="power" typeId="system.power"/>
+			<channel id="source" typeId="source"/>
+			<channel id="volume" typeId="system.volume"/>
+			<channel id="mute" typeId="system.mute"/>
+			<channel id="bass" typeId="bass"/>
+			<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>
+
+		<properties>
+			<property name="protocol">ASCII_V2</property>
+		</properties>
+
+		<config-description-ref uri="thing-type:rotel:serialandip"/>
+	</thing-type>
+
+</thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/x3.xml b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/x3.xml
new file mode 100644
index 00000000000..ef40d586818
--- /dev/null
+++ b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/x3.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="rotel"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+	xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+	<!-- Rotel X3 Connection Thing Type -->
+	<thing-type id="x3">
+		<label>X3 Integrated Amplifier</label>
+		<description>Connection to the Rotel Michi X3 integrated amplifier</description>
+
+		<channels>
+			<channel id="power" typeId="system.power"/>
+			<channel id="source" typeId="source"/>
+			<channel id="volume" typeId="system.volume"/>
+			<channel id="mute" typeId="system.mute"/>
+			<channel id="bass" typeId="bass"/>
+			<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>
+
+		<properties>
+			<property name="protocol">ASCII_V2</property>
+		</properties>
+
+		<config-description-ref uri="thing-type:rotel:serialandip"/>
+	</thing-type>
+
+</thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/x5.xml b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/x5.xml
new file mode 100644
index 00000000000..17e7af859f8
--- /dev/null
+++ b/bundles/org.openhab.binding.rotel/src/main/resources/OH-INF/thing/x5.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="rotel"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+	xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+	<!-- Rotel X5 Connection Thing Type -->
+	<thing-type id="x5">
+		<label>X5 Integrated Amplifier</label>
+		<description>Connection to the Rotel Michi X5 integrated amplifier</description>
+
+		<channels>
+			<channel id="power" typeId="system.power"/>
+			<channel id="source" typeId="source"/>
+			<channel id="volume" typeId="system.volume"/>
+			<channel id="mute" typeId="system.mute"/>
+			<channel id="bass" typeId="bass"/>
+			<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>
+
+		<properties>
+			<property name="protocol">ASCII_V2</property>
+		</properties>
+
+		<config-description-ref uri="thing-type:rotel:serialandip"/>
+	</thing-type>
+
+</thing:thing-descriptions>