use of org.eclipse.smarthome.core.persistence.HistoricItem in project smarthome by eclipse.
the class PersistenceExtensions method evolutionRate.
/**
* Gets the evolution rate of the state of a given <code>item</code> since a certain point in time.
* The {@link PersistenceService} identified by the <code>serviceId</code> is used.
*
* @param item the item to get the evolution rate value for
* @param timestamp the point in time from which to compute the evolution rate
* @param serviceId the name of the {@link PersistenceService} to use
* @return the evolution rate in percent (positive and negative) between now and then, or <code>null</code> if
* the persistence service given by serviceId is not available or is not a
* {@link QueryablePersistenceService}, or if there is no persisted state for the given
* <code>item</code> at the given <code>timestamp</code> using the persistence service given by
* <code>serviceId</code>, or if there is a state but it is zero (which would cause a divide-by-zero
* error)
*/
public static DecimalType evolutionRate(Item item, AbstractInstant timestamp, String serviceId) {
HistoricItem itemThen = historicState(item, timestamp, serviceId);
if (itemThen != null) {
DecimalType valueThen = (DecimalType) itemThen.getState();
DecimalType valueNow = (DecimalType) item.getStateAs(DecimalType.class);
if ((valueThen != null) && (valueThen.toBigDecimal().compareTo(BigDecimal.ZERO) != 0) && (valueNow != null)) {
// ((now - then) / then) * 100
return new DecimalType(valueNow.toBigDecimal().subtract(valueThen.toBigDecimal()).divide(valueThen.toBigDecimal(), MathContext.DECIMAL64).movePointRight(2));
}
}
return null;
}
use of org.eclipse.smarthome.core.persistence.HistoricItem in project smarthome by eclipse.
the class PersistenceExtensions method historicState.
/**
* Retrieves the historic item for a given <code>item</code> at a certain point in time through a
* {@link PersistenceService} identified by the <code>serviceId</code>.
*
* @param item the item for which to retrieve the historic item
* @param timestamp the point in time for which the historic item should be retrieved
* @param serviceId the name of the {@link PersistenceService} to use
* @return the historic item at the given point in time, or <code>null</code> if no historic item could be found or
* if the provided <code>serviceId</code> does not refer to an available
* {@link QueryablePersistenceService}
*/
public static HistoricItem historicState(Item item, AbstractInstant timestamp, String serviceId) {
PersistenceService service = getService(serviceId);
if (service instanceof QueryablePersistenceService) {
QueryablePersistenceService qService = (QueryablePersistenceService) service;
FilterCriteria filter = new FilterCriteria();
filter.setEndDate(ZonedDateTime.ofInstant(timestamp.toDate().toInstant(), timeZoneProvider.getTimeZone()));
filter.setItemName(item.getName());
filter.setPageSize(1);
filter.setOrdering(Ordering.DESCENDING);
Iterable<HistoricItem> result = qService.query(filter);
if (result.iterator().hasNext()) {
return result.iterator().next();
} else {
return null;
}
} else {
LoggerFactory.getLogger(PersistenceExtensions.class).warn("There is no queryable persistence service registered with the id '{}'", serviceId);
return null;
}
}
use of org.eclipse.smarthome.core.persistence.HistoricItem in project smarthome by eclipse.
the class PersistenceExtensions method lastUpdate.
/**
* Query for the last update time of a given <code>item</code>.
*
* @param item the item for which the last update time is to be returned
* @param serviceId the name of the {@link PersistenceService} to use
* @return last time <code>item</code> was updated, or <code>null</code> if there are no previously
* persisted updates or if persistence service given by <code>serviceId</code> does not refer to an
* available {@link QueryablePersistenceService}
*/
public static AbstractInstant lastUpdate(Item item, String serviceId) {
PersistenceService service = getService(serviceId);
if (service instanceof QueryablePersistenceService) {
QueryablePersistenceService qService = (QueryablePersistenceService) service;
FilterCriteria filter = new FilterCriteria();
filter.setItemName(item.getName());
filter.setOrdering(Ordering.DESCENDING);
filter.setPageSize(1);
Iterable<HistoricItem> result = qService.query(filter);
if (result.iterator().hasNext()) {
return new DateTime(result.iterator().next().getTimestamp());
} else {
return null;
}
} else {
LoggerFactory.getLogger(PersistenceExtensions.class).warn("There is no queryable persistence service registered with the id '{}'", serviceId);
return null;
}
}
use of org.eclipse.smarthome.core.persistence.HistoricItem in project habot by ghys.
the class HistoryLastChangesSkill method interpret.
@Override
public IntentInterpretation interpret(Intent intent, String language) {
IntentInterpretation interpretation = new IntentInterpretation();
Set<Item> matchedItems = findItems(intent);
if (matchedItems == null || matchedItems.isEmpty()) {
interpretation.setAnswer(answerFormatter.getRandomAnswer("answer_nothing_found"));
interpretation.setHint(answerFormatter.getStandardTagHint(intent.getEntities()));
return interpretation;
}
Set<String> tags = intent.getEntities().entrySet().stream().map(e -> e.getKey() + ":" + e.getValue()).collect(Collectors.toSet());
Card card = new Card("HbCard");
card.addTags(tags);
card.updateTimestamp();
card.setEphemeral(true);
card.setAddToDeckDenied(true);
Component timeline = new Component("HbTimeline");
if (matchedItems.size() == 1) {
Item item = matchedItems.stream().findFirst().get();
// TODO figure out a solution
HistoricItem historicItem = PersistenceExtensions.previousState(item, false);
if (historicItem == null) {
interpretation.setAnswer(answerFormatter.getRandomAnswer("answer_nothing_found"));
interpretation.setHint(answerFormatter.getRandomAnswer("no_historical_data"));
return interpretation;
}
card.setTitle(item.getLabel());
card.setSubtitle(item.getName());
DateFormat dateFormat = new SimpleDateFormat();
Component pastTimelineEntry = new Component("HbTimelineEntry");
pastTimelineEntry.addConfig("title", formatState(item, historicItem.getState()));
pastTimelineEntry.addConfig("subtitle", dateFormat.format(historicItem.getTimestamp()));
timeline.addComponent("main", pastTimelineEntry);
Component nowTimelineEntry = new Component("HbTimelineEntry");
nowTimelineEntry.addConfig("title", formatState(item, historicItem.getState()));
nowTimelineEntry.addConfig("subtitle", dateFormat.format(new Date()));
timeline.addComponent("main", nowTimelineEntry);
} else {
interpretation.setAnswer(answerFormatter.getRandomAnswer("multiple_items_error"));
return interpretation;
}
card.addComponent("main", timeline);
this.cardRegistry.add(card);
interpretation.setAnswer(answerFormatter.getRandomAnswer("info_found_simple"));
interpretation.setCard(card);
return interpretation;
}
use of org.eclipse.smarthome.core.persistence.HistoricItem in project smarthome by eclipse.
the class DefaultChartProvider method addItem.
boolean addItem(Chart chart, QueryablePersistenceService service, Date timeBegin, Date timeEnd, Item item, int seriesCounter, ChartTheme chartTheme, int dpi) {
Color color = chartTheme.getLineColor(seriesCounter);
// Get the item label
String label = null;
if (itemUIRegistry != null) {
// Get the item label
label = itemUIRegistry.getLabel(item.getName());
if (label != null && label.contains("[") && label.contains("]")) {
label = label.substring(0, label.indexOf('['));
}
}
if (label == null) {
label = item.getName();
}
Iterable<HistoricItem> result;
FilterCriteria filter;
// Generate data collections
List<Date> xData = new ArrayList<Date>();
List<Number> yData = new ArrayList<Number>();
// Declare state here so it will hold the last value at the end of the process
State state = null;
// First, get the value at the start time.
// This is necessary for values that don't change often otherwise data will start
// after the start of the graph (or not at all if there's no change during the graph period)
filter = new FilterCriteria();
filter.setEndDate(ZonedDateTime.ofInstant(timeBegin.toInstant(), timeZoneProvider.getTimeZone()));
filter.setItemName(item.getName());
filter.setPageSize(1);
filter.setOrdering(Ordering.DESCENDING);
result = service.query(filter);
if (result.iterator().hasNext()) {
HistoricItem historicItem = result.iterator().next();
state = historicItem.getState();
xData.add(timeBegin);
yData.add(convertData(state));
}
// Now, get all the data between the start and end time
filter.setBeginDate(ZonedDateTime.ofInstant(timeBegin.toInstant(), timeZoneProvider.getTimeZone()));
filter.setEndDate(ZonedDateTime.ofInstant(timeEnd.toInstant(), timeZoneProvider.getTimeZone()));
filter.setPageSize(Integer.MAX_VALUE);
filter.setOrdering(Ordering.ASCENDING);
// Get the data from the persistence store
result = service.query(filter);
Iterator<HistoricItem> it = result.iterator();
// Iterate through the data
while (it.hasNext()) {
HistoricItem historicItem = it.next();
// to avoid diagonal lines
if (state instanceof OnOffType || state instanceof OpenClosedType) {
Calendar cal = Calendar.getInstance();
cal.setTime(historicItem.getTimestamp());
cal.add(Calendar.MILLISECOND, -1);
xData.add(cal.getTime());
yData.add(convertData(state));
}
state = historicItem.getState();
xData.add(historicItem.getTimestamp());
yData.add(convertData(state));
}
// Lastly, add the final state at the endtime
if (state != null) {
xData.add(timeEnd);
yData.add(convertData(state));
}
// The chart engine will throw an exception if there's no data
if (xData.size() == 0) {
return false;
}
// If there's only 1 data point, plot it again!
if (xData.size() == 1) {
xData.add(xData.iterator().next());
yData.add(yData.iterator().next());
}
Series series = chart.addSeries(label, xData, yData);
float lineWidth = (float) chartTheme.getLineWidth(dpi);
series.setLineStyle(new BasicStroke(lineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));
series.setMarker(SeriesMarker.NONE);
series.setLineColor(color);
// We use this to decide whether to put the legend in the top or bottom corner.
if (yData.iterator().next().floatValue() > ((series.getYMax() - series.getYMin()) / 2 + series.getYMin())) {
legendPosition++;
} else {
legendPosition--;
}
return true;
}
Aggregations