Search in sources :

Example 26 with StateDescription

use of org.eclipse.smarthome.core.types.StateDescription in project smarthome by eclipse.

the class ItemUIRegistryImpl method getLabel.

@Override
public String getLabel(Widget w) {
    String label = getLabelFromWidget(w);
    String itemName = w.getItem();
    if (StringUtils.isBlank(itemName)) {
        return transform(label, null);
    }
    String labelMappedOption = null;
    State state = null;
    StateDescription stateDescription = null;
    String formatPattern = getFormatPattern(label);
    // (i.e. it contains at least a %)
    try {
        final Item item = getItem(itemName);
        // There is a known issue in the implementation of the method getStateDescription() of class Item
        // in the following case:
        // - the item provider returns as expected a state description without pattern but with for
        // example a min value because a min value is set in the item definition but no label with
        // pattern is set.
        // - the channel state description provider returns as expected a state description with a pattern
        // In this case, the result is no display of value by UIs because no pattern is set in the
        // returned StateDescription. What is expected is the display of a value using the pattern
        // provided by the channel state description provider.
        stateDescription = item.getStateDescription();
        if (formatPattern == null && stateDescription != null && stateDescription.getPattern() != null) {
            label = label + " [" + stateDescription.getPattern() + "]";
        }
        String updatedPattern = getFormatPattern(label);
        if (updatedPattern != null) {
            formatPattern = updatedPattern;
            // a number is requested, PercentType must not be converted to DecimalType:
            if (formatPattern.contains("%d") && !(item.getState() instanceof PercentType)) {
                state = item.getStateAs(DecimalType.class);
            } else {
                state = item.getState();
            }
        }
    } catch (ItemNotFoundException e) {
        logger.error("Cannot retrieve item for widget {}", w.eClass().getInstanceTypeName());
    }
    if (formatPattern != null) {
        if (formatPattern.isEmpty()) {
            label = label.substring(0, label.indexOf("[")).trim();
        } else {
            if (state == null || state instanceof UnDefType) {
                formatPattern = formatUndefined(formatPattern);
            } else if (state instanceof Type) {
                // if the channel contains options, we build a label with the mapped option value
                if (stateDescription != null && stateDescription.getOptions() != null) {
                    for (StateOption option : stateDescription.getOptions()) {
                        if (option.getValue().equals(state.toString()) && option.getLabel() != null) {
                            State stateOption = new StringType(option.getLabel());
                            try {
                                String formatPatternOption = stateOption.format(formatPattern);
                                labelMappedOption = label.trim();
                                labelMappedOption = labelMappedOption.substring(0, labelMappedOption.indexOf("[") + 1) + formatPatternOption + "]";
                            } catch (IllegalArgumentException e) {
                                logger.debug("Mapping option value '{}' for item {} using format '{}' failed ({}); mapping is ignored", stateOption, itemName, formatPattern, e.getMessage());
                                labelMappedOption = null;
                            }
                            break;
                        }
                    }
                }
                if (state instanceof QuantityType) {
                    QuantityType<?> quantityState = (QuantityType<?>) state;
                    // sanity convert current state to the item state description unit in case it was updated in the
                    // meantime. The item state is still in the "original" unit while the state description will
                    // display the new unit:
                    Unit<?> patternUnit = UnitUtils.parseUnit(formatPattern);
                    if (patternUnit != null && !quantityState.getUnit().equals(patternUnit)) {
                        quantityState = quantityState.toUnit(patternUnit);
                    }
                    // The widget may define its own unit in the widget label. Convert to this unit:
                    quantityState = convertStateToWidgetUnit(quantityState, w);
                    state = quantityState;
                }
                // This also handles IllegalFormatConversionException, which is a subclass of IllegalArgument.
                try {
                    formatPattern = fillFormatPattern(formatPattern, state);
                } catch (IllegalArgumentException e) {
                    logger.warn("Exception while formatting value '{}' of item {} with format '{}': {}", state, itemName, formatPattern, e.getMessage());
                    formatPattern = new String("Err");
                }
            }
            label = label.trim();
            label = label.substring(0, label.indexOf("[") + 1) + formatPattern + "]";
        }
    }
    return transform(label, labelMappedOption);
}
Also used : StringType(org.eclipse.smarthome.core.library.types.StringType) UnDefType(org.eclipse.smarthome.core.types.UnDefType) PercentType(org.eclipse.smarthome.core.library.types.PercentType) Unit(javax.measure.Unit) ChronoUnit(java.time.temporal.ChronoUnit) StateOption(org.eclipse.smarthome.core.types.StateOption) NumberItem(org.eclipse.smarthome.core.library.items.NumberItem) CallItem(org.eclipse.smarthome.core.library.items.CallItem) SwitchItem(org.eclipse.smarthome.core.library.items.SwitchItem) DateTimeItem(org.eclipse.smarthome.core.library.items.DateTimeItem) RollershutterItem(org.eclipse.smarthome.core.library.items.RollershutterItem) GroupItem(org.eclipse.smarthome.core.items.GroupItem) ColorItem(org.eclipse.smarthome.core.library.items.ColorItem) LocationItem(org.eclipse.smarthome.core.library.items.LocationItem) ContactItem(org.eclipse.smarthome.core.library.items.ContactItem) GenericItem(org.eclipse.smarthome.core.items.GenericItem) Item(org.eclipse.smarthome.core.items.Item) StringItem(org.eclipse.smarthome.core.library.items.StringItem) PlayerItem(org.eclipse.smarthome.core.library.items.PlayerItem) ImageItem(org.eclipse.smarthome.core.library.items.ImageItem) DimmerItem(org.eclipse.smarthome.core.library.items.DimmerItem) OnOffType(org.eclipse.smarthome.core.library.types.OnOffType) UnDefType(org.eclipse.smarthome.core.types.UnDefType) PlayPauseType(org.eclipse.smarthome.core.library.types.PlayPauseType) StringType(org.eclipse.smarthome.core.library.types.StringType) NextPreviousType(org.eclipse.smarthome.core.library.types.NextPreviousType) PercentType(org.eclipse.smarthome.core.library.types.PercentType) Type(org.eclipse.smarthome.core.types.Type) QuantityType(org.eclipse.smarthome.core.library.types.QuantityType) DateTimeType(org.eclipse.smarthome.core.library.types.DateTimeType) DecimalType(org.eclipse.smarthome.core.library.types.DecimalType) QuantityType(org.eclipse.smarthome.core.library.types.QuantityType) State(org.eclipse.smarthome.core.types.State) DecimalType(org.eclipse.smarthome.core.library.types.DecimalType) StateDescription(org.eclipse.smarthome.core.types.StateDescription) ItemNotFoundException(org.eclipse.smarthome.core.items.ItemNotFoundException)

