Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
529bf23
Testing method
PhilippSchmelter Aug 27, 2024
f72bb75
Fixed format
PhilippSchmelter Aug 27, 2024
9447e8b
Fixed format
PhilippSchmelter Aug 27, 2024
e0828af
Fixed Test
PhilippSchmelter Aug 27, 2024
6c4c0f8
Revert "Testing method"
PhilippSchmelter Aug 27, 2024
7502d97
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Sep 4, 2024
743e99a
Testing NoWeatherDataException
PhilippSchmelter Sep 4, 2024
74f4816
Handled NoWeatherData in for CSV Source
PhilippSchmelter Sep 4, 2024
8e8bed0
Handled NoWeatherData in for CSV Source
PhilippSchmelter Sep 4, 2024
21a05a3
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Sep 11, 2024
e0bcfb6
Adapted exception throwing for getWeather() which returns optional an…
PhilippSchmelter Sep 11, 2024
cee6660
Started adding NoDataException for SQL source
PhilippSchmelter Sep 14, 2024
8ed3f29
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Sep 14, 2024
f7a21d4
Spotless Applied
PhilippSchmelter Sep 14, 2024
646eaa8
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Sep 25, 2024
e666ea0
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Sep 30, 2024
171610b
Removed all occurences of Optional return type for getWeather() methods
PhilippSchmelter Sep 30, 2024
08a2679
spotless
PhilippSchmelter Sep 30, 2024
2a4d3b7
fixed tests
PhilippSchmelter Sep 30, 2024
7d449ee
Adapted SourceIconIT tests
PhilippSchmelter Sep 30, 2024
c83ca93
Fixed tests
PhilippSchmelter Sep 30, 2024
34d78aa
Fixed tests
PhilippSchmelter Sep 30, 2024
19d5c3b
Spotless Apply
PhilippSchmelter Sep 30, 2024
ad8946f
Final
PhilippSchmelter Sep 30, 2024
e1ec1db
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Oct 1, 2024
703e581
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Oct 16, 2024
cd5354d
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Oct 24, 2024
6723cba
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Nov 5, 2024
23b732f
Resolved Conversations
PhilippSchmelter Nov 5, 2024
88e1ec7
Fixed Tests
PhilippSchmelter Nov 5, 2024
cc9e1a0
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Nov 14, 2024
60ef7f5
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Nov 20, 2024
57ca9ab
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Nov 21, 2024
69838ed
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Jan 30, 2025
a8f892d
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Feb 4, 2025
01146b9
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Feb 12, 2025
955239e
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Mar 1, 2025
faa36cf
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Mar 9, 2025
22ca7f6
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
danielfeismann Jul 23, 2025
24441c9
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
danielfeismann Aug 8, 2025
8c2d1f7
Resolved Conversations
PhilippSchmelter Aug 20, 2025
9915bee
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Aug 20, 2025
5dc0f4a
spotless
PhilippSchmelter Aug 20, 2025
b9d747f
Merge remote-tracking branch 'origin/ps/#554-HandlingNoWeatherData' i…
PhilippSchmelter Aug 20, 2025
68ea181
improvements
PhilippSchmelter Aug 20, 2025
c2117e2
spotless
PhilippSchmelter Aug 20, 2025
b8ff373
fixed tests
PhilippSchmelter Aug 20, 2025
35a497d
spotless
PhilippSchmelter Aug 20, 2025
3951355
tests
PhilippSchmelter Aug 20, 2025
24ff4b5
added exception to couchbase tests
PhilippSchmelter Aug 20, 2025
e8a4fee
some fixes
PhilippSchmelter Aug 20, 2025
5cc104b
some fixes
PhilippSchmelter Aug 20, 2025
9f97b00
no more missing data
PhilippSchmelter Aug 20, 2025
4be6590
edited exception
PhilippSchmelter Aug 20, 2025
f20db54
bugfix
PhilippSchmelter Aug 20, 2025
fd0823b
fx
PhilippSchmelter Aug 21, 2025
ef08123
redundant log removed
PhilippSchmelter Aug 21, 2025
cf8adb3
hopefully final
PhilippSchmelter Aug 21, 2025
701d7e2
spotless
PhilippSchmelter Aug 21, 2025
b5d2ccf
more information
PhilippSchmelter Aug 21, 2025
dfb49df
fix
PhilippSchmelter Aug 21, 2025
c75b9fa
aa
PhilippSchmelter Aug 21, 2025
dc35434
Revert "redundant log removed"
PhilippSchmelter Aug 21, 2025
24e8d3f
Merge remote-tracking branch 'origin/ps/#554-HandlingNoWeatherData' i…
PhilippSchmelter Aug 21, 2025
0800310
Revert "fx"
PhilippSchmelter Aug 21, 2025
a2911b0
sql
PhilippSchmelter Aug 21, 2025
ce294c5
couchbaase
PhilippSchmelter Aug 21, 2025
c38e7a5
hopefully final
PhilippSchmelter Aug 26, 2025
3ebda49
bug
PhilippSchmelter Aug 26, 2025
bdd0ae8
Strict fail-fast on partial results
PhilippSchmelter Aug 27, 2025
7f6a59c
Revert "Strict fail-fast on partial results"
PhilippSchmelter Aug 27, 2025
183e0c8
little improvement
PhilippSchmelter Aug 27, 2025
bf86b78
removed unnecessary info from exception
PhilippSchmelter Aug 27, 2025
67000bd
spotless...
PhilippSchmelter Aug 27, 2025
1be0b8e
removed unnecessary test
PhilippSchmelter Aug 27, 2025
4b81cd1
Merge branch 'dev' into ps/#554-HandlingNoWeatherData
PhilippSchmelter Aug 29, 2025
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
3 changes: 2 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ Main Contributers:
- Johannes Bao - https://github.com/jo-bao
- Julian Hohmann - https://github.com/julianhohmann
- Simon Huette - https://github.com/SimonHuette
- Pierre Petersmeier - http://github.com/pierrepetersmeier
- Pierre Petersmeier - https://github.com/pierrepetersmeier
- Philipp Schmelter - https://github.com/PhilippSchmelter
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- 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)
- Added explicit handling for cases where no weather data is received from any source [#554](https://github.com/ie3-institute/PowerSystemDataModel/issues/554)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to the end of this subsection

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to move this to the Unreleased/Snapshot section

- 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)
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/edu/ie3/datamodel/exceptions/NoDataException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* © 2024. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.exceptions;

