Channel groups should not require static channels (#696)

* channel groups should not require static channels
* Added unit tests

Also-by: Christoph Weitkamp <github@christophweitkamp.de>
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
pull/705/head
Thomas Weißschuh 2019-04-08 21:44:52 +02:00 committed by Markus Rathgeb
parent 7838a6a46f
commit 82b7ff6db9
4 changed files with 72 additions and 11 deletions

View File

@ -56,7 +56,7 @@ public class ChannelGroupTypeConverter extends AbstractDescriptionTypeConverter<
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected List<ChannelXmlResult> readChannelTypeDefinitions(NodeIterator nodeIterator) throws ConversionException { protected List<ChannelXmlResult> readChannelTypeDefinitions(NodeIterator nodeIterator) throws ConversionException {
return (List<ChannelXmlResult>) nodeIterator.nextList("channels", true); return (List<ChannelXmlResult>) nodeIterator.nextList("channels", false);
} }
@Override @Override

View File

@ -88,7 +88,7 @@
<xs:element name="label" type="xs:string"/> <xs:element name="label" type="xs:string"/>
<xs:element name="description" type="xs:string" minOccurs="0"/> <xs:element name="description" type="xs:string" minOccurs="0"/>
<xs:element name="category" type="xs:string" minOccurs="0"/> <xs:element name="category" type="xs:string" minOccurs="0"/>
<xs:element name="channels" type="thing-description:channels" minOccurs="1"/> <xs:element name="channels" type="thing-description:channels" minOccurs="0"/>
</xs:sequence> </xs:sequence>
<xs:attribute name="id" type="config-description:idRestrictionPattern" use="required"/> <xs:attribute name="id" type="config-description:idRestrictionPattern" use="required"/>
<xs:attribute name="advanced" type="xs:boolean" default="false" use="optional"/> <xs:attribute name="advanced" type="xs:boolean" default="false" use="optional"/>

View File

@ -24,6 +24,9 @@ import java.util.Set;
import org.eclipse.smarthome.core.thing.binding.ThingTypeProvider; import org.eclipse.smarthome.core.thing.binding.ThingTypeProvider;
import org.eclipse.smarthome.core.thing.type.BridgeType; import org.eclipse.smarthome.core.thing.type.BridgeType;
import org.eclipse.smarthome.core.thing.type.ChannelDefinition; import org.eclipse.smarthome.core.thing.type.ChannelDefinition;
import org.eclipse.smarthome.core.thing.type.ChannelGroupDefinition;
import org.eclipse.smarthome.core.thing.type.ChannelGroupType;
import org.eclipse.smarthome.core.thing.type.ChannelGroupTypeRegistry;
import org.eclipse.smarthome.core.thing.type.ChannelType; import org.eclipse.smarthome.core.thing.type.ChannelType;
import org.eclipse.smarthome.core.thing.type.ChannelTypeRegistry; import org.eclipse.smarthome.core.thing.type.ChannelTypeRegistry;
import org.eclipse.smarthome.core.thing.type.ThingType; import org.eclipse.smarthome.core.thing.type.ThingType;
@ -40,11 +43,12 @@ public class ThingTypesTest extends JavaOSGiTest {
private LoadedTestBundle loadedTestBundle() throws Exception { private LoadedTestBundle loadedTestBundle() throws Exception {
return new LoadedTestBundle("ThingTypesTest.bundle", bundleContext, this::getService, return new LoadedTestBundle("ThingTypesTest.bundle", bundleContext, this::getService,
new StuffAddition().thingTypes(3)); new StuffAddition().thingTypes(4));
} }
private ThingTypeProvider thingTypeProvider; private ThingTypeProvider thingTypeProvider;
private ChannelTypeRegistry channelTypeRegistry; private ChannelTypeRegistry channelTypeRegistry;
private ChannelGroupTypeRegistry channelGroupTypeRegistry;
@Before @Before
public void setUp() { public void setUp() {
@ -53,6 +57,9 @@ public class ThingTypesTest extends JavaOSGiTest {
channelTypeRegistry = getService(ChannelTypeRegistry.class); channelTypeRegistry = getService(ChannelTypeRegistry.class);
assertThat(channelTypeRegistry, is(notNullValue())); assertThat(channelTypeRegistry, is(notNullValue()));
channelGroupTypeRegistry = getService(ChannelGroupTypeRegistry.class);
assertThat(channelGroupTypeRegistry, is(notNullValue()));
} }
@Test @Test
@ -60,6 +67,7 @@ public class ThingTypesTest extends JavaOSGiTest {
try (final AutoCloseable unused = loadedTestBundle()) { try (final AutoCloseable unused = loadedTestBundle()) {
Collection<ThingType> thingTypes = thingTypeProvider.getThingTypes(null); Collection<ThingType> thingTypes = thingTypeProvider.getThingTypes(null);
// HUE Bridge
BridgeType bridgeType = (BridgeType) thingTypes.stream().filter(it -> it.toString().equals("hue:bridge")) BridgeType bridgeType = (BridgeType) thingTypes.stream().filter(it -> it.toString().equals("hue:bridge"))
.findFirst().get(); .findFirst().get();
assertThat(bridgeType, is(notNullValue())); assertThat(bridgeType, is(notNullValue()));
@ -71,6 +79,7 @@ public class ThingTypesTest extends JavaOSGiTest {
assertThat(bridgeType.getProperties().get("vendor"), is("Philips")); assertThat(bridgeType.getProperties().get("vendor"), is("Philips"));
assertThat(bridgeType.getRepresentationProperty(), is("serialNumber")); assertThat(bridgeType.getRepresentationProperty(), is("serialNumber"));
// HUE Lamp
ThingType thingType = thingTypes.stream().filter(it -> it.toString().equals("hue:lamp")).findFirst().get(); ThingType thingType = thingTypes.stream().filter(it -> it.toString().equals("hue:lamp")).findFirst().get();
assertThat(thingType, is(notNullValue())); assertThat(thingType, is(notNullValue()));
@ -163,11 +172,42 @@ public class ThingTypesTest extends JavaOSGiTest {
assertThat(state.getOptions().get(0).getValue(), is(equalTo("SOUND"))); assertThat(state.getOptions().get(0).getValue(), is(equalTo("SOUND")));
assertThat(state.getOptions().get(0).getLabel(), is(equalTo("My great sound."))); assertThat(state.getOptions().get(0).getLabel(), is(equalTo("My great sound.")));
// HUE Lamp with group
thingType = thingTypes.stream().filter(it -> it.toString().equals("hue:lamp-with-group")).findFirst().get(); thingType = thingTypes.stream().filter(it -> it.toString().equals("hue:lamp-with-group")).findFirst().get();
assertThat(thingType, is(notNullValue()));
assertThat(thingType.getProperties().size(), is(0)); assertThat(thingType.getProperties().size(), is(0));
assertThat(thingType.getCategory(), is(nullValue())); assertThat(thingType.getCategory(), is(nullValue()));
assertThat(thingType.isListed(), is(true)); assertThat(thingType.isListed(), is(true));
assertThat(thingType.getExtensibleChannelTypeIds(), containsInAnyOrder("brightness", "alarm")); assertThat(thingType.getExtensibleChannelTypeIds(), containsInAnyOrder("brightness", "alarm"));
List<ChannelGroupDefinition> channelGroupDefinitions = thingType.getChannelGroupDefinitions();
assertThat(channelGroupDefinitions.size(), is(2));
// Channel Group
ChannelGroupDefinition channelGroupDefinition = channelGroupDefinitions.stream()
.filter(it -> it.getId().equals("lampgroup")).findFirst().get();
assertThat(channelGroupDefinition, is(notNullValue()));
ChannelGroupType channelGroupType = channelGroupTypeRegistry
.getChannelGroupType(channelGroupDefinition.getTypeUID());
assertThat(channelGroupType, is(notNullValue()));
channelDefinitions = channelGroupType.getChannelDefinitions();
assertThat(channelDefinitions.size(), is(3));
// Channel Group without channels
channelGroupDefinition = channelGroupDefinitions.stream()
.filter(it -> it.getId().equals("lampgroup-without-channels")).findFirst().get();
assertThat(channelGroupDefinition, is(notNullValue()));
channelGroupType = channelGroupTypeRegistry.getChannelGroupType(channelGroupDefinition.getTypeUID());
assertThat(channelGroupType, is(notNullValue()));
channelDefinitions = channelGroupType.getChannelDefinitions();
assertThat(channelDefinitions.size(), is(0));
// HUE Lamp without channels
thingType = thingTypes.stream().filter(it -> it.toString().equals("hue:lamp-without-channels")).findFirst()
.get();
assertThat(thingType, is(notNullValue()));
channelDefinitions = thingType.getChannelDefinitions();
assertThat(channelDefinitions.size(), is(0));
} }
} }

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="hue" <thing:thing-descriptions bindingId="hue" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:thing="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0" xmlns:thing="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0"
xsi:schemaLocation="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0 org.eclipse.smarthome.thing-description.xsd"> xsi:schemaLocation="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0 org.eclipse.smarthome.thing-description.xsd">
@ -63,7 +62,7 @@
<representation-property>uniqueId</representation-property> <representation-property>uniqueId</representation-property>
</thing-type> </thing-type>
<!-- HUE Lamp with Group --> <!-- HUE Lamp with group -->
<thing-type id="lamp-with-group" extensible="brightness, alarm"> <thing-type id="lamp-with-group" extensible="brightness, alarm">
<label>HUE Lamp</label> <label>HUE Lamp</label>
@ -71,17 +70,34 @@
<channel-groups> <channel-groups>
<channel-group id="lampgroup" typeId="lampgroup" /> <channel-group id="lampgroup" typeId="lampgroup" />
<channel-group id="lampgroup-without-channels" typeId="lampgroup-without-channels" />
</channel-groups> </channel-groups>
</thing-type> </thing-type>
<!-- HUE Lamp without channels -->
<thing-type id="lamp-without-channels" listed="false" extensible="alarm,brightness">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge" />
</supported-bridge-type-refs>
<label>HUE Lamp</label>
<description>My own great HUE Lamp without channels.</description>
<category>Lightbulb</category>
<properties>
<property name="key1">value1</property>
<property name="key2">value2</property>
</properties>
<representation-property>uniqueId</representation-property>
</thing-type>
<!-- HUE Lamp Color Channel --> <!-- HUE Lamp Color Channel -->
<channel-type id="color"> <channel-type id="color">
<item-type>ColorItem</item-type> <item-type>ColorItem</item-type>
<label>HUE Lamp Color</label> <label>HUE Lamp Color</label>
<description>The color channel allows to control the color of the hue <description>The color channel allows to control the color of the hue lamp. It is also possible to dim values and
lamp. It is also possible to dim values and switch the lamp on and switch the lamp on and off.
off.
</description> </description>
<tags> <tags>
<tag>Hue</tag> <tag>Hue</tag>
@ -116,8 +132,7 @@
<tag>Hue</tag> <tag>Hue</tag>
<tag>AlarmSystem</tag> <tag>AlarmSystem</tag>
</tags> </tags>
<state min="0" max="100.0" step="10.0" pattern="%d Peek" <state min="0" max="100.0" step="10.0" pattern="%d Peek" readOnly="true">
readOnly="true">
<options> <options>
<option value="SOUND">My great sound.</option> <option value="SOUND">My great sound.</option>
<option value="LIGHT" /> <option value="LIGHT" />
@ -136,4 +151,10 @@
</channels> </channels>
</channel-group-type> </channel-group-type>
<!-- Channel Group without channels -->
<channel-group-type id="lampgroup-without-channels" advanced="true">
<label>Alarm System</label>
<description>The alarm system without channels.</description>
</channel-group-type>
</thing:thing-descriptions> </thing:thing-descriptions>