Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancing TimeSeriesSources with method to extract future activation ticks #1059

Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
920aea4
Enhancing `TimeSeriesSource`s with method to extract future activatio…
staudtMarius Apr 8, 2024
27197fd
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Apr 9, 2024
bd2a28e
Fixing `Codacy` issues.
staudtMarius Apr 9, 2024
0aad6a5
Fixing `Codacy` issues.
staudtMarius Apr 9, 2024
afaff06
Fixing `Codacy` issue.
staudtMarius Apr 9, 2024
4785c51
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Apr 9, 2024
3e7d708
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Apr 15, 2024
916ac5a
Adapting `CHANGELOG`.
staudtMarius Apr 15, 2024
2bc514b
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Apr 23, 2024
54d2498
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Apr 30, 2024
945793d
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius May 1, 2024
db990d2
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius May 6, 2024
afcac35
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius May 7, 2024
50da7db
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius May 16, 2024
2d48c86
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius May 23, 2024
8bab275
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Jun 4, 2024
cd8f83c
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Jun 10, 2024
4ff3810
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Jun 11, 2024
cdaf952
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Jun 11, 2024
d901995
fmt
staudtMarius Jun 11, 2024
b24e11f
Some improvements to queries.
staudtMarius Jun 13, 2024
909db48
Merge branch 'refs/heads/dev' into ms/#543-enhance-timeseriesSources-…
staudtMarius Jun 24, 2024
3c7b167
Adding some comments.
staudtMarius Jun 24, 2024
a97201b
Adding some comments.
staudtMarius Jun 24, 2024
b4a1a29
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Jun 24, 2024
56280ab
Merge branch 'refs/heads/dev' into ms/#543-enhance-timeseriesSources-…
staudtMarius Jun 24, 2024
b998e53
Adapt to changes.
staudtMarius Jun 24, 2024
b63ae06
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Jun 24, 2024
f7ce136
Update `CHANGELOG`.
staudtMarius Jun 24, 2024
6862fbb
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Jul 1, 2024
efb7fff
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Jul 4, 2024
a8fe02d
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Jul 9, 2024
8dc7b0e
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Jul 29, 2024
be66f2b
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
staudtMarius Aug 9, 2024
75e10a9
Merge branch 'dev' into ms/#543-enhance-timeseriesSources-with-future…
sebastian-peter Aug 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Enhancing `VoltageLevel` with `equals` method [#1063](https://github.com/ie3-institute/PowerSystemDataModel/issues/1063)
- `ConnectorValidationUtils` checks if parallel devices is > 0 [#1077](https://github.com/ie3-institute/PowerSystemDataModel/issues/1077)
- Enhance `TimeSeriesSource` with method to retrieve all time keys after a given key [#543](https://github.com/ie3-institute/PowerSystemDataModel/issues/543)
- Enhance `WeatherSource` with method to retrieve all time keys after a given key [#572](https://github.com/ie3-institute/PowerSystemDataModel/issues/572)

### Fixed
- Fixed `MappingEntryies` not getting processed by adding `Getter` methods for record fields [#1084](https://github.com/ie3-institute/PowerSystemDataModel/issues/1084)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,12 @@ public abstract IndividualTimeSeries<V> getTimeSeries(ClosedInterval<ZonedDateTi
throws SourceException;

public abstract Optional<V> getValue(ZonedDateTime time) throws SourceException;

/**
* Method to return all time keys after a given timestamp.
*
* @param time given time
* @return a list of time keys
*/
public abstract List<ZonedDateTime> getTimeKeysAfter(ZonedDateTime time);
}
10 changes: 8 additions & 2 deletions src/main/java/edu/ie3/datamodel/io/source/WeatherSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ public abstract class WeatherSource {

protected TimeBasedWeatherValueFactory weatherFactory;

protected Map<Point, IndividualTimeSeries<WeatherValue>> coordinateToTimeSeries;

protected IdCoordinateSource idCoordinateSource;

protected static final String COORDINATE_ID = "coordinateid";
Expand Down Expand Up @@ -61,6 +59,14 @@ public abstract Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
public abstract Optional<TimeBasedValue<WeatherValue>> getWeather(
ZonedDateTime date, Point coordinate) throws SourceException;

public abstract Map<Point, List<ZonedDateTime>> getTimeKeysAfter(ZonedDateTime time)
throws SourceException;

public List<ZonedDateTime> getTimeKeysAfter(ZonedDateTime time, Point coordinate)
throws SourceException {
return getTimeKeysAfter(time).getOrDefault(coordinate, Collections.emptyList());
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,37 @@ public Optional<TimeBasedValue<WeatherValue>> getWeather(ZonedDateTime date, Poi
}
}

@Override
public Map<Point, List<ZonedDateTime>> getTimeKeysAfter(ZonedDateTime time) {
String query = createQueryStringForFollowingTimeKeys(time);
CompletableFuture<QueryResult> futureResult = connector.query(query);
QueryResult queryResult = futureResult.join();
List<JsonObject> jsonWeatherInputs = Collections.emptyList();
try {
jsonWeatherInputs = queryResult.rowsAsObject();
} catch (DecodingFailureException ex) {
logger.error("Querying weather inputs failed!", ex);
}
if (jsonWeatherInputs != null && !jsonWeatherInputs.isEmpty()) {

Map<Point, Set<TimeBasedValue<WeatherValue>>> timeBasedValues =
jsonWeatherInputs.stream()
.map(this::toTimeBasedWeatherValue)
.flatMap(Optional::stream)
.filter(t -> t.getTime().isAfter(time))
.collect(
Collectors.groupingBy(t -> t.getValue().getCoordinate(), Collectors.toSet()));

return timeBasedValues.entrySet().stream()
.collect(
Collectors.toMap(
Map.Entry::getKey,
t -> t.getValue().stream().map(TimeBasedValue::getTime).sorted().toList()));
}

return Collections.emptyMap();
}

/**
* Generates a key for weather documents with the pattern: {@code
* weather::<coordinate_id>::<time>}
Expand Down Expand Up @@ -216,6 +247,19 @@ public String createQueryStringForIntervalAndCoordinate(
return basicQuery + whereClause;
}

/**
* Create a query string to search for all time keys that comes after the given time.
*
* @param time given timestamp
* @return the query string
*/
public String createQueryStringForFollowingTimeKeys(ZonedDateTime time) {
String basicQuery =
"SELECT " + connector.getBucketName() + ".* FROM " + connector.getBucketName();
staudtMarius marked this conversation as resolved.
Show resolved Hide resolved
String whereClause = " WHERE META().id > '" + generateWeatherKey(time, 0) + "'";
staudtMarius marked this conversation as resolved.
Show resolved Hide resolved
return basicQuery + whereClause;
}

/**
* Converts a JsonObject into TimeBasedWeatherValueData by extracting all fields into a field to
* value map and then removing the coordinate from it to supply as a parameter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ public Optional<V> getValue(ZonedDateTime time) {
return timeSeries.getValue(time);
}

@Override
public List<ZonedDateTime> getTimeKeysAfter(ZonedDateTime time) {
return timeSeries.getTimeKeysAfter(time);
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

/** Implements a WeatherSource for CSV files by using the CsvTimeSeriesSource as a base */
public class CsvWeatherSource extends WeatherSource {
private final Map<Point, IndividualTimeSeries<WeatherValue>> coordinateToTimeSeries;
staudtMarius marked this conversation as resolved.
Show resolved Hide resolved

private final CsvDataSource dataSource;

Expand All @@ -64,7 +65,7 @@ public CsvWeatherSource(
throws SourceException {
super(idCoordinateSource, weatherFactory);
this.dataSource = new CsvDataSource(csvSep, folderPath, fileNamingStrategy);
coordinateToTimeSeries = getWeatherTimeSeries();
this.coordinateToTimeSeries = getWeatherTimeSeries();
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Expand Down Expand Up @@ -98,6 +99,12 @@ public Optional<TimeBasedValue<WeatherValue>> getWeather(ZonedDateTime date, Poi
return timeSeries.getTimeBasedValue(date);
}

@Override
public Map<Point, List<ZonedDateTime>> getTimeKeysAfter(ZonedDateTime time) {
return coordinateToTimeSeries.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, t -> t.getValue().getTimeKeysAfter(time)));
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,46 @@ public Optional<TimeBasedValue<WeatherValue>> getWeather(ZonedDateTime date, Poi
}
}

@Override
public Map<Point, List<ZonedDateTime>> getTimeKeysAfter(ZonedDateTime time) {
try (InfluxDB session = connector.getSession()) {
String query = createQueryStringForTimeKeysAfter(time);
QueryResult queryResult = session.query(new Query(query));
Stream<Optional<TimeBasedValue<WeatherValue>>> optValues =
optTimeBasedValueStream(queryResult);
Set<TimeBasedValue<WeatherValue>> timeBasedValues =
filterEmptyOptionals(optValues).collect(Collectors.toSet());
Map<Point, Set<TimeBasedValue<WeatherValue>>> coordinateToValues =
timeBasedValues.stream()
.collect(
Collectors.groupingBy(
timeBasedWeatherValue -> timeBasedWeatherValue.getValue().getCoordinate(),
Collectors.toSet()));

return coordinateToValues.entrySet().stream()
.collect(
Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().stream().map(TimeBasedValue::getTime).sorted().toList()));
}
}

@Override
public List<ZonedDateTime> getTimeKeysAfter(ZonedDateTime time, Point coordinate) {
Optional<Integer> coordinateId = idCoordinateSource.getId(coordinate);
if (coordinateId.isEmpty()) {
return Collections.emptyList();
}
try (InfluxDB session = connector.getSession()) {
String query = createQueryStringForTimeKeysAfterWithCoordinate(time, coordinateId.get());
QueryResult queryResult = session.query(new Query(query));

return filterEmptyOptionals(optTimeBasedValueStream(queryResult))
.map(TimeBasedValue::getTime)
.toList();
}
}

/**
* Return the weather for the given time interval AND coordinate
*
Expand Down Expand Up @@ -214,6 +254,19 @@ private String createQueryStringForTimeInterval(ClosedInterval<ZonedDateTime> ti
return BASIC_QUERY_STRING + WHERE + createTimeConstraint(timeInterval);
}

private String createQueryStringForTimeKeysAfter(ZonedDateTime time) {
return BASIC_QUERY_STRING + WHERE + createTimeConstraintAfter(time);
staudtMarius marked this conversation as resolved.
Show resolved Hide resolved
}

private String createQueryStringForTimeKeysAfterWithCoordinate(
ZonedDateTime time, int coordinateId) {
return BASIC_QUERY_STRING
+ WHERE
+ createCoordinateConstraintString(coordinateId)
+ AND
+ createTimeConstraintAfter(time);
}

private String createTimeConstraint(ClosedInterval<ZonedDateTime> timeInterval) {
return weatherFactory.getTimeFieldString()
+ " >= "
Expand All @@ -230,6 +283,12 @@ private String createTimeConstraint(ZonedDateTime date) {
+ date.toInstant().toEpochMilli() * MILLI_TO_NANO_FACTOR;
}

private String createTimeConstraintAfter(ZonedDateTime time) {
return weatherFactory.getTimeFieldString()
+ " > "
+ time.toInstant().toEpochMilli() * MILLI_TO_NANO_FACTOR;
}

private String createCoordinateConstraintString(int coordinateId) {
return COORDINATE_ID_COLUMN_NAME + "='" + coordinateId + "'";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
private final String queryFull;

private final String queryTimeInterval;
private final String queryTimeKeysAfter;
private final String queryTime;

public SqlTimeSeriesSource(
Expand Down Expand Up @@ -82,6 +83,8 @@
this.queryFull = createQueryFull(sqlDataSource.schemaName, tableName);
this.queryTimeInterval =
createQueryForTimeInterval(sqlDataSource.schemaName, tableName, dbTimeColumnName);
this.queryTimeKeysAfter =
createQueryForTimeKeysAfter(sqlDataSource.schemaName, tableName, dbTimeColumnName);
this.queryTime = createQueryForTime(sqlDataSource.schemaName, tableName, dbTimeColumnName);
}

Expand Down Expand Up @@ -187,6 +190,14 @@
return Optional.of(timeBasedValues.stream().toList().get(0).getValue());
}

@Override
public List<ZonedDateTime> getTimeKeysAfter(ZonedDateTime time) {
Set<TimeBasedValue<V>> timeBasedValues =
getTimeBasedValueSet(
queryTimeKeysAfter, ps -> ps.setTimestamp(1, Timestamp.from(time.toInstant())));
return timeBasedValues.stream().map(TimeBasedValue::getTime).sorted().toList();
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

/** Creates a set of TimeBasedValues from database */
Expand Down Expand Up @@ -245,11 +256,33 @@
+ TIME_SERIES
+ " = '"
+ timeSeriesUuid.toString()
+ "' AND "

Check failure on line 259 in src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesSource.java

View check run for this annotation

SonarQubeGithubPRChecks / PowerSystemDataModel Sonarqube Results

src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesSource.java#L259

Define a constant instead of duplicating this literal "' AND " 3 times.
+ timeColumnName
+ " BETWEEN ? AND ?;";
}

/**
* Creates a base query to retrieve all entities for given time series uuid and in the given time
* frame with the following pattern: <br>
* {@code <base query> WHERE time_series = $timeSeriesUuid AND <time column> > ?;}
*
* @param schemaName the name of the database schema
* @param tableName the name of the database table
* @param timeColumnName the name of the column holding the timestamp info
* @return the query string
*/
private String createQueryForTimeKeysAfter(
String schemaName, String tableName, String timeColumnName) {
return createBaseQueryString(schemaName, tableName)
staudtMarius marked this conversation as resolved.
Show resolved Hide resolved
+ WHERE
+ TIME_SERIES
+ " = '"
+ timeSeriesUuid.toString()
+ "' AND "
+ timeColumnName
+ " > ?;";
}

/**
* Creates a basic query to retrieve an entry for the given time series uuid and time with the
* following pattern: <br>
Expand Down
Loading