]> git.basschouten.com Git - openhab-addons.git/commitdiff
[sonos] Add support for Sonos Arc/Arc SL + new controls for sub/surround speakers...
authorlolodomo <lg.hc@free.fr>
Sun, 24 Jan 2021 15:10:33 +0000 (16:10 +0100)
committerGitHub <noreply@github.com>
Sun, 24 Jan 2021 15:10:33 +0000 (16:10 +0100)
* [sonos] Add support for Sonos Arc/Arc SL + new controls for sub/surround speakers

Related to #9874

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
* Use OnOffType.from

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
bundles/org.openhab.binding.sonos/README.md
bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/SonosBindingConstants.java
bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/discovery/ZonePlayerDiscoveryParticipant.java
bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java
bundles/org.openhab.binding.sonos/src/main/resources/OH-INF/thing/Arc.xml [new file with mode: 0644]
bundles/org.openhab.binding.sonos/src/main/resources/OH-INF/thing/ArcSL.xml [new file with mode: 0644]
bundles/org.openhab.binding.sonos/src/main/resources/OH-INF/thing/channels.xml

index 1b03e7af41b18f742157bb7a7bea2167cd09d752..c3be76fa85cf029d92460596bd9040573d6adf31 100644 (file)
@@ -93,6 +93,12 @@ The devices support the following channels:
 | standalone          | Switch    | W           | Make the Zone Player leave its Group and become a standalone Zone Player                                                                                  | all                                  |
 | state               | String    | R           | The State channel contains state of the Zone Player, e.g. PLAYING, STOPPED, ...                                                                           | all                                  |
 | stop                | Switch    | W           | Write `ON` to this channel: Stops the Zone Player player.                                                                                                 | all                                  |
+| subwoofer           | Switch    | RW          | Enable or disable the subwoofer                                                                                                                           | Arc, Arc SL                          |
+| subwoofergain       | Number    | RW          | Set or get the subwoofer gain adjustment (value in range -15 / 15)                                                                                        | Arc, Arc SL                          |
+| surround            | Switch    | RW          | Enable or disable the surround audio                                                                                                                      | Arc, Arc SL                          |
+| surroundmusicmode   | String    | RW          | Set or get the surround playback mode for music, either 0 for Ambient or 1 for full                                                                       | Arc, Arc SL                          |
+| surroundmusiclevel  | Number    | RW          | Set or get the surround level adjustment for music (value in range -15 / 15)                                                                              | Arc, Arc SL                          |
+| surroundtvlevel     | Number    | RW          | Set or get the surround level adjustment for TV (value in range -15 / 15)                                                                                 | Arc, Arc SL                          |
 | tuneinstationid     | String    | RW          | Provide the current TuneIn station id or play the TuneIn radio given by its station id                                                                    | all                                  |
 | volume              | Dimmer    | RW          | Set or get the master volume of the Zone Player                                                                                                           | all                                  |
 | zonegroupid         | String    | R           | Id of the Zone Group the Zone Player belongs to                                                                                                           | all                                  |
index 08d80138d9725c34da0d6f4c62333f650d3bac3d..4cf9485743174f5c8a194b28ef10c26020451216 100644 (file)
@@ -49,11 +49,13 @@ public class SonosBindingConstants {
     public static final ThingTypeUID CONNECTAMP_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "CONNECTAMP");
     public static final ThingTypeUID AMP_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "Amp");
     public static final ThingTypeUID SYMFONISK_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "SYMFONISK");
+    public static final ThingTypeUID ARC_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "Arc");
+    public static final ThingTypeUID ARC_SL_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "ArcSL");
     public static final ThingTypeUID ZONEPLAYER_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "zoneplayer");
 
-    public static final Set<ThingTypeUID> WITH_LINEIN_THING_TYPES_UIDS = Stream
-            .of(PLAY5_THING_TYPE_UID, PLAYBAR_THING_TYPE_UID, PLAYBASE_THING_TYPE_UID, BEAM_THING_TYPE_UID,
-                    CONNECT_THING_TYPE_UID, CONNECTAMP_THING_TYPE_UID, PORT_THING_TYPE_UID)
+    public static final Set<ThingTypeUID> WITH_LINEIN_THING_TYPES_UIDS = Stream.of(PLAY5_THING_TYPE_UID,
+            PLAYBAR_THING_TYPE_UID, PLAYBASE_THING_TYPE_UID, BEAM_THING_TYPE_UID, CONNECT_THING_TYPE_UID,
+            CONNECTAMP_THING_TYPE_UID, PORT_THING_TYPE_UID, ARC_THING_TYPE_UID, ARC_SL_THING_TYPE_UID)
             .collect(Collectors.toSet());
 
     public static final Set<ThingTypeUID> WITH_ANALOG_LINEIN_THING_TYPES_UIDS = Stream.of(AMP_THING_TYPE_UID)
