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.fmiweather.internal.client;
15 import java.math.BigDecimal;
16 import java.util.ArrayList;
17 import java.util.HashMap;
18 import java.util.List;
20 import java.util.Map.Entry;
21 import java.util.Optional;
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
28 * Class representing response from the FMI weather service
30 * @author Sami Salonen - Initial contribution
34 public class FMIResponse {
36 private Map<Location, Map<String, Data>> dataByLocationByParameter;
39 * Builder class for FMIResponse
41 * @author Sami Salonen
42 * author Sami Salonen - Initial contribution/
45 public static class Builder {
47 private Map<Location, Map<String, List<Long>>> timestampsByLocationByParameter;
48 private Map<Location, Map<String, List<@Nullable BigDecimal>>> valuesByLocationByParameter;
51 timestampsByLocationByParameter = new HashMap<>();
52 valuesByLocationByParameter = new HashMap<>();
55 public Builder appendLocationData(Location location, @Nullable Integer capacityHintForValues, String parameter,
56 long epochSecond, @Nullable BigDecimal val) {
57 timestampsByLocationByParameter.computeIfAbsent(location, k -> new HashMap<>()).computeIfAbsent(parameter,
58 k -> capacityHintForValues == null ? new ArrayList<>() : new ArrayList<>(capacityHintForValues))
60 valuesByLocationByParameter.computeIfAbsent(location, k -> new HashMap<>()).computeIfAbsent(parameter,
61 k -> capacityHintForValues == null ? new ArrayList<>() : new ArrayList<>(capacityHintForValues))
66 public FMIResponse build() {
67 Map<Location, Map<String, Data>> out = new HashMap<>(timestampsByLocationByParameter.size());
68 timestampsByLocationByParameter.entrySet().forEach(entry -> {
69 collectParametersForLocation(out, entry);
71 return new FMIResponse(out);
74 private void collectParametersForLocation(Map<Location, Map<String, Data>> out,
75 Entry<Location, Map<String, List<Long>>> locationEntry) {
76 Location location = locationEntry.getKey();
77 Map<String, List<Long>> timestampsByParameter = locationEntry.getValue();
78 out.put(location, new HashMap<String, Data>(timestampsByParameter.size()));
79 timestampsByParameter.entrySet().stream().forEach(parameterEntry -> {
80 collectValuesForParameter(out, location, parameterEntry);
84 private void collectValuesForParameter(Map<Location, Map<String, Data>> out, Location location,
85 Entry<String, List<Long>> parameterEntry) {
86 String parameter = parameterEntry.getKey();
87 long[] timestamps = parameterEntry.getValue().stream().mapToLong(Long::longValue).toArray();
88 BigDecimal[] values = valuesByLocationByParameter.get(location).get(parameter)
89 .toArray(new @Nullable BigDecimal[0]);
90 Data dataValues = new Data(timestamps, values);
91 out.get(location).put(parameter, dataValues);
95 public FMIResponse(Map<Location, Map<String, Data>> dataByLocationByParameter) {
96 this.dataByLocationByParameter = dataByLocationByParameter;
99 public Optional<Data> getData(Location location, String parameter) {
100 return Optional.ofNullable(dataByLocationByParameter.get(location)).map(paramData -> paramData.get(parameter));
103 public Set<Location> getLocations() {
104 return dataByLocationByParameter.keySet();
107 public Optional<Set<String>> getParameters(Location location) {
108 return Optional.ofNullable(dataByLocationByParameter.get(location)).map(paramData -> paramData.keySet());
112 public String toString() {
113 return new StringBuilder("FMIResponse(").append(dataByLocationByParameter.toString()).append(")").toString();