/**
* Exception that should be used whenever no data is received{@link
* edu.ie3.datamodel.io.source.DataSource}
*/
public class NoDataException extends Exception {

public NoDataException(final String message) {
super(message);
}

public NoDataException(final String message, final Throwable cause) {
super(message, cause);
}
}
9 changes: 5 additions & 4 deletions src/main/java/edu/ie3/datamodel/io/source/WeatherSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
package edu.ie3.datamodel.io.source;

import edu.ie3.datamodel.exceptions.NoDataException;
import edu.ie3.datamodel.exceptions.SourceException;
import edu.ie3.datamodel.exceptions.ValidationException;
import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueData;
Expand Down Expand Up @@ -55,14 +56,14 @@ public void validate() throws ValidationException {
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

public abstract Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
ClosedInterval<ZonedDateTime> timeInterval) throws SourceException;
ClosedInterval<ZonedDateTime> timeInterval) throws SourceException, NoDataException;

public abstract Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
ClosedInterval<ZonedDateTime> timeInterval, Collection<Point> coordinates)
throws SourceException;
throws SourceException, NoDataException;

public abstract Optional<TimeBasedValue<WeatherValue>> getWeather(
ZonedDateTime date, Point coordinate) throws SourceException;
public abstract TimeBasedValue<WeatherValue> getWeather(ZonedDateTime date, Point coordinate)
throws SourceException, NoDataException;

