From 997f2befe21f7f0d4953692ea5982293210150d6 Mon Sep 17 00:00:00 2001 From: Henning Treu Date: Wed, 21 Feb 2018 15:27:12 +0100 Subject: [PATCH] WIP: Extend ChannelType description by command options This is WIP and open for discussion. This addresses #5099 by adding command options as an alternative to a state description. The implementation is naive and straigt forward. Command options will be rendered as push buttons by UIs and send the corresponding command value as a command to the channel. With this proposal, the state of the channel will not be represented in the UI, so ThingHandelers may not even update the state. Signed-off-by: Henning Treu --- ...annelStateDescriptionProviderOSGiTest.java | 8 +-- .../xml/internal/ChannelTypeConverter.java | 42 ++++++++++++++- .../xml/internal/ThingDescriptionReader.java | 1 + .../xml/internal/XmlChannelTypeProvider.java | 7 +++ .../thing-description-1.0.0.xsd | 11 +++- .../core/thing/dto/ChannelTypeDTO.java | 6 ++- .../core/thing/type/ChannelType.java | 54 +++++++++++++++++++ .../smarthome/core/types/CommandOption.java | 52 ++++++++++++++++++ .../internal/channel/ChannelTypeResource.java | 3 +- .../test/hue/TestHueChannelTypeProvider.java | 9 ++-- .../ESH-INF/thing/channel-types.xml | 8 ++- .../ESH-INF/thing/channels.xml | 7 ++- 12 files changed, 188 insertions(+), 20 deletions(-) create mode 100644 bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/types/CommandOption.java diff --git a/bundles/core/org.eclipse.smarthome.core.thing.test/src/test/java/org/eclipse/smarthome/core/thing/internal/ChannelStateDescriptionProviderOSGiTest.java b/bundles/core/org.eclipse.smarthome.core.thing.test/src/test/java/org/eclipse/smarthome/core/thing/internal/ChannelStateDescriptionProviderOSGiTest.java index 62095f3f07b..df986e0af38 100644 --- a/bundles/core/org.eclipse.smarthome.core.thing.test/src/test/java/org/eclipse/smarthome/core/thing/internal/ChannelStateDescriptionProviderOSGiTest.java +++ b/bundles/core/org.eclipse.smarthome.core.thing.test/src/test/java/org/eclipse/smarthome/core/thing/internal/ChannelStateDescriptionProviderOSGiTest.java @@ -112,13 +112,13 @@ public void setup() { final ChannelType channelType2 = new ChannelType(new ChannelTypeUID("hue:num"), false, "Number", " ", "", null, null, state2, null); final ChannelType channelType3 = new ChannelType(new ChannelTypeUID("hue:info"), true, "String", " ", "", null, - null, null, null); + null, (StateDescription) null, null); final ChannelType channelType4 = new ChannelType(new ChannelTypeUID("hue:color"), false, "Color", "Color", "", - "ColorLight", null, null, null); + "ColorLight", null, (StateDescription) null, null); final ChannelType channelType5 = new ChannelType(new ChannelTypeUID("hue:brightness"), false, "Dimmer", - "Brightness", "", "DimmableLight", null, null, null); + "Brightness", "", "DimmableLight", null, (StateDescription) null, null); final ChannelType channelType6 = new ChannelType(new ChannelTypeUID("hue:switch"), false, "Switch", "Switch", - "", "Light", null, null, null); + "", "Light", null, (StateDescription) null, null); final ChannelType channelType7 = new ChannelType(new ChannelTypeUID("hue:num-dynamic"), false, "Number", " ", "", "Light", null, state, null); diff --git a/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/ChannelTypeConverter.java b/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/ChannelTypeConverter.java index b6ab892815d..3f9796af8af 100644 --- a/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/ChannelTypeConverter.java +++ b/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/ChannelTypeConverter.java @@ -13,10 +13,12 @@ package org.eclipse.smarthome.core.thing.xml.internal; import java.net.URI; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; + import org.eclipse.smarthome.config.core.ConfigDescription; import org.eclipse.smarthome.config.xml.util.ConverterAttributeMapValidator; import org.eclipse.smarthome.config.xml.util.NodeIterator; @@ -24,8 +26,10 @@ import org.eclipse.smarthome.core.thing.type.ChannelKind; import org.eclipse.smarthome.core.thing.type.ChannelType; import org.eclipse.smarthome.core.thing.type.ChannelTypeUID; +import org.eclipse.smarthome.core.types.CommandOption; import org.eclipse.smarthome.core.types.EventDescription; import org.eclipse.smarthome.core.types.StateDescription; + import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.UnmarshallingContext; @@ -127,6 +131,33 @@ private EventDescription readEventDescription(NodeIterator nodeIterator) { return null; } + private List readCommandOptions(NodeIterator nodeIterator) throws ConversionException { + List commandOptions = null; + + List commandOptionsNode = nodeIterator.nextList("command-options", false); + + if (commandOptionsNode != null) { + commandOptions = new ArrayList<>(commandOptionsNode.size()); + + for (Object coNodeObject : commandOptionsNode) { + NodeValue commandOptionNode = (NodeValue) coNodeObject; + + if ("option".equals(commandOptionNode.getNodeName())) { + String name = (String) commandOptionNode.getValue(); + String command = commandOptionNode.getAttributes().get("value"); + + if (name != null && command != null) { + commandOptions.add(new CommandOption(command, name)); + } + } else { + throw new ConversionException("The 'command-options' node must only contain 'option' nodes!"); + } + } + } + + return commandOptions; + } + @Override protected ChannelTypeXmlResult unmarshalType(HierarchicalStreamReader reader, UnmarshallingContext context, Map attributes, NodeIterator nodeIterator) throws ConversionException { @@ -142,6 +173,7 @@ protected ChannelTypeXmlResult unmarshalType(HierarchicalStreamReader reader, Un String description = super.readDescription(nodeIterator); String category = readCategory(nodeIterator); Set tags = readTags(nodeIterator); + List commandOptions = readCommandOptions(nodeIterator); StateDescription stateDescription = readStateDescription(nodeIterator); EventDescription eventDescription = readEventDescription(nodeIterator); @@ -153,8 +185,14 @@ protected ChannelTypeXmlResult unmarshalType(HierarchicalStreamReader reader, Un kind = "state"; } - ChannelType channelType = new ChannelType(channelTypeUID, advanced, itemType, ChannelKind.parse(kind), label, - description, category, tags, stateDescription, eventDescription, (URI) configDescriptionObjects[0]); + ChannelType channelType; + if (stateDescription == null && kind.equalsIgnoreCase("state") && commandOptions != null) { + channelType = new ChannelType(channelTypeUID, advanced, itemType, label, description, category, tags, + commandOptions, (URI) configDescriptionObjects[0]); + } else { + channelType = new ChannelType(channelTypeUID, advanced, itemType, ChannelKind.parse(kind), label, + description, category, tags, stateDescription, eventDescription, (URI) configDescriptionObjects[0]); + } ChannelTypeXmlResult channelTypeXmlResult = new ChannelTypeXmlResult(channelType, (ConfigDescription) configDescriptionObjects[1], system); diff --git a/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/ThingDescriptionReader.java b/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/ThingDescriptionReader.java index 295066e9beb..558781ffd8d 100644 --- a/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/ThingDescriptionReader.java +++ b/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/ThingDescriptionReader.java @@ -109,6 +109,7 @@ public void registerAliases(XStream xstream) { xstream.alias("properties", NodeList.class); xstream.alias("property", NodeValue.class); xstream.alias("representation-property", NodeValue.class); + xstream.alias("command-options", NodeList.class); } } diff --git a/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/XmlChannelTypeProvider.java b/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/XmlChannelTypeProvider.java index ece9facac61..163cdab8987 100644 --- a/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/XmlChannelTypeProvider.java +++ b/bundles/core/org.eclipse.smarthome.core.thing.xml/src/main/java/org/eclipse/smarthome/core/thing/xml/internal/XmlChannelTypeProvider.java @@ -24,6 +24,7 @@ import org.eclipse.smarthome.core.thing.i18n.ThingTypeI18nUtil; import org.eclipse.smarthome.core.thing.type.ChannelGroupType; import org.eclipse.smarthome.core.thing.type.ChannelGroupTypeUID; +import org.eclipse.smarthome.core.thing.type.ChannelKind; import org.eclipse.smarthome.core.thing.type.ChannelType; import org.eclipse.smarthome.core.thing.type.ChannelTypeProvider; import org.eclipse.smarthome.core.thing.type.ChannelTypeUID; @@ -108,6 +109,12 @@ protected ChannelType localize(Bundle bundle, ChannelType channelType, Locale lo channelType.getDescription(), locale); StateDescription state = createLocalizedChannelState(bundle, channelType, channelTypeUID, locale); + if (state == null && channelType.getKind() == ChannelKind.STATE && channelType.getCommandOptions() != null) { + return new ChannelType(channelTypeUID, channelType.isAdvanced(), channelType.getItemType(), label, + description, channelType.getCategory(), channelType.getTags(), channelType.getCommandOptions(), + channelType.getEvent(), channelType.getConfigDescriptionURI()); + } + return new ChannelType(channelTypeUID, channelType.isAdvanced(), channelType.getItemType(), channelType.getKind(), label, description, channelType.getCategory(), channelType.getTags(), state, channelType.getEvent(), channelType.getConfigDescriptionURI()); diff --git a/bundles/core/org.eclipse.smarthome.core.thing.xml/thing-description-1.0.0.xsd b/bundles/core/org.eclipse.smarthome.core.thing.xml/thing-description-1.0.0.xsd index d5d8e774b8f..79a79f3b042 100644 --- a/bundles/core/org.eclipse.smarthome.core.thing.xml/thing-description-1.0.0.xsd +++ b/bundles/core/org.eclipse.smarthome.core.thing.xml/thing-description-1.0.0.xsd @@ -61,7 +61,10 @@ - + + + + @@ -160,6 +163,12 @@ + + + + + + diff --git a/bundles/core/org.eclipse.smarthome.core.thing/src/main/java/org/eclipse/smarthome/core/thing/dto/ChannelTypeDTO.java b/bundles/core/org.eclipse.smarthome.core.thing/src/main/java/org/eclipse/smarthome/core/thing/dto/ChannelTypeDTO.java index b6614dad126..b27b3fd001a 100644 --- a/bundles/core/org.eclipse.smarthome.core.thing/src/main/java/org/eclipse/smarthome/core/thing/dto/ChannelTypeDTO.java +++ b/bundles/core/org.eclipse.smarthome.core.thing/src/main/java/org/eclipse/smarthome/core/thing/dto/ChannelTypeDTO.java @@ -14,9 +14,11 @@ import java.util.List; import java.util.Set; + import org.eclipse.smarthome.config.core.dto.ConfigDescriptionParameterDTO; import org.eclipse.smarthome.config.core.dto.ConfigDescriptionParameterGroupDTO; import org.eclipse.smarthome.core.thing.type.ChannelKind; +import org.eclipse.smarthome.core.types.CommandOption; import org.eclipse.smarthome.core.types.StateDescription; /** @@ -38,6 +40,7 @@ public class ChannelTypeDTO { public Set tags; public String UID; public boolean advanced; + public List commandOptions; public ChannelTypeDTO() { } @@ -45,7 +48,7 @@ public ChannelTypeDTO() { public ChannelTypeDTO(String UID, String label, String description, String category, String itemType, ChannelKind kind, List parameters, List parameterGroups, StateDescription stateDescription, - Set tags, boolean advanced) { + Set tags, boolean advanced, List commandOptions) { this.UID = UID; this.label = label; this.description = description; @@ -57,5 +60,6 @@ public ChannelTypeDTO(String UID, String label, String description, String categ this.kind = kind.toString(); this.itemType = itemType; this.advanced = advanced; + this.commandOptions = commandOptions; } } diff --git a/bundles/core/org.eclipse.smarthome.core.thing/src/main/java/org/eclipse/smarthome/core/thing/type/ChannelType.java b/bundles/core/org.eclipse.smarthome.core.thing/src/main/java/org/eclipse/smarthome/core/thing/type/ChannelType.java index d2a1bf167c4..37c374ea04e 100644 --- a/bundles/core/org.eclipse.smarthome.core.thing/src/main/java/org/eclipse/smarthome/core/thing/type/ChannelType.java +++ b/bundles/core/org.eclipse.smarthome.core.thing/src/main/java/org/eclipse/smarthome/core/thing/type/ChannelType.java @@ -15,9 +15,12 @@ import java.net.URI; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; + import org.eclipse.smarthome.config.core.ConfigDescription; import org.eclipse.smarthome.core.thing.Channel; +import org.eclipse.smarthome.core.types.CommandOption; import org.eclipse.smarthome.core.types.EventDescription; import org.eclipse.smarthome.core.types.StateDescription; @@ -29,6 +32,7 @@ * Hint: This class is immutable. * * @author Michael Grammling - Initial Contribution + * @author Henning Treu - add command options */ public class ChannelType extends AbstractDescriptionType { @@ -38,6 +42,7 @@ public class ChannelType extends AbstractDescriptionType { private final Set tags; private final String category; private final StateDescription state; + private final List commandOptions; private final EventDescription event; private final URI configDescriptionURI; @@ -70,6 +75,38 @@ public ChannelType(ChannelTypeUID uid, boolean advanced, String itemType, String } } + /** + * Creates a new instance of a "write-only" {@link ChannelType} with command options. The purpose of this + * {@link ChannelType} is to send command to a device without updating the state of the corresponding channel. + * E.g. activate a special device mode which is not represented as a definitive state. + * + * @param uid the unique identifier which identifies this Channel type within + * the overall system (must neither be null, nor empty) + * @param advanced true if this channel type contains advanced features, otherwise false + * @param itemType the item type of this Channel type, e.g. {@code ColorItem} (must neither be null nor empty) + * @param label the human readable label for the according type + * (must neither be null nor empty) + * @param description the human readable description for the according type + * (could be null or empty) + * @param category the category of this Channel type, e.g. {@code TEMPERATURE} (could be null or empty) + * @param tags all tags of this {@link ChannelType}, e.g. {@code Alarm} (could be null or empty) + * @param commandOptions a list of {@link CommandOption}s which should be rendered as push-buttons. The command + * values will be send to the channel from this {@link ChannelType}. + * @param configDescriptionURI the link to the concrete ConfigDescription (could be null) + */ + public ChannelType(ChannelTypeUID uid, boolean advanced, String itemType, String label, String description, + String category, Set tags, List commandOptions, URI configDescriptionURI) { + this(uid, advanced, itemType, ChannelKind.STATE, label, description, category, tags, null, commandOptions, null, + configDescriptionURI); + } + + public ChannelType(ChannelTypeUID channelTypeUID, boolean advanced, String itemType, String label, + String description, String category, Set tags, List commandOptions, + EventDescription event, URI configDescriptionURI) { + this(channelTypeUID, advanced, itemType, ChannelKind.STATE, label, description, category, tags, null, + commandOptions, event, configDescriptionURI); + } + /** * Creates a new instance of this class with the specified parameters. * @@ -93,6 +130,14 @@ public ChannelType(ChannelTypeUID uid, boolean advanced, String itemType, String public ChannelType(ChannelTypeUID uid, boolean advanced, String itemType, ChannelKind kind, String label, String description, String category, Set tags, StateDescription state, EventDescription event, URI configDescriptionURI) throws IllegalArgumentException { + this(uid, advanced, itemType, kind, label, description, category, tags, state, null, event, + configDescriptionURI); + } + + private ChannelType(ChannelTypeUID uid, boolean advanced, String itemType, ChannelKind kind, String label, + String description, String category, Set tags, StateDescription state, + List commandOptions, EventDescription event, URI configDescriptionURI) + throws IllegalArgumentException { super(uid, label, description); if (kind == null) { @@ -119,6 +164,11 @@ public ChannelType(ChannelTypeUID uid, boolean advanced, String itemType, Channe this.advanced = advanced; this.category = category; this.state = state; + if (state == null && commandOptions != null) { + this.commandOptions = commandOptions; + } else { + this.commandOptions = null; + } this.event = event; } @@ -209,4 +259,8 @@ public String getCategory() { return category; } + public List getCommandOptions() { + return commandOptions; + } + } diff --git a/bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/types/CommandOption.java b/bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/types/CommandOption.java new file mode 100644 index 00000000000..e28e0fede3b --- /dev/null +++ b/bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/types/CommandOption.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.smarthome.core.types; + +import java.nio.channels.Channel; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * Represents a command option for "write only" command {@link Channel}s. CommandOptions will be rendered as + * push-buttons in the UI and will not represent a state. + * + * @author Henning Treu - initial contribution + * + */ +@NonNullByDefault +public class CommandOption { + + /** + * The command which will be send to the Channel + */ + private final String command; + + /** + * The name of the command which will be displayed in the UI. + */ + private final String name; + + public CommandOption(String command, String name) { + this.command = command; + this.name = name; + } + + public String getCommand() { + return command; + } + + public String getName() { + return name; + } + +} diff --git a/bundles/io/org.eclipse.smarthome.io.rest.core/src/main/java/org/eclipse/smarthome/io/rest/core/internal/channel/ChannelTypeResource.java b/bundles/io/org.eclipse.smarthome.io.rest.core/src/main/java/org/eclipse/smarthome/io/rest/core/internal/channel/ChannelTypeResource.java index d70080fe053..c258f892a38 100644 --- a/bundles/io/org.eclipse.smarthome.io.rest.core/src/main/java/org/eclipse/smarthome/io/rest/core/internal/channel/ChannelTypeResource.java +++ b/bundles/io/org.eclipse.smarthome.io.rest.core/src/main/java/org/eclipse/smarthome/io/rest/core/internal/channel/ChannelTypeResource.java @@ -196,7 +196,8 @@ private ChannelTypeDTO convertToChannelTypeDTO(ChannelType channelType, Locale l return new ChannelTypeDTO(channelType.getUID().toString(), channelType.getLabel(), channelType.getDescription(), channelType.getCategory(), channelType.getItemType(), channelType.getKind(), parameters, - parameterGroups, channelType.getState(), channelType.getTags(), channelType.isAdvanced()); + parameterGroups, channelType.getState(), channelType.getTags(), channelType.isAdvanced(), + channelType.getCommandOptions()); } @Override diff --git a/bundles/model/org.eclipse.smarthome.model.thing.tests/src/org/eclipse/smarthome/model/thing/test/hue/TestHueChannelTypeProvider.java b/bundles/model/org.eclipse.smarthome.model.thing.tests/src/org/eclipse/smarthome/model/thing/test/hue/TestHueChannelTypeProvider.java index 0eeabf429f5..b3eb81cd7b8 100644 --- a/bundles/model/org.eclipse.smarthome.model.thing.tests/src/org/eclipse/smarthome/model/thing/test/hue/TestHueChannelTypeProvider.java +++ b/bundles/model/org.eclipse.smarthome.model.thing.tests/src/org/eclipse/smarthome/model/thing/test/hue/TestHueChannelTypeProvider.java @@ -24,6 +24,7 @@ import org.eclipse.smarthome.core.thing.type.ChannelType; import org.eclipse.smarthome.core.thing.type.ChannelTypeProvider; import org.eclipse.smarthome.core.thing.type.ChannelTypeUID; +import org.eclipse.smarthome.core.types.StateDescription; /** * @@ -47,14 +48,14 @@ public class TestHueChannelTypeProvider implements ChannelTypeProvider { public TestHueChannelTypeProvider() { try { ChannelType ctColor = new ChannelType(COLOR_CHANNEL_TYPE_UID, false, "Color", "colorLabel", "description", - null, null, null, new URI("hue", "LCT001:color", null)); + null, null, (StateDescription) null, new URI("hue", "LCT001:color", null)); ChannelType ctColorTemperature = new ChannelType(COLOR_TEMP_CHANNEL_TYPE_UID, false, "Dimmer", - "colorTemperatureLabel", "description", null, null, null, + "colorTemperatureLabel", "description", null, null, (StateDescription) null, new URI("hue", "LCT001:color_temperature", null)); ChannelType ctColorX = new ChannelType(COLORX_CHANNEL_TYPE_UID, false, "Color", "colorLabel", "description", - null, null, null, new URI("Xhue", "XLCT001:Xcolor", null)); + null, null, (StateDescription) null, new URI("Xhue", "XLCT001:Xcolor", null)); ChannelType ctColorTemperatureX = new ChannelType(COLORX_TEMP_CHANNEL_TYPE_UID, false, "Dimmer", - "colorTemperatureLabel", "description", null, null, null, + "colorTemperatureLabel", "description", null, null, (StateDescription) null, new URI("Xhue", "XLCT001:Xcolor_temperature", null)); channelTypes = Arrays.asList(ctColor, ctColorTemperature, ctColorX, ctColorTemperatureX); diff --git a/bundles/test/org.eclipse.smarthome.magic/ESH-INF/thing/channel-types.xml b/bundles/test/org.eclipse.smarthome.magic/ESH-INF/thing/channel-types.xml index 613efd43a19..93d4fba640e 100644 --- a/bundles/test/org.eclipse.smarthome.magic/ESH-INF/thing/channel-types.xml +++ b/bundles/test/org.eclipse.smarthome.magic/ESH-INF/thing/channel-types.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0 /Users/henning/work/smarthome-master2/git/smarthome/bundles/core/org.eclipse.smarthome.core.thing.xml/thing-description-1.0.0.xsd"> Switch @@ -51,13 +51,11 @@ String The alert channel allows a temporary change to the bulb’s state. - - + - - + diff --git a/extensions/binding/org.eclipse.smarthome.binding.sonos/ESH-INF/thing/channels.xml b/extensions/binding/org.eclipse.smarthome.binding.sonos/ESH-INF/thing/channels.xml index 7bdd28fb858..4ad8dc956b3 100644 --- a/extensions/binding/org.eclipse.smarthome.binding.sonos/ESH-INF/thing/channels.xml +++ b/extensions/binding/org.eclipse.smarthome.binding.sonos/ESH-INF/thing/channels.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0 /Users/henning/work/smarthome-master2/git/smarthome/bundles/core/org.eclipse.smarthome.core.thing.xml/thing-description-1.0.0.xsd"> @@ -31,9 +31,12 @@ - Switch + String Suppress all songs from the current queue + + +