@@ -62,10 +64,11 @@ public class SonosBindingConstants {
     public static final Set<ThingTypeUID> WITH_DIGITAL_LINEIN_THING_TYPES_UIDS = Stream.of(AMP_THING_TYPE_UID)
             .collect(Collectors.toSet());
 
-    public static final Set<ThingTypeUID> SUPPORTED_KNOWN_THING_TYPES_UIDS = Stream.of(ONE_THING_TYPE_UID,
-            ONE_SL_THING_TYPE_UID, PLAY1_THING_TYPE_UID, PLAY3_THING_TYPE_UID, PLAY5_THING_TYPE_UID,
-            PLAYBAR_THING_TYPE_UID, PLAYBASE_THING_TYPE_UID, BEAM_THING_TYPE_UID, CONNECT_THING_TYPE_UID,
-            CONNECTAMP_THING_TYPE_UID, PORT_THING_TYPE_UID, AMP_THING_TYPE_UID, SYMFONISK_THING_TYPE_UID)
+    public static final Set<ThingTypeUID> SUPPORTED_KNOWN_THING_TYPES_UIDS = Stream
+            .of(ONE_THING_TYPE_UID, ONE_SL_THING_TYPE_UID, PLAY1_THING_TYPE_UID, PLAY3_THING_TYPE_UID,
+                    PLAY5_THING_TYPE_UID, PLAYBAR_THING_TYPE_UID, PLAYBASE_THING_TYPE_UID, BEAM_THING_TYPE_UID,
+                    CONNECT_THING_TYPE_UID, CONNECTAMP_THING_TYPE_UID, PORT_THING_TYPE_UID, AMP_THING_TYPE_UID,
+                    SYMFONISK_THING_TYPE_UID, ARC_THING_TYPE_UID, ARC_SL_THING_TYPE_UID)
             .collect(Collectors.toSet());
 
     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = new HashSet<>(SUPPORTED_KNOWN_THING_TYPES_UIDS);
@@ -120,6 +123,12 @@ public class SonosBindingConstants {
     public static final String STANDALONE = "standalone";
     public static final String STATE = "state";
     public static final String STOP = "stop";
+    public static final String SUBWOOFER = "subwoofer";
+    public static final String SUBWOOFERGAIN = "subwoofergain";
+    public static final String SURROUND = "surround";
+    public static final String SURROUNDMUSICMODE = "surroundmusicmode";
+    public static final String SURROUNDMUSICLEVEL = "surroundmusiclevel";
+    public static final String SURROUNDTVLEVEL = "surroundtvlevel";
     public static final String TUNEINSTATIONID = "tuneinstationid";
     public static final String VOLUME = "volume";
     public static final String ZONEGROUPID = "zonegroupid";
index 4f6e275227b13fd46ca88a4ce6c5fc1ede5124b1..d4458d430edfeab63c549490d903761224406120 100644 (file)
@@ -91,6 +91,9 @@ public class ZonePlayerDiscoveryParticipant implements UpnpDiscoveryParticipant
                     case "One SL":
                         modelName = "OneSL";
                         break;
+                    case "Arc SL":
+                        modelName = "ArcSL";
+                        break;
                     default:
                         break;
                 }
index 15e87d0ccd02ea16790a76289f5602cad0f934d1..bf1b9ad5cfe37f9740fd3c4be8ced9877acf931f 100644 (file)
@@ -111,6 +111,11 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
 
     private static final int TUNEIN_DEFAULT_SERVICE_TYPE = 65031;
 
+    private static final int MIN_SUBWOOFER_GAIN = -15;
+    private static final int MAX_SUBWOOFER_GAIN = 15;
+    private static final int MIN_SURROUND_LEVEL = -15;
+    private static final int MAX_SURROUND_LEVEL = 15;
+
     private final Logger logger = LoggerFactory.getLogger(ZonePlayerHandler.class);
 
     private final ThingRegistry localThingRegistry;
@@ -259,6 +264,24 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
                 case VOLUME:
                     setVolumeForGroup(command);
                     break;
+                case SUBWOOFER:
+                    setSubwoofer(command);
+                    break;
+                case SUBWOOFERGAIN:
+                    setSubwooferGain(command);
+                    break;
+                case SURROUND:
+                    setSurround(command);
+                    break;
+                case SURROUNDMUSICMODE:
+                    setSurroundMusicMode(command);
+                    break;
+                case SURROUNDMUSICLEVEL:
+                    setSurroundMusicLevel(command);
+                    break;
+                case SURROUNDTVLEVEL:
+                    setSurroundTvLevel(command);
+                    break;
                 case ADD:
                     addMember(command);
                     break;
@@ -485,6 +508,24 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
                 case "MuteMaster":
                     updateChannel(MUTE);
                     break;
+                case "SubEnabled":
+                    updateChannel(SUBWOOFER);
+                    break;
+                case "SubGain":
+                    updateChannel(SUBWOOFERGAIN);
+                    break;
+                case "SurroundEnabled":
+                    updateChannel(SURROUND);
+                    break;
+                case "SurroundMode":
+                    updateChannel(SURROUNDMUSICMODE);
+                    break;
+                case "SurroundLevel":
+                    updateChannel(SURROUNDTVLEVEL);
+                    break;
+                case "MusicSurroundLevel":
+                    updateChannel(SURROUNDMUSICLEVEL);
+                    break;
                 case "NightMode":
                     updateChannel(NIGHTMODE);
                     break;
@@ -700,6 +741,42 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
                     newState = isMuted() ? OnOffType.ON : OnOffType.OFF;
                 }
                 break;
