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);
}
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;
}
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;
}
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;
}
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."));
}
Aggregations