public abstract Map<Point, List<ZonedDateTime>> getTimeKeysAfter(ZonedDateTime time)
throws SourceException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.couchbase.client.java.json.JsonObject;
import com.couchbase.client.java.kv.GetResult;
import com.couchbase.client.java.query.QueryResult;
import edu.ie3.datamodel.exceptions.NoDataException;
import edu.ie3.datamodel.io.connectors.CouchbaseConnector;
import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueData;
import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueFactory;
Expand Down Expand Up @@ -105,7 +106,7 @@ public Optional<Set<String>> getSourceFields() {

@Override
public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
ClosedInterval<ZonedDateTime> timeInterval) {
ClosedInterval<ZonedDateTime> timeInterval) throws NoDataException {
logger.warn(
"By not providing coordinates you are forcing couchbase to check all possible coordinates one by one."
+ " This is not very performant. Please consider providing specific coordinates instead.");
Expand All @@ -114,7 +115,18 @@ public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(

@Override
public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
ClosedInterval<ZonedDateTime> timeInterval, Collection<Point> coordinates) {
ClosedInterval<ZonedDateTime> timeInterval, Collection<Point> coordinates)
throws NoDataException {

List<Point> invalidCoordinates =
coordinates.stream()
.filter(coordinate -> idCoordinateSource.getId(coordinate).isEmpty())
.toList();

if (!invalidCoordinates.isEmpty()) {
throw new NoDataException("No data for given coordinates: " + invalidCoordinates);
}
Comment on lines +126 to +128
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I think there's a way to heal this instead of breaking right away.
I'd say, if for a coordinate we cannot retrieve weather data, we try to provide the last available data (the available data for the last point in time before now) first. In this case, we also log a warning.
If that also fails though, we should throw an exception.


HashMap<Point, IndividualTimeSeries<WeatherValue>> coordinateToTimeSeries = new HashMap<>();
for (Point coordinate : coordinates) {
Optional<Integer> coordinateId = idCoordinateSource.getId(coordinate);
Expand All @@ -126,7 +138,8 @@ public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
try {
jsonWeatherInputs = queryResult.rowsAsObject();
} catch (DecodingFailureException ex) {
logger.error("Querying weather inputs failed!", ex);
throw new NoDataException(
"Failed to decode weather data for coordinate " + coordinate, ex);
}
if (jsonWeatherInputs != null && !jsonWeatherInputs.isEmpty()) {
Set<TimeBasedValue<WeatherValue>> weatherInputs =
Expand All @@ -138,32 +151,52 @@ public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
new IndividualTimeSeries<>(weatherInputs);
coordinateToTimeSeries.put(coordinate, weatherTimeSeries);
}
} else logger.warn("Unable to match coordinate {} to a coordinate ID", coordinate);
}
}
return coordinateToTimeSeries;
}

