-
Notifications
You must be signed in to change notification settings - Fork 5
/
CsvThermalSource.java
214 lines (195 loc) · 8.87 KB
/
CsvThermalSource.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
* © 2021. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.io.source.csv;
import edu.ie3.datamodel.io.factory.input.*;
import edu.ie3.datamodel.io.naming.FileNamingStrategy;
import edu.ie3.datamodel.io.source.ThermalSource;
import edu.ie3.datamodel.io.source.TypeSource;
import edu.ie3.datamodel.models.input.OperatorInput;
import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput;
import edu.ie3.datamodel.models.input.thermal.ThermalBusInput;
import edu.ie3.datamodel.models.input.thermal.ThermalHouseInput;
import edu.ie3.datamodel.models.input.thermal.ThermalStorageInput;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Source that provides the capability to build thermal {@link
* edu.ie3.datamodel.models.input.AssetInput} entities from .csv files
*
* <p>This source is <b>not buffered</b> which means each call on a getter method always tries to
* read all data is necessary to return the requested objects in a hierarchical cascading way.
*
* <p>If performance is an issue, it is recommended to read the data cascading starting with reading
* nodes and then using the getters with arguments to avoid reading the same data multiple times.
*
* <p>The resulting sets are always unique on object <b>and</b> UUID base (with distinct UUIDs).
*
* @version 0.1
* @since 03.04.20
*/
public class CsvThermalSource extends CsvDataSource implements ThermalSource {
// general fields
private final TypeSource typeSource;
// factories
private final ThermalBusInputFactory thermalBusInputFactory;
private final CylindricalStorageInputFactory cylindricalStorageInputFactory;
private final ThermalHouseInputFactory thermalHouseInputFactory;
public CsvThermalSource(
String csvSep,
Path thermalUnitsFolderPath,
FileNamingStrategy fileNamingStrategy,
TypeSource typeSource) {
super(csvSep, thermalUnitsFolderPath, fileNamingStrategy);
this.typeSource = typeSource;
// init factories
this.thermalBusInputFactory = new ThermalBusInputFactory();
this.cylindricalStorageInputFactory = new CylindricalStorageInputFactory();
this.thermalHouseInputFactory = new ThermalHouseInputFactory();
}
/** {@inheritDoc} */
@Override
public Set<ThermalBusInput> getThermalBuses() {
return assetInputEntityDataStream(ThermalBusInput.class, typeSource.getOperators())
.map(thermalBusInputFactory::get)
.flatMap(Optional::stream)
.collect(Collectors.toSet());
}
/**
* {@inheritDoc}
*
* <p>If the set with {@link OperatorInput} is not exhaustive, the corresponding operator is set
* to {@link OperatorInput#NO_OPERATOR_ASSIGNED}
*/
@Override
public Set<ThermalBusInput> getThermalBuses(Set<OperatorInput> operators) {
return assetInputEntityDataStream(ThermalBusInput.class, operators)
.map(thermalBusInputFactory::get)
.flatMap(Optional::stream)
.collect(Collectors.toSet());
}
/** {@inheritDoc} */
@Override
public Set<ThermalStorageInput> getThermalStorages() {
return new HashSet<>(getCylindricStorages());
}
/**
* {@inheritDoc}
*
* <p>If the set of {@link ThermalBusInput} entities is not exhaustive for all available {@link
* ThermalStorageInput} entities (e.g. a {@link ThermalBusInput} entity is missing) or if an error
* during the building process occurs, the entity that misses something will be skipped (which can
* be seen as a filtering functionality) but all entities that are able to be built will be
* returned anyway and the elements that couldn't have been built are logged.
*
* <p>If the set with {@link OperatorInput} is not exhaustive, the corresponding operator is set
* to {@link OperatorInput#NO_OPERATOR_ASSIGNED}
*/
@Override
public Set<ThermalStorageInput> getThermalStorages(
Set<OperatorInput> operators, Set<ThermalBusInput> thermalBuses) {
return new HashSet<>(getCylindricStorages(operators, thermalBuses));
}
/** {@inheritDoc} */
@Override
public Set<ThermalHouseInput> getThermalHouses() {
return assetInputEntityDataStream(ThermalHouseInput.class, typeSource.getOperators())
.flatMap(
assetInputEntityData ->
buildThermalUnitInputEntityData(assetInputEntityData, getThermalBuses())
.map(dataOpt -> dataOpt.flatMap(thermalHouseInputFactory::get))
.flatMap(Optional::stream))
.collect(Collectors.toSet());
}
/**
* {@inheritDoc}
*
* <p>If the set of {@link ThermalBusInput} entities is not exhaustive for all available {@link
* ThermalHouseInput} entities (e.g. a {@link ThermalBusInput} entity is missing) or if an error
* during the building process occurs, the entity that misses something will be skipped (which can
* be seen as a filtering functionality) but all entities that are able to be built will be
* returned anyway and the elements that couldn't have been built are logged.
*
* <p>If the set with {@link OperatorInput} is not exhaustive, the corresponding operator is set
* to {@link OperatorInput#NO_OPERATOR_ASSIGNED}
*/
@Override
public Set<ThermalHouseInput> getThermalHouses(
Set<OperatorInput> operators, Set<ThermalBusInput> thermalBuses) {
return assetInputEntityDataStream(ThermalHouseInput.class, operators)
.map(
assetInputEntityData ->
buildThermalUnitInputEntityData(assetInputEntityData, thermalBuses)
.map(dataOpt -> dataOpt.flatMap(thermalHouseInputFactory::get)))
.flatMap(elements -> elements.flatMap(Optional::stream))
.collect(Collectors.toSet());
}
/** {@inheritDoc} */
@Override
public Set<CylindricalStorageInput> getCylindricStorages() {
return assetInputEntityDataStream(CylindricalStorageInput.class, typeSource.getOperators())
.map(
assetInputEntityData ->
buildThermalUnitInputEntityData(assetInputEntityData, getThermalBuses())
.map(dataOpt -> dataOpt.flatMap(cylindricalStorageInputFactory::get)))
.flatMap(elements -> elements.flatMap(Optional::stream))
.collect(Collectors.toSet());
}
/**
* {@inheritDoc}
*
* <p>If the set of {@link ThermalBusInput} entities is not exhaustive for all available {@link
* CylindricalStorageInput} entities (e.g. a {@link ThermalBusInput} entity is missing) or if an
* error during the building process occurs, the entity that misses something will be skipped
* (which can be seen as a filtering functionality) but all entities that are able to be built
* will be returned anyway and the elements that couldn't have been built are logged.
*
* <p>If the set with {@link OperatorInput} is not exhaustive, the corresponding operator is set
* to {@link OperatorInput#NO_OPERATOR_ASSIGNED}
*/
@Override
public Set<CylindricalStorageInput> getCylindricStorages(
Set<OperatorInput> operators, Set<ThermalBusInput> thermalBuses) {
return assetInputEntityDataStream(CylindricalStorageInput.class, operators)
.map(
assetInputEntityData ->
buildThermalUnitInputEntityData(assetInputEntityData, thermalBuses)
.map(dataOpt -> dataOpt.flatMap(cylindricalStorageInputFactory::get)))
.flatMap(elements -> elements.flatMap(Optional::stream))
.collect(Collectors.toSet());
}
private Stream<Optional<ThermalUnitInputEntityData>> buildThermalUnitInputEntityData(
AssetInputEntityData assetInputEntityData, Collection<ThermalBusInput> thermalBuses) {
// get the raw data
Map<String, String> fieldsToAttributes = assetInputEntityData.getFieldsToValues();
// get the thermal bus input for this chp unit
String thermalBusUuid = fieldsToAttributes.get("thermalbus");
Optional<ThermalBusInput> thermalBus =
thermalBuses.stream()
.filter(storage -> storage.getUuid().toString().equalsIgnoreCase(thermalBusUuid))
.findFirst();
// remove fields that are passed as objects to constructor
fieldsToAttributes.keySet().removeAll(new HashSet<>(Collections.singletonList("thermalbus")));
// if the type is not present we return an empty element and
// log a warning
if (thermalBus.isEmpty()) {
logSkippingWarning(
assetInputEntityData.getTargetClass().getSimpleName(),
fieldsToAttributes.get("uuid"),
fieldsToAttributes.get("id"),
"thermalBus: " + thermalBusUuid);
return Stream.of(Optional.empty());
}
return Stream.of(
Optional.of(
new ThermalUnitInputEntityData(
assetInputEntityData.getFieldsToValues(),
assetInputEntityData.getTargetClass(),
assetInputEntityData.getOperatorInput(),
thermalBus.get())));
}
}