diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ef1d290..3abd7d730 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Adding timeseries for voltage values [#1128](https://github.com/ie3-institute/PowerSystemDataModel/issues/1128) - Added Staudt to list of reviewers [#1190](https://github.com/ie3-institute/PowerSystemDataModel/issues/1190) - Extend ValidationUtils for validating ThermalGrids [#1216](https://github.com/ie3-institute/PowerSystemDataModel/issues/1216) +- Enhance `TimeSeriesSource` with method to retrieve the previous value before a given key [#1182](https://github.com/ie3-institute/PowerSystemDataModel/issues/1182) ### Fixed - Removing opened `SwitchInput` during connectivity check [#1221](https://github.com/ie3-institute/PowerSystemDataModel/issues/1221) diff --git a/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesSource.java b/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesSource.java index a9ade054e..2a80e0a78 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesSource.java @@ -50,7 +50,9 @@ protected Try, FactoryException> createTimeBasedValue( public abstract IndividualTimeSeries getTimeSeries(ClosedInterval timeInterval) throws SourceException; - public abstract Optional getValue(ZonedDateTime time) throws SourceException; + public abstract Optional getValue(ZonedDateTime time); + + public abstract Optional> getPreviousTimeBasedValue(ZonedDateTime time); /** * Method to return all time keys after a given timestamp. diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java index 1bbab427a..0210b7dde 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java @@ -128,6 +128,15 @@ public Optional getValue(ZonedDateTime time) { return timeSeries.getValue(time); } + @Override + public Optional> getPreviousTimeBasedValue(ZonedDateTime time) { + return timeSeries.getPreviousTimeBasedValue(time); + } + + public Optional> getNextTimeBasedValue(ZonedDateTime time) { + return timeSeries.getNextTimeBasedValue(time); + } + @Override public List getTimeKeysAfter(ZonedDateTime time) { return timeSeries.getTimeKeysAfter(time); diff --git a/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesSource.java b/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesSource.java index c75e8b949..7016feb5d 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesSource.java @@ -48,6 +48,7 @@ public class SqlTimeSeriesSource extends TimeSeriesSource { private final String queryTimeInterval; private final String queryTimeKeysAfter; + private final String queryForValueBefore; private final String queryTime; public SqlTimeSeriesSource( @@ -63,15 +64,16 @@ public SqlTimeSeriesSource( final ColumnScheme columnScheme = ColumnScheme.parse(valueClass).orElseThrow(); this.tableName = sqlDataSource.databaseNamingStrategy.getTimeSeriesEntityName(columnScheme); + String schemaName = sqlDataSource.schemaName; + String dbTimeColumnName = sqlDataSource.getDbColumnName(factory.getTimeFieldString(), tableName); - 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); + this.queryFull = createQueryFull(schemaName, tableName); + this.queryTimeInterval = createQueryForTimeInterval(schemaName, tableName, dbTimeColumnName); + this.queryTimeKeysAfter = createQueryForTimeKeysAfter(schemaName, tableName, dbTimeColumnName); + this.queryForValueBefore = createQueryForValueBefore(schemaName, tableName, dbTimeColumnName); + this.queryTime = createQueryForTime(schemaName, tableName, dbTimeColumnName); } /** @@ -179,6 +181,14 @@ public Optional getValue(ZonedDateTime time) { return Optional.of(timeBasedValues.stream().toList().get(0).getValue()); } + @Override + public Optional> getPreviousTimeBasedValue(ZonedDateTime time) { + return getTimeBasedValueSet( + queryForValueBefore, ps -> ps.setTimestamp(1, Timestamp.from(time.toInstant()))) + .stream() + .max(TimeBasedValue::compareTo); + } + @Override public List getTimeKeysAfter(ZonedDateTime time) { return dataSource @@ -278,8 +288,30 @@ private String createQueryForTimeKeysAfter( } /** - * Creates a basic query to retrieve an entry for the given time series uuid and time with the - * following pattern:
+ * Creates a base query to retrieve all time keys after a given time for given time series with + * the following pattern:
+ * {@code WHERE time_series = $timeSeriesUuid AND