use of org.eclipse.smarthome.core.library.types.QuantityType in project smarthome by eclipse.
the class GroupItemTest method assertThatNumberGroupItemWithDimensionCalculatesCorrectState.
@SuppressWarnings("null")
@Test
public void assertThatNumberGroupItemWithDimensionCalculatesCorrectState() {
NumberItem baseItem = createNumberItem("baseItem", Temperature.class, UnDefType.NULL);
GroupFunctionDTO gfDTO = new GroupFunctionDTO();
gfDTO.name = "sum";
GroupFunction function = groupFunctionHelper.createGroupFunction(gfDTO, Collections.emptyList(), Temperature.class);
GroupItem groupItem = new GroupItem("number", baseItem, function);
groupItem.setUnitProvider(unitProvider);
NumberItem celsius = createNumberItem("C", Temperature.class, new QuantityType<Temperature>("23 °C"));
groupItem.addMember(celsius);
NumberItem fahrenheit = createNumberItem("F", Temperature.class, new QuantityType<Temperature>("23 °F"));
groupItem.addMember(fahrenheit);
NumberItem kelvin = createNumberItem("K", Temperature.class, new QuantityType<Temperature>("23 K"));
groupItem.addMember(kelvin);
QuantityType<?> state = (QuantityType<?>) groupItem.getStateAs(QuantityType.class);
assertThat(state.getUnit(), is(Units.CELSIUS));
assertThat(state.doubleValue(), is(-232.15d));
celsius.setState(new QuantityType<Temperature>("265 °C"));
state = (QuantityType<?>) groupItem.getStateAs(QuantityType.class);
assertThat(state.getUnit(), is(Units.CELSIUS));
assertThat(state.doubleValue(), is(9.85d));
}
use of org.eclipse.smarthome.core.library.types.QuantityType in project smarthome by eclipse.
the class ItemUIRegistryImpl method convertState.
/**
* Converts an item state to the type the widget supports (if possible)
*
* @param w Widget in sitemap that shows the state
* @param i item
* @return the converted state or the original if conversion was not possible
*/
private State convertState(Widget w, Item i) {
State returnState = null;
State itemState = i.getState();
if (itemState instanceof QuantityType) {
itemState = convertStateToWidgetUnit((QuantityType<?>) itemState, w);
}
if (w instanceof Switch && i instanceof RollershutterItem) {
// RollerShutter are represented as Switch in a Sitemap but need a PercentType state
returnState = itemState.as(PercentType.class);
} else if (w instanceof Slider) {
if (i.getAcceptedDataTypes().contains(PercentType.class)) {
returnState = itemState.as(PercentType.class);
} else {
returnState = itemState.as(DecimalType.class);
}
} else if (w instanceof Switch) {
Switch sw = (Switch) w;
if (sw.getMappings().size() == 0) {
returnState = itemState.as(OnOffType.class);
}
}
// if returnState is null, a conversion was not possible
if (returnState == null) {
// we return the original state to not break anything
returnState = itemState;
}
return returnState;
}
use of org.eclipse.smarthome.core.library.types.QuantityType 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.library.types.QuantityType in project smarthome by eclipse.
the class SelectionRenderer method renderWidget.
@Override
public EList<Widget> renderWidget(Widget w, StringBuilder sb) throws RenderException {
String snippet = getSnippet("selection");
snippet = StringUtils.replace(snippet, "%category%", getCategory(w));
snippet = StringUtils.replace(snippet, "%state%", getState(w));
snippet = StringUtils.replace(snippet, "%format%", getFormat());
State state = itemUIRegistry.getState(w);
Selection selection = (Selection) w;
String mappedValue = "";
Item item = null;
try {
item = itemUIRegistry.getItem(w.getItem());
} catch (ItemNotFoundException e) {
logger.debug("Failed to retrieve item during widget rendering: {}", e.getMessage());
}
StringBuilder rowSB = new StringBuilder();
for (Mapping mapping : selection.getMappings()) {
String rowSnippet = getSnippet("selection_row");
String command = mapping.getCmd() != null ? mapping.getCmd() : "";
String label = mapping.getLabel();
if (item instanceof NumberItem && ((NumberItem) item).getDimension() != null) {
String unit = getUnitForWidget(w);
command = StringUtils.replace(command, UnitUtils.UNIT_PLACEHOLDER, unit);
label = StringUtils.replace(label, UnitUtils.UNIT_PLACEHOLDER, unit);
// Special treatment for °C since uom library uses a single character: ℃
// This will ensure the current state matches the cmd and the buttonClass is set accordingly.
command = StringUtils.replace(command, "°C", "℃");
}
rowSnippet = StringUtils.replace(rowSnippet, "%item%", w.getItem() != null ? w.getItem() : "");
rowSnippet = StringUtils.replace(rowSnippet, "%cmd%", StringEscapeUtils.escapeHtml(command));
rowSnippet = StringUtils.replace(rowSnippet, "%label%", label != null ? StringEscapeUtils.escapeHtml(label) : "");
State compareMappingState = state;
if (state instanceof QuantityType) {
// convert the item state to the command value for proper
// comparison and "checked" attribute calculation
compareMappingState = convertStateToLabelUnit((QuantityType<?>) state, command);
}
if (compareMappingState.toString().equals(command)) {
rowSnippet = StringUtils.replace(rowSnippet, "%checked%", "checked=\"true\"");
mappedValue = (label != null) ? label : command;
} else {
rowSnippet = StringUtils.replace(rowSnippet, "%checked%", "");
}
rowSB.append(rowSnippet);
}
snippet = StringUtils.replace(snippet, "%label_header%", getLabel(w, mappedValue));
snippet = StringUtils.replace(snippet, "%rows%", rowSB.toString());
// Process the color tags
snippet = processColor(w, snippet);
sb.append(snippet);
return null;
}
use of org.eclipse.smarthome.core.library.types.QuantityType in project smarthome by eclipse.
the class SwitchRenderer method renderWidget.
@Override
public EList<Widget> renderWidget(Widget w, StringBuilder sb) throws RenderException {
Switch s = (Switch) w;
String snippetName = null;
Item item = null;
try {
item = itemUIRegistry.getItem(w.getItem());
if (s.getMappings().size() == 0) {
if (item instanceof RollershutterItem) {
snippetName = "rollerblind";
} else if (item instanceof GroupItem && ((GroupItem) item).getBaseItem() instanceof RollershutterItem) {
snippetName = "rollerblind";
} else {
snippetName = "switch";
}
} else {
snippetName = "buttons";
}
} catch (ItemNotFoundException e) {
logger.warn("Cannot determine item type of '{}'", w.getItem(), e);
snippetName = "switch";
}
String snippet = getSnippet(snippetName);
snippet = StringUtils.replace(snippet, "%id%", itemUIRegistry.getWidgetId(w));
snippet = StringUtils.replace(snippet, "%category%", getCategory(w));
snippet = StringUtils.replace(snippet, "%state%", getState(w));
snippet = StringUtils.replace(snippet, "%format%", getFormat());
snippet = StringUtils.replace(snippet, "%item%", w.getItem());
snippet = StringUtils.replace(snippet, "%label%", getLabel(w));
snippet = StringUtils.replace(snippet, "%servletname%", WebAppServlet.SERVLET_NAME);
State state = itemUIRegistry.getState(w);
if (s.getMappings().size() == 0) {
if (state.equals(OnOffType.ON)) {
snippet = snippet.replaceAll("%checked%", "checked=true");
} else {
snippet = snippet.replaceAll("%checked%", "");
}
} else {
StringBuilder buttons = new StringBuilder();
for (Mapping mapping : s.getMappings()) {
String button = getSnippet("button");
String command = mapping.getCmd();
String label = mapping.getLabel();
if (item instanceof NumberItem && ((NumberItem) item).getDimension() != null) {
String unit = getUnitForWidget(w);
command = StringUtils.replace(command, UnitUtils.UNIT_PLACEHOLDER, unit);
label = StringUtils.replace(label, UnitUtils.UNIT_PLACEHOLDER, unit);
// Special treatment for °C since uom library uses a single character: ℃
// This will ensure the current state matches the cmd and the buttonClass is set accordingly.
command = StringUtils.replace(command, "°C", "℃");
}
button = StringUtils.replace(button, "%item%", w.getItem());
button = StringUtils.replace(button, "%cmd%", StringEscapeUtils.escapeHtml(command));
button = StringUtils.replace(button, "%label%", label != null ? StringEscapeUtils.escapeHtml(label) : "");
String buttonClass;
State compareMappingState = state;
if (state instanceof QuantityType) {
// convert the item state to the command value for proper
// comparison and buttonClass calculation
compareMappingState = convertStateToLabelUnit((QuantityType<?>) state, command);
}
if (s.getMappings().size() > 1 && compareMappingState.toString().equals(command)) {
// button with red color
buttonClass = "Warn";
} else {
// button with blue color
buttonClass = "Action";
}
button = StringUtils.replace(button, "%type%", buttonClass);
buttons.append(button);
}
snippet = StringUtils.replace(snippet, "%buttons%", buttons.toString());
}
// Process the color tags
snippet = processColor(w, snippet);
sb.append(snippet);
return null;
}
Aggregations