Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Commit

Permalink
converting state types into accepted type before sending item state e…
Browse files Browse the repository at this point in the history
…vents

fixes #2253
Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
  • Loading branch information
Simon Kaufmann committed Oct 31, 2016
1 parent 8d49d70 commit 057f76d
Show file tree
Hide file tree
Showing 27 changed files with 440 additions and 169 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
*/
package org.eclipse.smarthome.core.library.types;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.junit.Assert.*;

import java.text.DecimalFormatSymbols;

import org.eclipse.smarthome.core.types.UnDefType;
import org.junit.Test;

/**
Expand Down Expand Up @@ -83,4 +83,26 @@ public void testFloatFormat() {
dt = new DecimalType("11.0");
assertEquals("11" + sep + "0", dt.format("%.1f")); // "11.0"
}

@Test
public void testConversionToOnOffType() {
assertEquals(OnOffType.ON, new DecimalType("100.0").as(OnOffType.class));
assertEquals(OnOffType.ON, new DecimalType("1.0").as(OnOffType.class));
assertEquals(OnOffType.OFF, new DecimalType("0.0").as(OnOffType.class));
}

@Test
public void testConversionToOpenCloseType() {
assertEquals(OpenClosedType.OPEN, new DecimalType("1.0").as(OpenClosedType.class));
assertEquals(OpenClosedType.CLOSED, new DecimalType("0.0").as(OpenClosedType.class));
assertEquals(UnDefType.UNDEF, new DecimalType("0.5").as(OpenClosedType.class));
}

@Test
public void testConversionToUpDownType() {
assertEquals(UpDownType.UP, new DecimalType("0.0").as(UpDownType.class));
assertEquals(UpDownType.DOWN, new DecimalType("1.0").as(UpDownType.class));
assertEquals(UnDefType.UNDEF, new DecimalType("0.5").as(OpenClosedType.class));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,26 @@ private void compareRgbToHsbValues(String hsbValues, int red, int green, int blu
assertEquals(hsb.getSaturation(), hsbRgb.getSaturation());
assertEquals(hsb.getBrightness(), hsbRgb.getBrightness());
}

@Test
public void testConversionToOnOffType() {
assertEquals(OnOffType.ON, new HSBType("100,100,100").as(OnOffType.class));
assertEquals(OnOffType.ON, new HSBType("100,100,1").as(OnOffType.class));
assertEquals(OnOffType.OFF, new HSBType("100,100,0").as(OnOffType.class));
}

@Test
public void testConversionToDecimalType() {
assertEquals(new DecimalType("1.0"), new HSBType("100,100,100").as(DecimalType.class));
assertEquals(new DecimalType("0.01"), new HSBType("100,100,1").as(DecimalType.class));
assertEquals(DecimalType.ZERO, new HSBType("100,100,0").as(DecimalType.class));
}

@Test
public void testConversionToPercentType() {
assertEquals(PercentType.HUNDRED, new HSBType("100,100,100").as(PercentType.class));
assertEquals(new PercentType("1"), new HSBType("100,100,1").as(PercentType.class));
assertEquals(PercentType.ZERO, new HSBType("100,100,0").as(PercentType.class));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2014-2016 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.core.library.types;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

/**
* @author Simon Kaufmann - Initial contribution and API
*/
public class OnOffTypeTest {

@Test
public void testConversionToPercentType() {
assertEquals(PercentType.HUNDRED, OnOffType.ON.as(PercentType.class));
assertEquals(PercentType.ZERO, OnOffType.OFF.as(PercentType.class));
}

@Test
public void testConversionToDecimalType() {
assertEquals(new DecimalType("1.0"), OnOffType.ON.as(DecimalType.class));
assertEquals(DecimalType.ZERO, OnOffType.OFF.as(DecimalType.class));
}

@Test
public void testConversionToHSBType() {
assertEquals(HSBType.WHITE, OnOffType.ON.as(HSBType.class));
assertEquals(HSBType.BLACK, OnOffType.OFF.as(HSBType.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright (c) 2014-2016 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.core.library.types;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

/**
* @author Simon Kaufmann - Initial contribution and API
*/
public class OpenClosedTypeTest {

@Test
public void testConversionToPercentType() {
assertEquals(PercentType.ZERO, OpenClosedType.CLOSED.as(PercentType.class));
assertEquals(PercentType.HUNDRED, OpenClosedType.OPEN.as(PercentType.class));
}

@Test
public void testConversionToDecimalType() {
assertEquals(DecimalType.ZERO, OpenClosedType.CLOSED.as(DecimalType.class));
assertEquals(new DecimalType(1), OpenClosedType.OPEN.as(DecimalType.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import static org.junit.Assert.assertEquals;

import org.eclipse.smarthome.core.types.UnDefType;
import org.junit.Test;

/**
Expand Down Expand Up @@ -49,4 +50,33 @@ public void testEquals() {
assertEquals(true, pt3.equals(pt4));
assertEquals(false, pt3.equals(pt1));
}

@Test
public void testConversionToOnOffType() {
assertEquals(OnOffType.ON, new PercentType("100.0").as(OnOffType.class));
assertEquals(OnOffType.ON, new PercentType("1.0").as(OnOffType.class));
assertEquals(OnOffType.OFF, new PercentType("0.0").as(OnOffType.class));
}

@Test
public void testConversionToDecimalType() {
assertEquals(new DecimalType("1.0"), new PercentType("100.0").as(DecimalType.class));
assertEquals(new DecimalType("0.01"), new PercentType("1.0").as(DecimalType.class));
assertEquals(DecimalType.ZERO, new PercentType("0.0").as(DecimalType.class));
}

@Test
public void testConversionToOpenCloseType() {
assertEquals(OpenClosedType.OPEN, new PercentType("100.0").as(OpenClosedType.class));
assertEquals(OpenClosedType.CLOSED, new PercentType("0.0").as(OpenClosedType.class));
assertEquals(UnDefType.UNDEF, new PercentType("50.0").as(OpenClosedType.class));
}

@Test
public void testConversionToUpDownType() {
assertEquals(UpDownType.UP, new PercentType("0.0").as(UpDownType.class));
assertEquals(UpDownType.DOWN, new PercentType("100.0").as(UpDownType.class));
assertEquals(UnDefType.UNDEF, new PercentType("50.0").as(OpenClosedType.class));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2014-2016 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.core.library.types;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

/**
* @author Simon Kaufmann - Initial contribution and API
*/
public class UpDownTypeTest {

@Test
public void testConversionToPercentType() {
assertEquals(PercentType.ZERO, UpDownType.UP.as(PercentType.class));
assertEquals(PercentType.HUNDRED, UpDownType.DOWN.as(PercentType.class));
}

@Test
public void testConversionToDecimalType() {
assertEquals(DecimalType.ZERO, UpDownType.UP.as(DecimalType.class));
assertEquals(new DecimalType(1), UpDownType.DOWN.as(DecimalType.class));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.eclipse.smarthome.config.core.BundleProcessor;
import org.eclipse.smarthome.config.core.BundleProcessor.BundleProcessorListener;
import org.eclipse.smarthome.config.core.ConfigDescription;
Expand All @@ -32,6 +33,8 @@
import org.eclipse.smarthome.core.common.SafeMethodCaller;
import org.eclipse.smarthome.core.common.ThreadPoolManager;
import org.eclipse.smarthome.core.events.EventPublisher;
import org.eclipse.smarthome.core.items.Item;
import org.eclipse.smarthome.core.items.ItemUtil;
import org.eclipse.smarthome.core.items.events.AbstractItemEventSubscriber;
import org.eclipse.smarthome.core.items.events.ItemCommandEvent;
import org.eclipse.smarthome.core.items.events.ItemEventFactory;
Expand Down Expand Up @@ -67,6 +70,7 @@
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
Expand All @@ -84,7 +88,7 @@
* @author Michael Grammling - Added dynamic configuration update
* @author Stefan Bußweiler - Added new thing status handling, migration to new event mechanism,
* refactorings thing life cycle
* @author Simon Kaufmann - Added remove handling
* @author Simon Kaufmann - Added remove handling, type conversion
* @author Kai Kreuzer - Removed usage of itemRegistry and thingLinkRegistry, fixed vetoing mechanism
* @author Andre Fuechsel - Added the {@link ThingTypeMigrationService} 
*/
Expand Down Expand Up @@ -164,15 +168,17 @@ private ThingUID getThingUID(ServiceReference<ThingHandler> reference) {

@Override
public void stateUpdated(ChannelUID channelUID, State state) {
Set<String> items = itemChannelLinkRegistry.getLinkedItems(channelUID);
for (String item : items) {
eventPublisher.post(ItemEventFactory.createStateEvent(item, state, channelUID.toString()));
Set<Item> items = itemChannelLinkRegistry.getLinkedItems(channelUID);
for (Item item : items) {
State acceptedState = ItemUtil.convertToAcceptedState(state, item);
eventPublisher
.post(ItemEventFactory.createStateEvent(item.getName(), acceptedState, channelUID.toString()));
}
}

@Override
public void postCommand(ChannelUID channelUID, Command command) {
Set<String> items = itemChannelLinkRegistry.getLinkedItems(channelUID);
Set<String> items = itemChannelLinkRegistry.getLinkedItemNames(channelUID);
for (String item : items) {
eventPublisher.post(ItemEventFactory.createCommandEvent(item, command, channelUID.toString()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public boolean isLinked(String itemName, UID uid) {
* @param uid UID
* @return a non-null collection of item names that are linked to the given UID.
*/
public Set<String> getLinkedItems(UID uid) {
public Set<String> getLinkedItemNames(UID uid) {
Set<String> linkedItems = new LinkedHashSet<>();
for (AbstractLink link : getAll()) {
if (link.getUID().equals(uid)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.LinkedHashSet;
import java.util.Set;

import org.eclipse.smarthome.core.items.Item;
import org.eclipse.smarthome.core.items.ItemRegistry;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.Thing;
Expand Down Expand Up @@ -66,7 +67,7 @@ public ItemChannelLink update(ItemChannelLink element) {
}

@Override
public Set<String> getLinkedItems(UID uid) {
public Set<String> getLinkedItemNames(UID uid) {
final Set<String> linkedItems = new LinkedHashSet<>();
for (final AbstractLink link : getAll()) {
final String itemName = link.getItemName();
Expand All @@ -77,6 +78,18 @@ public Set<String> getLinkedItems(UID uid) {
return linkedItems;
}

public Set<Item> getLinkedItems(UID uid) {
final Set<Item> linkedItems = new LinkedHashSet<>();
for (final AbstractLink link : getAll()) {
final String itemName = link.getItemName();
Item item = itemRegistry.get(itemName);
if (link.getUID().equals(uid) && item != null) {
linkedItems.add(item);
}
}
return linkedItems;
}

/**
* Returns a set of bound things for the given item name.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ protected void receiveTypedEvent(ThingStatusInfoChangedEvent event) {
Thing thing = thingRegistry.get(event.getThingUID());
if (thing != null) {
for (Channel channel : thing.getChannels()) {
if (itemChannelLinkRegistry.getLinkedItems(channel.getUID()).size() > 0) {
if (itemChannelLinkRegistry.getLinkedItemNames(channel.getUID()).size() > 0) {
informHandlerAboutLinkedChannel(thing, channel);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.eclipse.smarthome.core.events.EventPublisher;
import org.eclipse.smarthome.core.items.events.ItemEventFactory;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.Convertible;
import org.eclipse.smarthome.core.types.RefreshType;
import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.core.types.StateDescription;
Expand Down Expand Up @@ -90,8 +91,8 @@ public State getState() {
*/
@Override
public State getStateAs(Class<? extends State> typeClass) {
if (typeClass != null && typeClass.isInstance(state)) {
return state;
if (state instanceof Convertible) {
return ((Convertible) state).as(typeClass);
} else {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ public interface Item {
* the accepted data types would be in this case {@link PercentType}, {@link OnOffType} and {@link UnDefType}
* </p>
*
* <p>
* The order of data types denotes the order of preference. So in case a state needs to be converted
* in order to be accepted, it will be attempted to convert it to a type from top to bottom. Therefore
* the type with the least information loss should be on top of the list - in the example above the
* {@link PercentType} carries more information than the {@link OnOffType}, hence it is listed first.
* </p>
* @return a list of data types that can be used to update the item state
*/
public List<Class<? extends State>> getAcceptedDataTypes();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@
*/
package org.eclipse.smarthome.core.items;

import org.eclipse.smarthome.core.types.Convertible;
import org.eclipse.smarthome.core.types.State;
import org.slf4j.LoggerFactory;

/**
* The {@link ItemUtil} class contains utility methods for {@link Item} objects.
* <p>
* This class cannot be instantiated, it only contains static methods.
*
* @author Michael Grammling - Initial contribution and API
* @author Simon Kaufmann - added type conversion
*/
public class ItemUtil {

Expand Down Expand Up @@ -71,4 +76,23 @@ public static void assertValidItemName(String itemName) throws IllegalArgumentEx
}
}

public static State convertToAcceptedState(final State state, final Item item) {
if (item != null && !isAccepted(item, state) && state instanceof Convertible) {
for (Class<? extends State> acceptedType : item.getAcceptedDataTypes()) {
State convertedState = ((Convertible) state).as(acceptedType);
if (convertedState != null) {
LoggerFactory.getLogger(ItemUtil.class).debug("Converting {} '{}' to {} '{}' for item '{}'",
state.getClass().getSimpleName(), state.toString(),
convertedState.getClass().getSimpleName(), convertedState.toString(), item.getName());
return convertedState;
}
}
}
return state;
}

private static boolean isAccepted(Item item, State state) {
return item.getAcceptedDataTypes().contains(state.getClass());
}

}
Loading

0 comments on commit 057f76d

Please sign in to comment.