Example 27 with StateDescription

use of org.eclipse.smarthome.core.types.StateDescription in project smarthome by eclipse.

the class ChannelStateDescriptionProvider method getStateDescription.

@Override
public StateDescription getStateDescription(String itemName, Locale locale) {
    Set<ChannelUID> boundChannels = itemChannelLinkRegistry.getBoundChannels(itemName);
    if (!boundChannels.isEmpty()) {
        ChannelUID channelUID = boundChannels.iterator().next();
        Channel channel = thingRegistry.getChannel(channelUID);
        if (channel != null) {
            StateDescription stateDescription = null;
            ChannelType channelType = thingTypeRegistry.getChannelType(channel, locale);
            if (channelType != null) {
                stateDescription = channelType.getState();
                if ((channelType.getItemType() != null) && ((stateDescription == null) || (stateDescription.getPattern() == null))) {
                    String pattern = null;
                    if (channelType.getItemType().equalsIgnoreCase(CoreItemFactory.STRING)) {
                        pattern = "%s";
                    } else if (channelType.getItemType().startsWith(CoreItemFactory.NUMBER)) {
                        pattern = "%.0f";
                    }
                    if (pattern != null) {
                        logger.trace("Provide a default pattern {} for item {}", pattern, itemName);
                        if (stateDescription == null) {
                            stateDescription = new StateDescription(null, null, null, pattern, false, null);
                        } else {
                            stateDescription = new StateDescription(stateDescription.getMinimum(), stateDescription.getMaximum(), stateDescription.getStep(), pattern, stateDescription.isReadOnly(), stateDescription.getOptions());
                        }
                    }
                }
            }
            StateDescription dynamicStateDescription = getDynamicStateDescription(channel, stateDescription, locale);
            if (dynamicStateDescription != null) {
                return dynamicStateDescription;
            }
            return stateDescription;
        }
    }
    return null;
}
Also used : ChannelUID(org.eclipse.smarthome.core.thing.ChannelUID) Channel(org.eclipse.smarthome.core.thing.Channel) ChannelType(org.eclipse.smarthome.core.thing.type.ChannelType) StateDescription(org.eclipse.smarthome.core.types.StateDescription)

Example 28 with StateDescription

use of org.eclipse.smarthome.core.types.StateDescription in project smarthome by eclipse.

the class StateDescriptionConverter method unmarshal.

@Override
public final Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    Map<String, String> attributes = this.attributeMapValidator.readValidatedAttributes(reader);
    BigDecimal minimum = toBigDecimal(attributes, "min", null);
    BigDecimal maximum = toBigDecimal(attributes, "max", null);
    BigDecimal step = toBigDecimal(attributes, "step", null);
    String pattern = attributes.get("pattern");
    boolean readOnly = toBoolean(attributes, "readOnly", false);
    List<StateOption> channelOptions = null;
    NodeList nodes = (NodeList) context.convertAnother(context, NodeList.class);
    NodeIterator nodeIterator = new NodeIterator(nodes.getList());
    NodeList optionNodes = (NodeList) nodeIterator.next();
    if (optionNodes != null) {
        channelOptions = toListOfChannelState(optionNodes);
    }
    nodeIterator.assertEndOfType();
    StateDescription stateDescription = new StateDescription(minimum, maximum, step, pattern, readOnly, channelOptions);
    return stateDescription;
}
Also used : NodeIterator(org.eclipse.smarthome.config.xml.util.NodeIterator) NodeList(org.eclipse.smarthome.config.xml.util.NodeList) BigDecimal(java.math.BigDecimal) StateOption(org.eclipse.smarthome.core.types.StateOption) StateDescription(org.eclipse.smarthome.core.types.StateDescription)