+            case SUBWOOFER:
+                value = getSubwooferEnabled();
+                if (value != null) {
+                    newState = OnOffType.from(value);
+                }
+                break;
+            case SUBWOOFERGAIN:
+                value = getSubwooferGain();
+                if (value != null) {
+                    newState = new DecimalType(value);
+                }
+                break;
+            case SURROUND:
+                value = getSurroundEnabled();
+                if (value != null) {
+                    newState = OnOffType.from(value);
+                }
+                break;
+            case SURROUNDMUSICMODE:
+                value = getSurroundMusicMode();
+                if (value != null) {
+                    newState = new StringType(value);
+                }
+                break;
+            case SURROUNDMUSICLEVEL:
+                value = getSurroundMusicLevel();
+                if (value != null) {
+                    newState = new DecimalType(value);
+                }
+                break;
+            case SURROUNDTVLEVEL:
+                value = getSurroundTvLevel();
+                if (value != null) {
+                    newState = new DecimalType(value);
+                }
+                break;
             case NIGHTMODE:
                 value = getNightMode();
                 if (value != null) {
@@ -1238,6 +1315,30 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
         return stateMap.get("VolumeMaster");
     }
 
+    public @Nullable String getSurroundEnabled() {
+        return stateMap.get("SurroundEnabled");
+    }
+
+    public @Nullable String getSurroundMusicMode() {
+        return stateMap.get("SurroundMode");
+    }
+
+    public @Nullable String getSurroundTvLevel() {
+        return stateMap.get("SurroundLevel");
+    }
+
+    public @Nullable String getSurroundMusicLevel() {
+        return stateMap.get("MusicSurroundLevel");
+    }
+
+    public @Nullable String getSubwooferEnabled() {
+        return stateMap.get("SubEnabled");
+    }
+
+    public @Nullable String getSubwooferGain() {
+        return stateMap.get("SubGain");
+    }
+
     public @Nullable String getTransportState() {
         return stateMap.get("TransportState");
     }
@@ -1844,20 +1945,68 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
         }
     }
 
