Add dashboard for timeseries management - #446
Conversation
032dd8c to
3ef5d1b
Compare
715669f to
392c7a0
Compare
|
When testing the validation, I saw that the validation, if the length of the timeseries matches the length of the timesteps in the scenario/projects, is not working yet. That is due to the fact, that atm you cannot connect your timeseries to a scenario yet. Since the whole timeseries to scenario relation will be changed to a timeseries to project relation, the fixing of the length mismatch validation will wait until that is changed. Also there is the question of, if you wanna have timeseries that will not belong to any project or if every timeseries will need to have a project. Having timeseries without a project gives the advantage, that you should be able to use them in any project/scenario. In that case the length mismatch check will need to be adjusted. |
|
@CelinaKellinghaus @josihoppe looking good so far. I just had a look at the actual dash and have a few additional notes that came up:
|
0888c3c to
6e9e29a
Compare
|
@paulapreuss Similarly, for the tooltip/help text task: I switched |
| generation_parameters = models.JSONField( | ||
| blank=True, | ||
| null=True, | ||
| ) | ||
| description = models.TextField( | ||
| blank=True, | ||
| null=True, | ||
| ) |
There was a problem hiding this comment.
I cherry-picked these changes for #511, which is also still WIP. We will have to check where to keep the migrations depending on the merge order (just something to keep in mind).
| return HttpResponseRedirect(reverse("timeseries_dashboard")) | ||
|
|
||
| return HttpResponseRedirect(reverse("timeseries_dashboard")) |
There was a problem hiding this comment.
Here, you are redirecting the user back to timeseries_dashboard regardless of if the form is valid or not. If the form is not valid, the modal should not close but instead display the validation error message so that the user knows that something went wrong, like it does in the asset modals when building the scenario. This is a bit tricky because you have to dynamically update the form contents to display the error instead of reloading the page. You can check how it is done for the asset modals in grid_model_topology.js submitForm (starting from line 374)
There was a problem hiding this comment.
Same comment for timeseries_upload, needs to take data validation and feedback into account.
There was a problem hiding this comment.
I am still working on that redirecting and displaying the form errors, but should be working tomorrow
| if uploaded_file: | ||
| try: | ||
| parse_input_timeseries(uploaded_file) | ||
| uploaded_file.seek(0) | ||
| except (ValueError, TypeError) as e: | ||
| raise ValidationError(str(e)) | ||
| except Exception as e: | ||
| raise ValidationError(f"Could not parse uploaded file: {e}") | ||
|
|
||
| return uploaded_file |
There was a problem hiding this comment.
Good start, only that the validation error is currently not being passed to the user. Right now I'm able to upload any random file and simply be redirected back to the dashboard.
| existing_asset_types = ( | ||
| timeseries_qs.exclude(asset_type__isnull=True) | ||
| .values_list("asset_type", flat=True) | ||
| .distinct() | ||
| ) |
| <div class="small muted">Filter</div> | ||
| <form method="GET"> | ||
| <div style="display: flex; gap: 8px; align-items: center;"> | ||
| <select name="filter_type" class="form-select" onchange="toggleFilterValue(this.value)"> |
There was a problem hiding this comment.
I think the filter looks pretty nice, however I think that it still needs a bit of fine-tuning in terms of usability. Some things I noticed:
- It should be possible to filter by multiple options, e.g. to filter all PV timeseries from a specific project. Not sure what the nicest way to do this would be UI wise - in general I do like the current filtering box
- When clicking on a timeseries, the page resets and displays all timeseries again, also resetting the filtering options that we just set. This is an issue based on the fact that we currently reload the whole page when selecting any timeseries, when actually here we should be working with javascript to dynamically update the table contents and the timeseries details without refreshing (we probably need at least two functions to
fetchand replaceinnerHTMLof the table/details - the corresponding views would only return the JSON data to javascript instead of redirecting)
| ASSET_TYPE_TO_CATEGORY = { | ||
| "demand": "demand", | ||
| "gas_demand": "demand", | ||
| "h2_demand": "demand", | ||
| "heat_demand": "demand", | ||
| "pv_plant": "supply", | ||
| "wind_plant": "supply", | ||
| "biogas_plant": "supply", | ||
| "geothermal_conversion": "supply", | ||
| "solar_thermal_plant": "supply", | ||
| } |
There was a problem hiding this comment.
I think this is good, couldn't find any other place where this is already defined either :)
| existing_scenarios = ( | ||
| timeseries_qs.exclude(scenario__isnull=True) | ||
| .values_list("scenario_id", flat=True) | ||
| .distinct() | ||
| ) |
There was a problem hiding this comment.
I think for the scenario filter the option to select should display the scenario name (currently it displays the scenario number which is not that helpful). When applying the option to the filter, though, it probably makes more sense to pass the ID, so I would probably pass existing scenarios as tuples (id, name) to allow the user to select by name but internally use the ID for the filtering.
… template partials

Will (hopefully) close #403, close #401, close #331, close #332.
The current state is simply a frontend prototype to display what this dashboard could look like (a lot of this code will have to be deleted and replaced). Here are some of my thoughts on the things that need to be handled (alternative approaches of course are also okay):
Backend:
Timeseriesis used for a different scenario, a duplicate timeseries gets created, that means that a timeseries might have four duplicates (for each scenario) with the exact same values. It might be better to replace thescenariofield of the Timeseries withprojectand fill those withscenario.projecton the next migration (keeping only one Timeseries), which would get rid of the many duplicates. This would need a custom migration to handle the deletion and replacement of the field values - here we have to be really careful since we would be deleting production database objects. We still might have the issue of a user wanting to share a timeseries between different projects. The options here would be to handle it through aManyToManyfield instead of a strictForeignKey(aTimeseriescan be assigned to multipleProjects) or to simply have the user duplicate this timeseries for the other project (I think this is my preffered option, as this would also avoid issues if for example one project has a different number of timesteps than the other).Timeseriesclass also should get two new metadata fields: ageneration_parametersJSONField (stores the values used to create the timeseries, e.g. if a timeseries is created from an eesyplan method with a specific tilt/azimuth it can store these inputs in a JSON format), and adescriptionTextField where the user can freely add a description to their Timeseries. It was wished that this description would also be shown in the modal when selecting a timeseries on an asset.Frontend:
TimeseriesModelFormout of theTimeseriesclass and feed it to the existing modal template ({% include "modal_template.html" ... %})timeseries_inputdoes, and should make use of the validation pipeline that is already established thereeesyplanmethods should be accessible for creating Timeseries and which inputs they require.