]> git.basschouten.com Git - openhab-addons.git/blob
88fb455be99625335b55d5b81b0e6821f10b9c7b
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.io.imperihome.internal.handler;
14
15 import java.net.URLDecoder;
16 import java.nio.charset.StandardCharsets;
17 import java.time.Instant;
18 import java.time.ZoneId;
19 import java.time.ZonedDateTime;
20 import java.util.Iterator;
21 import java.util.LinkedList;
22 import java.util.List;
23 import java.util.regex.Matcher;
24
25 import javax.servlet.http.HttpServletRequest;
26
27 import org.openhab.core.library.types.DecimalType;
28 import org.openhab.core.persistence.FilterCriteria;
29 import org.openhab.core.persistence.HistoricItem;
30 import org.openhab.core.persistence.PersistenceService;
31 import org.openhab.core.persistence.PersistenceServiceRegistry;
32 import org.openhab.core.persistence.QueryablePersistenceService;
33 import org.openhab.core.types.State;
34 import org.openhab.io.imperihome.internal.model.HistoryItem;
35 import org.openhab.io.imperihome.internal.model.HistoryList;
36 import org.openhab.io.imperihome.internal.model.device.AbstractDevice;
37 import org.openhab.io.imperihome.internal.processor.DeviceRegistry;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 /**
42  * Device history request handler.
43  *
44  * @author Pepijn de Geus - Initial contribution
45  */
46 public class DeviceHistoryHandler {
47
48     private final Logger logger = LoggerFactory.getLogger(DeviceHistoryHandler.class);
49
50     private final DeviceRegistry deviceRegistry;
51     private final PersistenceServiceRegistry persistenceServiceRegistry;
52
53     public DeviceHistoryHandler(DeviceRegistry deviceRegistry, PersistenceServiceRegistry persistenceServiceRegistry) {
54         this.deviceRegistry = deviceRegistry;
55         this.persistenceServiceRegistry = persistenceServiceRegistry;
56     }
57
58     public HistoryList handle(HttpServletRequest req, Matcher urlMatcher) {
59         String deviceId, field;
60         long start, end;
61         try {
62             deviceId = URLDecoder.decode(urlMatcher.group(1), StandardCharsets.UTF_8);
63             field = URLDecoder.decode(urlMatcher.group(2), StandardCharsets.UTF_8);
64             start = Long.parseLong(urlMatcher.group(3));
65             end = Long.parseLong(urlMatcher.group(4));
66         } catch (NumberFormatException e) {
67             throw new RuntimeException("Could not decode request params", e);
68         }
69
70         logger.debug("History request for device {}, field {}: {}-{}", deviceId, field, start, end);
71
72         AbstractDevice device = deviceRegistry.getDevice(deviceId);
73         if (device == null) {
74             logger.warn("Received history request for unknown device: {}", urlMatcher.group(0));
75             return null;
76         }
77
78         PersistenceService persistence = persistenceServiceRegistry.getDefault();
79         if (persistence == null) {
80             logger.warn("Could not retrieve default persistence service; can't serve history request");
81             return null;
82         }
83         if (!(persistence instanceof QueryablePersistenceService)) {
84             logger.warn("Default persistence service is not queryable; can't serve history request");
85             return null;
86         }
87
88         return serveHistory(device, (QueryablePersistenceService) persistence, start, end);
89     }
90
91     private HistoryList serveHistory(AbstractDevice device, QueryablePersistenceService persistence, long start,
92             long end) {
93         logger.info("Querying persistence for history of Item {}, from {} to {}", device.getItemName(), start, end);
94
95         FilterCriteria criteria = new FilterCriteria().setItemName(device.getItemName())
96                 .setBeginDate(ZonedDateTime.ofInstant(Instant.ofEpochMilli(start), ZoneId.systemDefault()))
97                 .setEndDate(ZonedDateTime.ofInstant(Instant.ofEpochMilli(end), ZoneId.systemDefault()));
98
99         List<HistoryItem> resultItems = new LinkedList<>();
100         Iterable<HistoricItem> historicItems = persistence.query(criteria);
101
102         Iterator<HistoricItem> iterator = historicItems.iterator();
103         if (!iterator.hasNext()) {
104             logger.info("Persistence returned no results for history query");
105         } else {
106             while (iterator.hasNext()) {
107                 HistoricItem historicItem = iterator.next();
108                 State state = historicItem.getState();
109                 if (state instanceof DecimalType) {
110                     Number value = ((DecimalType) state).toBigDecimal();
111                     resultItems.add(new HistoryItem(historicItem.getTimestamp().toInstant().toEpochMilli(), value));
112                 }
113             }
114
115             if (resultItems.isEmpty()) {
116                 logger.warn(
117                         "Persistence returned results for history query, but could not be interpreted as DecimalTypes");
118             }
119         }
120
121         return new HistoryList(resultItems);
122     }
123 }