-    public void setNightMode(Command command) {
-        if (command instanceof OnOffType || command instanceof OpenClosedType || command instanceof UpDownType) {
-            setEQ("NightMode", (command.equals(OnOffType.ON) || command.equals(UpDownType.UP)
-                    || command.equals(OpenClosedType.OPEN)) ? "1" : "0");
+    public void setSubwoofer(Command command) {
+        setEqualizerBooleanSetting(command, "SubEnabled");
+    }
+
+    public void setSubwooferGain(Command command) {
+        setEqualizerNumericSetting(command, "SubGain", getSubwooferGain(), MIN_SUBWOOFER_GAIN, MAX_SUBWOOFER_GAIN);
+    }
+
+    public void setSurround(Command command) {
+        setEqualizerBooleanSetting(command, "SurroundEnabled");
+    }
+
+    public void setSurroundMusicMode(Command command) {
+        if (command instanceof StringType) {
+            setEQ("SurroundMode", command.toString());
         }
     }
 
+    public void setSurroundMusicLevel(Command command) {
+        setEqualizerNumericSetting(command, "MusicSurroundLevel", getSurroundMusicLevel(), MIN_SURROUND_LEVEL,
+                MAX_SURROUND_LEVEL);
+    }
+
+    public void setSurroundTvLevel(Command command) {
+        setEqualizerNumericSetting(command, "SurroundLevel", getSurroundTvLevel(), MIN_SURROUND_LEVEL,
+                MAX_SURROUND_LEVEL);
+    }
+
+    public void setNightMode(Command command) {
+        setEqualizerBooleanSetting(command, "NightMode");
+    }
+
     public void setSpeechEnhancement(Command command) {
+        setEqualizerBooleanSetting(command, "DialogLevel");
+    }
+
+    private void setEqualizerBooleanSetting(Command command, String eqType) {
         if (command instanceof OnOffType || command instanceof OpenClosedType || command instanceof UpDownType) {
-            setEQ("DialogLevel", (command.equals(OnOffType.ON) || command.equals(UpDownType.UP)
+            setEQ(eqType, (command.equals(OnOffType.ON) || command.equals(UpDownType.UP)
                     || command.equals(OpenClosedType.OPEN)) ? "1" : "0");
         }
     }
 
+    private void setEqualizerNumericSetting(Command command, String eqType, @Nullable String currentValue, int minValue,
+            int maxValue) {
+        if (command instanceof IncreaseDecreaseType || command instanceof DecimalType) {
+            String newValue = null;
+            if (command == IncreaseDecreaseType.INCREASE && currentValue != null) {
+                int i = Integer.valueOf(currentValue);
+                newValue = String.valueOf(Math.min(maxValue, i + 1));
+            } else if (command == IncreaseDecreaseType.DECREASE && currentValue != null) {
+                int i = Integer.valueOf(currentValue);
+                newValue = String.valueOf(Math.max(minValue, i - 1));
+            } else if (command instanceof DecimalType) {
+                newValue = String.valueOf(((DecimalType) command).intValue());
+            } else {
+                return;
+            }
+            setEQ(eqType, newValue);
+        }
+    }
+
     private void setEQ(String eqType, String value) {
         try {
             Map<String, String> inputs = new HashMap<>();
diff --git a/bundles/org.openhab.binding.sonos/src/main/resources/OH-INF/thing/Arc.xml b/bundles/org.openhab.binding.sonos/src/main/resources/OH-INF/thing/Arc.xml
new file mode 100644 (file)
index 0000000..fa4cd8b
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="sonos"
+       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">
+
+       <!-- Soundbar Arc Thing Type -->
+       <thing-type id="Arc" listed="false">
+               <label>Arc</label>
+               <description>Represents SONOS Arc soundbar</description>
+
+               <channels>
+                       <channel id="add" typeId="add"/>
+                       <channel id="alarm" typeId="alarm"/>
+                       <channel id="alarmproperties" typeId="alarmproperties"/>
+                       <channel id="alarmrunning" typeId="alarmrunning"/>
+                       <channel id="control" typeId="system.media-control"/>
+                       <channel id="currentalbum" typeId="currentalbum"/>
+                       <channel id="currentalbumart" typeId="currentalbumart"/>
+                       <channel id="currentalbumarturl" typeId="currentalbumarturl"/>
+                       <channel id="currentartist" typeId="system.media-artist"/>
+                       <channel id="currenttitle" typeId="system.media-title"/>
+                       <channel id="currenttrack" typeId="currenttrack"/>
+                       <channel id="shuffle" typeId="shuffle"/>
+                       <channel id="repeat" typeId="repeat"/>
+                       <channel id="favorite" typeId="favorite"/>
+                       <channel id="led" typeId="led"/>
+                       <channel id="localcoordinator" typeId="localcoordinator"/>
+                       <channel id="mute" typeId="system.mute"/>
+                       <channel id="notificationsound" typeId="notificationsound"/>
+                       <channel id="playlist" typeId="playlist"/>
+                       <channel id="clearqueue" typeId="clearqueue"/>
+                       <channel id="playlinein" typeId="playlinein"/>
+                       <channel id="playqueue" typeId="playqueue"/>
+                       <channel id="playtrack" typeId="playtrack"/>
+                       <channel id="playuri" typeId="playuri"/>
+                       <channel id="publicaddress" typeId="publicaddress"/>
+                       <channel id="radio" typeId="radio"/>
+                       <channel id="remove" typeId="remove"/>
+                       <channel id="restore" typeId="restore"/>
+                       <channel id="restoreall" typeId="restoreall"/>
+                       <channel id="save" typeId="save"/>
+                       <channel id="saveall" typeId="saveall"/>
+                       <channel id="snooze" typeId="snooze"/>
+                       <channel id="standalone" typeId="standalone"/>
+                       <channel id="state" typeId="state"/>
+                       <channel id="stop" typeId="stop"/>
+                       <channel id="tuneinstationid" typeId="tuneinstationid"/>
+                       <channel id="volume" typeId="system.volume"/>
+                       <channel id="zonegroupid" typeId="zonegroupid"/>
+                       <channel id="zonename" typeId="zonename"/>
+                       <channel id="coordinator" typeId="coordinator"/>
+                       <channel id="sleeptimer" typeId="sleeptimer"/>
+                       <channel id="currenttransporturi" typeId="currenttransporturi"/>
+                       <channel id="currenttrackuri" typeId="currenttrackuri"/>
+                       <!-- Extended SONOS channels -->
+                       <channel id="linein" typeId="linein"/>
+                       <channel id="nightmode" typeId="nightmode"/>
+                       <channel id="speechenhancement" typeId="speechenhancement"/>
+                       <channel id="subwoofer" typeId="subwoofer"/>
+                       <channel id="subwoofergain" typeId="subwoofergain"/>
+                       <channel id="surround" typeId="surround"/>
+                       <channel id="surroundmusicmode" typeId="surroundmusicmode"/>
+                       <channel id="surroundmusiclevel" typeId="surroundmusiclevel"/>
+                       <channel id="surroundtvlevel" typeId="surroundtvlevel"/>
+               </channels>
+
+               <properties>
+                       <property name="vendor">SONOS</property>
+                       <property name="modelId">Arc</property>
+               </properties>
+
+               <representation-property>udn</representation-property>
+
+               <config-description-ref uri="thing-type:sonos:zoneplayer"/>
+       </thing-type>
+</thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.sonos/src/main/resources/OH-INF/thing/ArcSL.xml b/bundles/org.openhab.binding.sonos/src/main/resources/OH-INF/thing/ArcSL.xml
new file mode 100644 (file)
index 0000000..ea77c44
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="sonos"
+       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">
+
+       <!-- Soundbar Arc SL Thing Type -->
+       <thing-type id="ArcSL" listed="false">
+               <label>Arc</label>
+               <description>Represents SONOS Arc SL soundbar</description>
+
+               <channels>
+                       <channel id="add" typeId="add"/>
+                       <channel id="alarm" typeId="alarm"/>
+                       <channel id="alarmproperties" typeId="alarmproperties"/>
+                       <channel id="alarmrunning" typeId="alarmrunning"/>
+                       <channel id="control" typeId="system.media-control"/>
+                       <channel id="currentalbum" typeId="currentalbum"/>
+                       <channel id="currentalbumart" typeId="currentalbumart"/>
+                       <channel id="currentalbumarturl" typeId="currentalbumarturl"/>
+                       <channel id="currentartist" typeId="system.media-artist"/>
+                       <channel id="currenttitle" typeId="system.media-title"/>
+                       <channel id="currenttrack" typeId="currenttrack"/>
+                       <channel id="shuffle" typeId="shuffle"/>
+                       <channel id="repeat" typeId="repeat"/>
+                       <channel id="favorite" typeId="favorite"/>
+                       <channel id="led" typeId="led"/>
+                       <channel id="localcoordinator" typeId="localcoordinator"/>
+                       <channel id="mute" typeId="system.mute"/>
+                       <channel id="notificationsound" typeId="notificationsound"/>
+                       <channel id="playlist" typeId="playlist"/>
+                       <channel id="clearqueue" typeId="clearqueue"/>
+                       <channel id="playlinein" typeId="playlinein"/>
+                       <channel id="playqueue" typeId="playqueue"/>
+                       <channel id="playtrack" typeId="playtrack"/>
+                       <channel id="playuri" typeId="playuri"/>
+                       <channel id="publicaddress" typeId="publicaddress"/>
+                       <channel id="radio" typeId="radio"/>
+                       <channel id="remove" typeId="remove"/>
+                       <channel id="restore" typeId="restore"/>
+                       <channel id="restoreall" typeId="restoreall"/>
+                       <channel id="save" typeId="save"/>
+                       <channel id="saveall" typeId="saveall"/>
+                       <channel id="snooze" typeId="snooze"/>
+                       <channel id="standalone" typeId="standalone"/>
+                       <channel id="state" typeId="state"/>
+                       <channel id="stop" typeId="stop"/>
+                       <channel id="tuneinstationid" typeId="tuneinstationid"/>
+                       <channel id="volume" typeId="system.volume"/>
+                       <channel id="zonegroupid" typeId="zonegroupid"/>
+                       <channel id="zonename" typeId="zonename"/>
+                       <channel id="coordinator" typeId="coordinator"/>
+                       <channel id="sleeptimer" typeId="sleeptimer"/>
+                       <channel id="currenttransporturi" typeId="currenttransporturi"/>
+                       <channel id="currenttrackuri" typeId="currenttrackuri"/>
+                       <!-- Extended SONOS channels -->
+                       <channel id="linein" typeId="linein"/>
+                       <channel id="nightmode" typeId="nightmode"/>
+                       <channel id="speechenhancement" typeId="speechenhancement"/>
+                       <channel id="subwoofer" typeId="subwoofer"/>
+                       <channel id="subwoofergain" typeId="subwoofergain"/>
+                       <channel id="surround" typeId="surround"/>
+                       <channel id="surroundmusicmode" typeId="surroundmusicmode"/>
+                       <channel id="surroundmusiclevel" typeId="surroundmusiclevel"/>
+                       <channel id="surroundtvlevel" typeId="surroundtvlevel"/>
+               </channels>
+
+               <properties>
+                       <property name="vendor">SONOS</property>
+                       <property name="modelId">Arc SL</property>
+               </properties>
+
+               <representation-property>udn</representation-property>
+
+               <config-description-ref uri="thing-type:sonos:zoneplayer"/>
+       </thing-type>
+</thing:thing-descriptions>
index c6281e24328d748222340f31b3419cdc58dca8ce..f826a671d85449daff3ae32f5d97920b00c64436 100644 (file)
                <description>Stop the Zone Player. ON if the player is stopped.</description>
        </channel-type>
 
+       <channel-type id="subwoofer" advanced="true">
+               <item-type>Switch</item-type>
+               <label>Subwoofer</label>
+               <description>Enable or disable the subwoofer</description>
+       </channel-type>
+
+       <channel-type id="subwoofergain" advanced="true">
+               <item-type>Number</item-type>
+               <label>Subwoofer Gain</label>
+               <description>Set or get the subwoofer gain adjustment</description>
+               <state min="-15" max="15" step="1" readOnly="false" pattern="%d"/>
+       </channel-type>
+
+       <channel-type id="surround" advanced="true">
+               <item-type>Switch</item-type>
+               <label>Surround Audio</label>
+               <description>Enable or disable the surround audio</description>
+       </channel-type>
+
+       <channel-type id="surroundmusicmode" advanced="true">
+               <item-type>String</item-type>
+               <label>Surround Music Mode</label>
+               <description>Set or get the surround playback mode for music</description>
+               <state readOnly="false">
+                       <options>
+                               <option value="0">Ambient</option>
+                               <option value="1">Full</option>
+                       </options>
+               </state>
+       </channel-type>
+
+       <channel-type id="surroundmusiclevel" advanced="true">
+               <item-type>Number</item-type>
+               <label>Surround Music Level</label>
+               <description>Set or get the surround level adjustment for music</description>
+               <state min="-15" max="15" step="1" readOnly="false" pattern="%d"/>
+       </channel-type>
+
+       <channel-type id="surroundtvlevel" advanced="true">
+               <item-type>Number</item-type>
+               <label>Surround TV Level</label>
+               <description>Set or get the surround level adjustment for TV</description>
+               <state min="-15" max="15" step="1" readOnly="false" pattern="%d"/>
+       </channel-type>
+
        <channel-type id="tuneinstationid" advanced="true">
                <item-type>String</item-type>
                <label>TuneIn Station Id</label>