2 * Copyright (c) 2010-2024 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.smhi.internal;
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;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
24 * @author Anders Alfredsson - Initial contribution
27 public class ForecastAggregator {
29 * Get the maximum value for the specified parameter for the n:th day after the forecast's reference time
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);
43 * Get the minimum value for the specified parameter for the n:th day after the forecast's reference time
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);
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.
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);
70 List<BigDecimal> values = new ArrayList<>();
71 for (int i = 0; i < dayForecasts.size(); i++) {
72 Forecast current = dayForecasts.get(i);
75 hours = current.getValidTime().until(dayForecasts.get(i + 1).getValidTime(), ChronoUnit.HOURS);
77 hours = dayForecasts.get(i - 1).getValidTime().until(current.getValidTime(), ChronoUnit.HOURS);
79 values.add(current.getParameter(parameter).map(value -> value.multiply(BigDecimal.valueOf(hours)))
80 .orElse(BigDecimal.ZERO));
82 return values.stream().reduce(BigDecimal::add);
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
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));