Example 29 with StateDescription

use of org.eclipse.smarthome.core.types.StateDescription in project smarthome by eclipse.

the class ChannelTypeConverter method unmarshalType.

@Override
protected ChannelTypeXmlResult unmarshalType(HierarchicalStreamReader reader, UnmarshallingContext context, Map<String, String> attributes, NodeIterator nodeIterator) throws ConversionException {
    boolean advanced = readBoolean(attributes, "advanced", false);
    boolean system = readBoolean(attributes, "system", false);
    String uid = system ? XmlHelper.getSystemUID(super.getID(attributes)) : super.getUID(attributes, context);
    ChannelTypeUID channelTypeUID = new ChannelTypeUID(uid);
    String itemType = readItemType(nodeIterator);
    String kind = readKind(nodeIterator);
    String label = super.readLabel(nodeIterator);
    String description = super.readDescription(nodeIterator);
    String category = readCategory(nodeIterator);
    Set<String> tags = readTags(nodeIterator);
    StateDescription stateDescription = readStateDescription(nodeIterator);
    EventDescription eventDescription = readEventDescription(nodeIterator);
    Object[] configDescriptionObjects = super.getConfigDescriptionObjects(nodeIterator);
    if (kind == null) {
        // Default for kind is 'state'
        kind = "state";
    }
    ChannelType 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);
    return channelTypeXmlResult;
}
Also used : ChannelTypeUID(org.eclipse.smarthome.core.thing.type.ChannelTypeUID) EventDescription(org.eclipse.smarthome.core.types.EventDescription) ChannelType(org.eclipse.smarthome.core.thing.type.ChannelType) StateDescription(org.eclipse.smarthome.core.types.StateDescription)

Example 30 with StateDescription

use of org.eclipse.smarthome.core.types.StateDescription in project smarthome by eclipse.

the class EnrichedItemDTOMapperWithTransformOSGiTest method shouldConsiderTraformationWhenPresent.

@Test
public void shouldConsiderTraformationWhenPresent() {
    NumberItem item1 = new NumberItem("Item1");
    item1.setState(new DecimalType("12.34"));
    item1.setStateDescriptionService(stateDescriptionService);
    EnrichedItemDTO enrichedDTO = EnrichedItemDTOMapper.map(item1, false, null, null, null);
    assertThat(enrichedDTO, is(notNullValue()));
    assertThat(enrichedDTO.name, is("Item1"));
    assertThat(enrichedDTO.state, is("12.34"));
    StateDescription sd = enrichedDTO.stateDescription;
    assertThat(sd.getMinimum(), is(BigDecimal.valueOf(0)));
    assertThat(sd.getMaximum(), is(BigDecimal.valueOf(100)));
    assertThat(sd.getStep(), is(BigDecimal.valueOf(10)));
    assertThat(sd.getPattern(), is("%d °C"));
    assertThat(sd.getOptions().get(0).getValue(), is("SOUND"));
    assertThat(sd.getOptions().get(0).getLabel(), is("My great sound."));
}
Also used : NumberItem(org.eclipse.smarthome.core.library.items.NumberItem) EnrichedItemDTO(org.eclipse.smarthome.io.rest.core.item.EnrichedItemDTO) DecimalType(org.eclipse.smarthome.core.library.types.DecimalType) StateDescription(org.eclipse.smarthome.core.types.StateDescription) JavaOSGiTest(org.eclipse.smarthome.test.java.JavaOSGiTest) Test(org.junit.Test)

Aggregations

StateDescription (org.eclipse.smarthome.core.types.StateDescription)31 Test (org.junit.Test)15 StateOption (org.eclipse.smarthome.core.types.StateOption)13 NumberItem (org.eclipse.smarthome.core.library.items.NumberItem)7 ArrayList (java.util.ArrayList)6 StringType (org.eclipse.smarthome.core.library.types.StringType)6 ChannelType (org.eclipse.smarthome.core.thing.type.ChannelType)6 BigDecimal (java.math.BigDecimal)4 Item (org.eclipse.smarthome.core.items.Item)4 ChannelTypeUID (org.eclipse.smarthome.core.thing.type.ChannelTypeUID)4 StateDescriptionProvider (org.eclipse.smarthome.core.types.StateDescriptionProvider)4 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)4 GroupItem (org.eclipse.smarthome.core.items.GroupItem)3 ColorItem (org.eclipse.smarthome.core.library.items.ColorItem)3 DimmerItem (org.eclipse.smarthome.core.library.items.DimmerItem)3 StringItem (org.eclipse.smarthome.core.library.items.StringItem)3 SwitchItem (org.eclipse.smarthome.core.library.items.SwitchItem)3 JavaOSGiTest (org.eclipse.smarthome.test.java.JavaOSGiTest)3 Before (org.junit.Before)3 Collection (java.util.Collection)2