]> git.basschouten.com Git - openhab-addons.git/blob
eb598da257f13941c009a6f9a1ad6bf0b038562a
[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.binding.smhi.internal;
14
15 import java.math.BigDecimal;
16 import java.time.temporal.ChronoUnit;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.Optional;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22
23 /**
24  * @author Anders Alfredsson - Initial contribution
25  */
26 @NonNullByDefault
27 public class ForecastAggregator {
28     /**
29      * Get the maximum value for the specified parameter for the n:th day after the forecast's reference time
30      *
31      * @param timeSeries
32      * @param dayOffset
33      * @param parameter
34      * @return
35      */
36     public static Optional<BigDecimal> max(TimeSeries timeSeries, int dayOffset, String parameter) {
37         List<Forecast> dayForecasts = timeSeries.getDay(dayOffset);
38         return dayForecasts.stream().map(forecast -> forecast.getParameter(parameter)).filter(Optional::isPresent)
39                 .map(Optional::get).max(BigDecimal::compareTo);
40     }
41
42     /**
43      * Get the minimum value for the specified parameter for the n:th day after the forecast's reference time
44      *
45      * @param timeSeries
46      * @param dayOffset
47      * @param parameter
48      * @return
49      */
50     public static Optional<BigDecimal> min(TimeSeries timeSeries, int dayOffset, String parameter) {
51         List<Forecast> dayForecasts = timeSeries.getDay(dayOffset);
52         return dayForecasts.stream().map(forecast -> forecast.getParameter(parameter)).filter(Optional::isPresent)
53                 .map(Optional::get).min(BigDecimal::compareTo);
54     }
55
56     /**
57      * Get the total value for the specified parameter for the n:th day after the forecast's reference time.
58      * If there aren't any values for every hour, the previous value is used for each empty slot.
59      *
60      * @param timeSeries
61      * @param dayOffset
62      * @param parameter
63      * @return
64      */
65     public static Optional<BigDecimal> total(TimeSeries timeSeries, int dayOffset, String parameter) {
66         List<Forecast> dayForecasts = timeSeries.getDay(dayOffset);
67         if (dayForecasts.size() == 1) {
68             return dayForecasts.get(0).getParameter(parameter);
69         }
70         List<BigDecimal> values = new ArrayList<>();
71         for (int i = 0; i < dayForecasts.size(); i++) {
72             Forecast current = dayForecasts.get(i);
73             long hours;
74             if (i == 0) {
75                 hours = current.getValidTime().until(dayForecasts.get(i + 1).getValidTime(), ChronoUnit.HOURS);
76             } else {
77                 hours = dayForecasts.get(i - 1).getValidTime().until(current.getValidTime(), ChronoUnit.HOURS);
78             }
79             values.add(current.getParameter(parameter).map(value -> value.multiply(BigDecimal.valueOf(hours)))
80                     .orElse(BigDecimal.ZERO));
81         }
82         return values.stream().reduce(BigDecimal::add);
83     }
84
85     /**
86      * Get the value at 12:00 UTC for the specified parameter for the n:th day after the forecast's reference time.
87      * If that time is not included (should only happen for day 0 if after 12:00), get the first value for the day
88      * instead.
89      *
90      * @param timeSeries
91      * @param dayOffset
92      * @param parameter
93      * @return
94      */
95     public static Optional<BigDecimal> noonOrFirst(TimeSeries timeSeries, int dayOffset, String parameter) {
96         List<Forecast> dayForecasts = timeSeries.getDay(dayOffset);
97         return dayForecasts.stream().filter(forecast -> forecast.getValidTime().getHour() >= 12).findFirst()
98                 .flatMap(forecast -> forecast.getParameter(parameter));
99     }
100 }