@Override
public Optional<TimeBasedValue<WeatherValue>> getWeather(ZonedDateTime date, Point coordinate) {
public TimeBasedValue<WeatherValue> getWeather(ZonedDateTime date, Point coordinate)
throws NoDataException {
Optional<Integer> coordinateId = idCoordinateSource.getId(coordinate);
if (coordinateId.isEmpty()) {
logger.warn("Unable to match coordinate {} to a coordinate ID", coordinate);
return Optional.empty();
logger.error("Unable to match coordinate {} to a coordinate ID", coordinate);
throw new NoDataException("No coordinate ID found for the given point: " + coordinate);
Comment on lines +164 to +165
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging an error is obsolete when we also throw and exception in the next line, imho

}
try {
CompletableFuture<GetResult> futureResult =
connector.get(generateWeatherKey(date, coordinateId.get()));
GetResult getResult = futureResult.join();
JsonObject jsonWeatherInput = getResult.contentAsObject();
return toTimeBasedWeatherValue(jsonWeatherInput);
return toTimeBasedWeatherValue(jsonWeatherInput)
.orElseThrow(
() ->
new NoDataException(
"No valid weather data found for the given date and coordinate."));
Comment on lines +175 to +176
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: Maybe try to take an earlier data point instead?

} catch (DecodingFailureException ex) {
logger.error("Decoding to TimeBasedWeatherValue failed!", ex);
return Optional.empty();
throw new NoDataException(
"Failed to decode weather data for coordinate " + coordinate + " and date " + date, ex);
} catch (DocumentNotFoundException ex) {
return Optional.empty();
throw new NoDataException(
"Weather document not found for coordinate " + coordinate + " and date " + date, ex);
} catch (CompletionException ex) {
if (ex.getCause() instanceof DocumentNotFoundException) return Optional.empty();
else throw ex;
Throwable cause = ex.getCause();
if (cause instanceof DocumentNotFoundException) {
throw new NoDataException(
"Weather document not found in completion stage for coordinate "
+ coordinate
+ " and date "
+ date,
cause);
} else {
throw new NoDataException(
"Unexpected completion exception while retrieving weather data for coordinate "
+ coordinate
+ " and date "
+ date,
ex);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static edu.ie3.datamodel.utils.validation.UniquenessValidationUtils.checkWeatherUniqueness;

import edu.ie3.datamodel.exceptions.DuplicateEntitiesException;
import edu.ie3.datamodel.exceptions.NoDataException;
import edu.ie3.datamodel.exceptions.SourceException;
import edu.ie3.datamodel.exceptions.ValidationException;
import edu.ie3.datamodel.io.connectors.CsvFileConnector;
Expand Down Expand Up @@ -90,25 +91,63 @@ public Optional<Set<String>> getSourceFields() {

@Override
public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
ClosedInterval<ZonedDateTime> timeInterval) {
return trimMapToInterval(coordinateToTimeSeries, timeInterval);
ClosedInterval<ZonedDateTime> timeInterval) throws NoDataException {

Map<Point, IndividualTimeSeries<WeatherValue>> result =
trimMapToInterval(coordinateToTimeSeries, timeInterval);

if (result == null || result.isEmpty()) {
throw new NoDataException(
"No weather data found for the given time interval: " + timeInterval);
}

return result;
}

@Override
public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
ClosedInterval<ZonedDateTime> timeInterval, Collection<Point> coordinates) {
ClosedInterval<ZonedDateTime> timeInterval, Collection<Point> coordinates)
throws NoDataException {

List<Point> invalidCoordinates =
coordinates.stream()
.filter(coordinate -> !coordinateToTimeSeries.containsKey(coordinate))
.toList();

if (!invalidCoordinates.isEmpty()) {
throw new NoDataException("No data for given coordinates: " + invalidCoordinates);
}
Comment on lines +117 to +119
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above


Map<Point, IndividualTimeSeries<WeatherValue>> filteredMap =
coordinateToTimeSeries.entrySet().stream()
.filter(entry -> coordinates.contains(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return trimMapToInterval(filteredMap, timeInterval);

Map<Point, IndividualTimeSeries<WeatherValue>> result =
trimMapToInterval(filteredMap, timeInterval);

if (result == null || result.isEmpty()) {
throw new NoDataException(
"No weather data found for the given time interval: " + timeInterval);
}
return result;
}

@Override
public Optional<TimeBasedValue<WeatherValue>> getWeather(ZonedDateTime date, Point coordinate) {
public TimeBasedValue<WeatherValue> getWeather(ZonedDateTime date, Point coordinate)
throws NoDataException {
IndividualTimeSeries<WeatherValue> timeSeries = coordinateToTimeSeries.get(coordinate);
if (timeSeries == null) return Optional.empty();
return timeSeries.getTimeBasedValue(date);

if (timeSeries == null) {
throw new NoDataException("No weather data found for the given coordinate: " + coordinate);
}

return timeSeries
.getTimeBasedValue(date)
.orElseThrow(
() ->
new NoDataException(
"No weather data found for the given coordinate: " + coordinate));
Comment on lines +149 to +150
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
package edu.ie3.datamodel.io.source.influxdb;

import edu.ie3.datamodel.exceptions.NoDataException;
import edu.ie3.datamodel.io.connectors.InfluxDbConnector;
import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueData;
import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueFactory;
Expand Down Expand Up @@ -59,14 +60,18 @@ public Optional<Set<String>> getSourceFields() {

@Override
public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
ClosedInterval<ZonedDateTime> timeInterval) {
ClosedInterval<ZonedDateTime> timeInterval) throws NoDataException {
try (InfluxDB session = connector.getSession()) {
String query = createQueryStringForTimeInterval(timeInterval);
QueryResult queryResult = session.query(new Query(query));
Stream<Optional<TimeBasedValue<WeatherValue>>> optValues =
optTimeBasedValueStream(queryResult);
Set<TimeBasedValue<WeatherValue>> timeBasedValues =
filterEmptyOptionals(optValues).collect(Collectors.toSet());
if (timeBasedValues.isEmpty()) {
throw new NoDataException(
"No weather data found for the given time interval: " + timeInterval);
}
Map<Point, Set<TimeBasedValue<WeatherValue>>> coordinateToValues =
timeBasedValues.stream()
.collect(
Expand All @@ -81,10 +86,22 @@ public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(

@Override
public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
ClosedInterval<ZonedDateTime> timeInterval, Collection<Point> coordinates) {
ClosedInterval<ZonedDateTime> timeInterval, Collection<Point> coordinates)
throws NoDataException {
if (coordinates == null) return getWeather(timeInterval);
Map<Point, Optional<Integer>> coordinatesToId =
coordinates.stream().collect(Collectors.toMap(point -> point, idCoordinateSource::getId));

List<Point> invalidCoordinates =
coordinatesToId.entrySet().stream()
.filter(entry -> entry.getValue().isEmpty())
.map(Map.Entry::getKey)
.toList();

if (!invalidCoordinates.isEmpty()) {
throw new NoDataException("No data for given coordinates: " + invalidCoordinates);
}

HashMap<Point, IndividualTimeSeries<WeatherValue>> coordinateToTimeSeries = new HashMap<>();
try (InfluxDB session = connector.getSession()) {
for (Map.Entry<Point, Optional<Integer>> entry : coordinatesToId.entrySet()) {
Expand All @@ -97,25 +114,37 @@ public Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
optTimeBasedValueStream(queryResult);
Set<TimeBasedValue<WeatherValue>> timeBasedValues =
filterEmptyOptionals(optValues).collect(Collectors.toSet());
IndividualTimeSeries<WeatherValue> timeSeries =
new IndividualTimeSeries<>(timeBasedValues);
coordinateToTimeSeries.put(entry.getKey(), timeSeries);
if (!timeBasedValues.isEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it also lead to an exception in case timeBasedValues is empty, since one could assume we would expect weather data when asking for it and those aren't there? Not sure about this, I might have to rethink on this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, testing this would also be great.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested throwing an exception when timeBasedValues is empty, but that broke existing behavior and tests. For now we keep it simple: invalid coordinates throw a NoDataException, but valid coordinates with no data just return an empty series. Or do we really want it that strict? If so we could use my last commit which I reverted again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be great to have equivalent behavior across types of data sources, at least where it's possible

IndividualTimeSeries<WeatherValue> timeSeries =
new IndividualTimeSeries<>(timeBasedValues);
coordinateToTimeSeries.put(entry.getKey(), timeSeries);
}
}
}
}
return coordinateToTimeSeries;
}

@Override
public Optional<TimeBasedValue<WeatherValue>> getWeather(ZonedDateTime date, Point coordinate) {
public TimeBasedValue<WeatherValue> getWeather(ZonedDateTime date, Point coordinate)
throws NoDataException {
Optional<Integer> coordinateId = idCoordinateSource.getId(coordinate);
if (coordinateId.isEmpty()) {
return Optional.empty();
throw new NoDataException("No coordinate ID found for the given point: " + coordinate);
}

try (InfluxDB session = connector.getSession()) {
String query = createQueryStringForCoordinateAndTime(date, coordinateId.get());
QueryResult queryResult = session.query(new Query(query));
return filterEmptyOptionals(optTimeBasedValueStream(queryResult)).findFirst();
return filterEmptyOptionals(optTimeBasedValueStream(queryResult))
.findFirst()
.orElseThrow(
() ->
new NoDataException(
"No weather data available for the given date "
+ date
+ " and coordinate "
+ coordinate));
}
}

Expand Down Expand Up @@ -167,10 +196,10 @@ public List<ZonedDateTime> getTimeKeysAfter(ZonedDateTime time, Point coordinate
* @return weather data for the specified time and coordinate
*/
public IndividualTimeSeries<WeatherValue> getWeather(
ClosedInterval<ZonedDateTime> timeInterval, Point coordinate) {
ClosedInterval<ZonedDateTime> timeInterval, Point coordinate) throws NoDataException {
Optional<Integer> coordinateId = idCoordinateSource.getId(coordinate);
if (coordinateId.isEmpty()) {
return new IndividualTimeSeries<>(UUID.randomUUID(), Collections.emptySet());
throw new NoDataException("No data for given coordinates: " + coordinate);
}
try (InfluxDB session = connector.getSession()) {
String query =
Expand Down
Loading