Introduce new component from eesyplan#492
Conversation
Inherting from Asset might be preferable, as the class remain a child of Asset, one can always use Asset.objects.filter(asset_type=...)
The ModelForm is instanciated with a Meta class referring to the specific asset model if differing from Asset. Currently problems remain at the export to datapackage and export scenarios
b3b2e5d to
fd1cf09
Compare
|
Now export of the scenario produces an error but only when the scenario is reimported and the special component clicked |
The new asset specific fields are successfully exported
| com = Commodity(asset_type=at, scenario=scen, full_load_hours_max=30) | ||
| com.save() | ||
| print(com.to_datapackage()) | ||
| pdb.set_trace() |
There was a problem hiding this comment.
Remove before merge (linter is already flagging this anyway so shouldn't be a problem)
There was a problem hiding this comment.
I would remove the whole file before merge, this is just for testing
| asset_type = ASSET_MAPPING.get(self.asset_type.asset_type, Asset) | ||
| existing_asset = get_object_or_404(asset_type, unique_id=self.unique_id) | ||
|
|
There was a problem hiding this comment.
Why do we need to do this lookup for the asset within the model class? isn't existing_asset just self?
There was a problem hiding this comment.
Ah, is this because Commodity is not treated as an Asset but as a separate class?
There was a problem hiding this comment.
If we use self within the Asset's methods, then self is of type Asset and I had the problem that I couldn't list the extra attributes
| # 2) add an asset_type for this new component with their visible fields (under static/resources/assettypes_list.csv) | ||
|
|
||
|
|
||
| class Commodity(Asset): |
There was a problem hiding this comment.
I do like having the new component inherit from Asset rather than having a very bloated Asset class
|
|
||
|
|
||
| def get_asset_or_404(asset_type, asset_uuid): | ||
| asset_type = ASSET_MAPPING.get(asset_type, Asset) |
There was a problem hiding this comment.
| asset_type = ASSET_MAPPING.get(asset_type, Asset) | |
| asset_model = ASSET_MAPPING.get(asset_type, Asset) |
I would rename this to match the variable name also used in asset_form_factory
| widget=forms.HiddenInput(), required=False, label="" | ||
| ) | ||
|
|
||
| if self.asset_type_name == "heat_pump": |
There was a problem hiding this comment.
Ideally if we split the assets into their own models it would be good to also handle these special cases within the asset models. Or if the parameters have different names anyway depending on the asset (coming from the eesyplan naming), could also be handled through the general widget definition.
There was a problem hiding this comment.
We would not need to handle this as special cases because here we are overloading "efficiency" and using it as many different things. If we simply inheritate from Asset, then we write cop as attribute of the heat pump and do not need this whole if statement block :)
| return _AssetCreateForm(asset_type=asset_type, **kwargs) | ||
|
|
||
|
|
||
| class AssetCreateForm(OpenPlanModelForm): |
There was a problem hiding this comment.
Delete if keeping the form factory
There was a problem hiding this comment.
This is just work in progress because of the nightmare StorageAssetForm which inherit from AssetForm. Hopefully we can get rid of the complicated StorageAsset with eesyplan :)
| hess,energy_storage,Heat,storage,[name],kW (therm),"{'input_1':['bus_in_heat','Heat'],'output_1': ['bus_out_heat','Heat']}" | ||
| chp,energy_conversion,Electricity,extractionTurbineCHP,"[name,age_installed,installed_capacity,capex_fix,capex_var,opex_var,opex_fix,lifetime,optimize_cap,maximum_capacity,efficiency_multiple,efficiency,thermal_loss_rate]",kW,"{'input_1':['bus_in_fuel','Gas'],'output_1': ['bus_out_heat','Heat'], 'output_2': ['bus_out_electricity','Electricity']}" | ||
| chp_fixed_ratio,energy_conversion,Electricity,transformer,"[name,age_installed,installed_capacity,capex_var,opex_fix,lifetime,optimize_cap,maximum_capacity,efficiency_multiple,efficiency]",kW,"{'input_1':['bus_in_fuel','Gas'],'output_1': ['bus_out_heat','Heat'], 'output_2': ['bus_out_electricity','Electricity']}" | ||
| commodity,energy_production,Electricity,source,"[name,installed_capacity,capex_var,commodity_type,full_load_hours_max,full_load_hours_max_asset]",kW,"{'output_1': ['bus_out_electricity','Electricity']}" |
There was a problem hiding this comment.
How do we want to handle the commodity bus? Maybe we can just use the fuel bus for now?
There was a problem hiding this comment.
This is why I started to implement the commodity. A quick solution is to do the same as with the busses in OpenPlan: we get 4 busses to choose from and we could get 4 commodities to choose from.
And not always the default Asset class
Only the asset count of a given asset_type is relevant here
At those occasion it might be needed to make sure the classes inheriting from Asset appear in the listing explicitely and not simply as Asset instances.
PROTOCOL (option a or b)
a) write a new class which inherits from Asset with the new needed fields
b) add the fields within the Asset class
add an asset_type for this new component with their visible fields (under static/resources/assettypes_list.csv)
add the asset to the drag and drop within the
projects/views.py::scenario_create_topologyfunction. Right at the beginning there is a dict namedcomponentswith asset_type as keys and the verbose name as Valueprovide an icon for this component in
static/asset/gui, its name must be<asset_type>.svg, like "commodity.svg" for example. You then need to add a mapping "<asset_type>:<asset_type>," within$component-categories-mappingin thestatic/scss/abstracts/_variables.scssAt this stage the component will be visible within the GUI and can be dragged to the energy system. However option a) doesn't provide out of the box access to the component's fields, whereas option b) does.
To change this one need to be able to set the
modelattribute of the Meta class to something else than Asset (ie a decorator function which would find the new asset's Model from a dict and return a CreateAssetForm instance with modifiedMetaAfter internal disscussion and testing option a) seems the most long term beneficial, as it will make the components much more aligned on eesyplan structure. This PR already made the structural changes necessary for:
Here is a list of the components which need to have their own Model (inheriting Asset class)
There is also the storage components (hess, h2ss, bess, gess), but the migration might be a bit more complex as they had a structure with a parent asset and 3 children assets
One need to look over clean() method from
AssetCreateFormin forms.py to remove code which will not be necessary there anymore. Idem for theto_datapackage()method af theAssetclass It will break the dto.py classes but this is only used for MVS and will be removed in the future.Also look into
widgetsattribute of the Meta class attribute of theAssetCreateFormNeed to migrate the Storage into an eesyplan storage (this might require quite some preparation?)