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

Fix transmission #154

Merged
merged 5 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions ensysmod/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
energy_sinks,
energy_sources,
energy_storages,
energy_transmission_distances,
energy_transmission_losses,
energy_transmissions,
regions,
ts_capacity_fix,
Expand All @@ -31,6 +33,8 @@
api_router.include_router(energy_sources.router, prefix="/sources", tags=["Energy Sources"])
api_router.include_router(energy_storages.router, prefix="/storages", tags=["Energy Storages"])
api_router.include_router(energy_transmissions.router, prefix="/transmissions", tags=["Energy Transmissions"])
api_router.include_router(energy_transmission_distances.router, prefix="/distances", tags=["Energy Transmission Distances"])
api_router.include_router(energy_transmission_losses.router, prefix="/losses", tags=["Energy Transmission Losses"])
api_router.include_router(energy_models.router, prefix="/models", tags=["Energy Models"])

api_router.include_router(ts_capacity_fix.router, prefix="/fix-capacities", tags=["Fix Capacities"])
Expand Down
148 changes: 148 additions & 0 deletions ensysmod/api/endpoints/energy_transmission_distances.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
from typing import List, Optional

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from ensysmod import crud, model
from ensysmod.api import deps, permissions
from ensysmod.schemas import (
EnergyTransmissionDistance,
EnergyTransmissionDistanceCreate,
EnergyTransmissionDistanceUpdate,
)

router = APIRouter()


@router.get("/", response_model=List[EnergyTransmissionDistance])
def get_all_transmission_distances(
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
skip: int = 0,
limit: int = 100,
) -> List[EnergyTransmissionDistance]:
"""
Retrieve all transmission distances.
"""
return crud.energy_transmission_distance.get_multi(db=db, skip=skip, limit=limit)


@router.get("/{distance_id}", response_model=EnergyTransmissionDistance)
def get_transmission_distance(
distance_id: int,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
):
"""
Retrieve a transmission distance.
"""
# TODO Check if user has permission for dataset and EnergyTransmissionDistance
return crud.energy_transmission_distance.get(db=db, id=distance_id)


@router.get("/component/{component_id}", response_model=List[EnergyTransmissionDistance])
def get_transmission_distances_by_component(
component_id: int,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
) -> Optional[List[EnergyTransmissionDistance]]:
"""
Retrieve all transmission distances for a given component.
"""
# TODO Check if user has permission for dataset and EnergyTransmissionDistance
return crud.energy_transmission_distance.get_by_component(db=db, component_id=component_id)


@router.post("/", response_model=EnergyTransmissionDistance)
def create_transmission_distance(
request: EnergyTransmissionDistanceCreate,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
):
"""
Create a new transmission distance.
"""
dataset = crud.dataset.get(db=db, id=request.ref_dataset)
if dataset is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Dataset {request.ref_dataset} not found!")

permissions.check_modification_permission(db, user=current, dataset_id=dataset.id)

component = crud.energy_component.get_by_dataset_and_name(db=db, dataset_id=dataset.id, name=request.component)
if component is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=f"Component {request.component} not found in dataset {dataset.id}!"
)

region_from = crud.region.get_by_dataset_and_name(db=db, dataset_id=dataset.id, name=request.region_from)
if region_from is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Region {request.region_from} not found in dataset {dataset.id}!")

region_to = crud.region.get_by_dataset_and_name(db=db, dataset_id=dataset.id, name=request.region_to)
if region_to is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Region {request.region_to} not found in dataset {dataset.id}!")

distance_entry = crud.energy_transmission_distance.get_by_component_and_region_ids(
db=db,
component_id=component.id,
region_from_id=region_from.id,
region_to_id=region_to.id,
)
if distance_entry is not None:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail=f"EnergyTransmissionDistance for component {component.name} (id {component.id}) from region {region_from.name} (id {region_from.id}) to region {region_to.name} (id {region_to.id}) already exists with id {distance_entry.id}!", # noqa: E501
)

return crud.energy_transmission_distance.create(db=db, obj_in=request)


@router.put("/{distance_id}", response_model=EnergyTransmissionDistance)
def update_transmission_distance(
distance_id: int,
request: EnergyTransmissionDistanceUpdate,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
):
"""
Update a transmission distance.
"""
distance = crud.energy_transmission_distance.get(db=db, id=distance_id)
if distance is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"EnergyTransmissionDistance {distance_id} not found!")

Check warning on line 112 in ensysmod/api/endpoints/energy_transmission_distances.py

View check run for this annotation

Codecov / codecov/patch

ensysmod/api/endpoints/energy_transmission_distances.py#L112

Added line #L112 was not covered by tests

permissions.check_modification_permission(db, user=current, dataset_id=distance.transmission.component.ref_dataset)
return crud.energy_transmission_distance.update(db=db, db_obj=distance, obj_in=request)


@router.delete("/{distance_id}", response_model=EnergyTransmissionDistance)
def remove_transmission_distance(
distance_id: int,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
):
"""
Delete a transmission distance.
"""
distance = crud.energy_transmission_distance.get(db=db, id=distance_id)
if distance is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"EnergyTransmissionDistance {distance_id} not found!")

Check warning on line 129 in ensysmod/api/endpoints/energy_transmission_distances.py

View check run for this annotation

Codecov / codecov/patch

ensysmod/api/endpoints/energy_transmission_distances.py#L129

Added line #L129 was not covered by tests
permissions.check_modification_permission(db, user=current, dataset_id=distance.transmission.component.ref_dataset)
return crud.energy_transmission_distance.remove(db=db, id=distance_id)


@router.delete("/component/{component_id}", response_model=List[EnergyTransmissionDistance])
def remove_transmission_distances_by_component(
component_id: int,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
):
"""
Delete all transmission distances for a given component.
"""
distances = crud.energy_transmission_distance.get_by_component(db=db, component_id=component_id)
if distances is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"EnergyTransmissionDistance for component {component_id} not found!")

Check warning on line 145 in ensysmod/api/endpoints/energy_transmission_distances.py

View check run for this annotation

Codecov / codecov/patch

ensysmod/api/endpoints/energy_transmission_distances.py#L145

Added line #L145 was not covered by tests

# TODO Check if user has permission for dataset and EnergyTransmissionDistance
return crud.energy_transmission_distance.remove_by_component(db=db, component_id=component_id)
148 changes: 148 additions & 0 deletions ensysmod/api/endpoints/energy_transmission_losses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
from typing import List, Optional

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from ensysmod import crud, model
from ensysmod.api import deps, permissions
from ensysmod.schemas import (
EnergyTransmissionLoss,
EnergyTransmissionLossCreate,
EnergyTransmissionLossUpdate,
)

router = APIRouter()


@router.get("/", response_model=List[EnergyTransmissionLoss])
def get_all_transmission_losses(
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
skip: int = 0,
limit: int = 100,
) -> List[EnergyTransmissionLoss]:
"""
Retrieve all transmission losses.
"""
return crud.energy_transmission_loss.get_multi(db=db, skip=skip, limit=limit)


@router.get("/{loss_id}", response_model=EnergyTransmissionLoss)
def get_transmission_loss(
loss_id: int,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
):
"""
Retrieve a transmission loss.
"""
# TODO Check if user has permission for dataset and EnergyTransmissionLoss
return crud.energy_transmission_loss.get(db=db, id=loss_id)


@router.get("/component/{component_id}", response_model=List[EnergyTransmissionLoss])
def get_transmission_losses_by_component(
component_id: int,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
) -> Optional[List[EnergyTransmissionLoss]]:
"""
Retrieve all transmission losses for a given component.
"""
# TODO Check if user has permission for dataset and EnergyTransmissionLoss
return crud.energy_transmission_loss.get_by_component(db=db, component_id=component_id)


@router.post("/", response_model=EnergyTransmissionLoss)
def create_transmission_loss(
request: EnergyTransmissionLossCreate,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
):
"""
Create a new transmission loss.
"""
dataset = crud.dataset.get(db=db, id=request.ref_dataset)
if dataset is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Dataset {request.ref_dataset} not found!")

permissions.check_modification_permission(db, user=current, dataset_id=dataset.id)

component = crud.energy_component.get_by_dataset_and_name(db=db, dataset_id=dataset.id, name=request.component)
if component is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=f"Component {request.component} not found in dataset {dataset.id}!"
)

region_from = crud.region.get_by_dataset_and_name(db=db, dataset_id=dataset.id, name=request.region_from)
if region_from is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Region {request.region_from} not found in dataset {dataset.id}!")

region_to = crud.region.get_by_dataset_and_name(db=db, dataset_id=dataset.id, name=request.region_to)
if region_to is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Region {request.region_to} not found in dataset {dataset.id}!")

loss_entry = crud.energy_transmission_loss.get_by_component_and_region_ids(
db=db,
component_id=component.id,
region_from_id=region_from.id,
region_to_id=region_to.id,
)
if loss_entry is not None:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail=f"EnergyTransmissionLoss for component {component.name} (id {component.id}) from region {region_from.name} (id {region_from.id}) to region {region_to.name} (id {region_to.id}) already exists with id {loss_entry.id}!", # noqa: E501
)

return crud.energy_transmission_loss.create(db=db, obj_in=request)


@router.put("/{loss_id}", response_model=EnergyTransmissionLoss)
def update_transmission_loss(
loss_id: int,
request: EnergyTransmissionLossUpdate,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
):
"""
Update a transmission loss.
"""
loss = crud.energy_transmission_loss.get(db=db, id=loss_id)
if loss is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"EnergyTransmissionLoss {loss_id} not found!")

Check warning on line 112 in ensysmod/api/endpoints/energy_transmission_losses.py

View check run for this annotation

Codecov / codecov/patch

ensysmod/api/endpoints/energy_transmission_losses.py#L112

Added line #L112 was not covered by tests

permissions.check_modification_permission(db, user=current, dataset_id=loss.transmission.component.ref_dataset)
return crud.energy_transmission_loss.update(db=db, db_obj=loss, obj_in=request)


@router.delete("/{loss_id}", response_model=EnergyTransmissionLoss)
def remove_transmission_loss(
loss_id: int,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
):
"""
Delete a transmission loss.
"""
loss = crud.energy_transmission_loss.get(db=db, id=loss_id)
if loss is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"EnergyTransmissionLoss {loss_id} not found!")

Check warning on line 129 in ensysmod/api/endpoints/energy_transmission_losses.py

View check run for this annotation

Codecov / codecov/patch

ensysmod/api/endpoints/energy_transmission_losses.py#L129

Added line #L129 was not covered by tests
permissions.check_modification_permission(db, user=current, dataset_id=loss.transmission.component.ref_dataset)
return crud.energy_transmission_loss.remove(db=db, id=loss_id)


@router.delete("/component/{component_id}", response_model=List[EnergyTransmissionLoss])
def remove_transmission_losses_by_component(
component_id: int,
db: Session = Depends(deps.get_db),
current: model.User = Depends(deps.get_current_user),
):
"""
Delete all transmission losses for a given component.
"""
losses = crud.energy_transmission_loss.get_by_component(db=db, component_id=component_id)
if losses is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"EnergyTransmissionLoss for component {component_id} not found!")

Check warning on line 145 in ensysmod/api/endpoints/energy_transmission_losses.py

View check run for this annotation

Codecov / codecov/patch

ensysmod/api/endpoints/energy_transmission_losses.py#L145

Added line #L145 was not covered by tests

# TODO Check if user has permission for dataset and EnergyTransmissionLoss
return crud.energy_transmission_loss.remove_by_component(db=db, component_id=component_id)
14 changes: 6 additions & 8 deletions ensysmod/core/file_download.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import json
import os
import zipfile
from typing import Any, Type, Set, Dict, List
from typing import Any, Dict, List, Set, Type

import json
from pydantic import BaseModel
from sqlalchemy.orm import Session

Expand Down Expand Up @@ -115,14 +115,12 @@ def dump_energy_components(db: Session, dataset_id: int, temp_folder: str, crud_
# dump excel files
dump_excel_file(db, obj.ref_component, region_ids, crud.capacity_fix, f"{obj_folder}/capacityFix.xlsx")
dump_excel_file(db, obj.ref_component, region_ids, crud.capacity_max, f"{obj_folder}/capacityMax.xlsx")
dump_excel_file(db, obj.ref_component, region_ids, crud.operation_rate_fix,
f"{obj_folder}/operationRateFix.xlsx")
dump_excel_file(db, obj.ref_component, region_ids, crud.operation_rate_max,
f"{obj_folder}/operationRateMax.xlsx")
dump_excel_file(db, obj.ref_component, region_ids, crud.operation_rate_fix, f"{obj_folder}/operationRateFix.xlsx")
dump_excel_file(db, obj.ref_component, region_ids, crud.operation_rate_max, f"{obj_folder}/operationRateMax.xlsx")

if file_name == "transmission":
crud.energy_transmission_distance.get_dataframe(db, obj.ref_component, region_ids) \
.to_excel(f"{obj_folder}/distances.xlsx")
crud.energy_transmission_distance.get_dataframe(db, obj.ref_component, region_ids).to_excel(f"{obj_folder}/distances.xlsx")
crud.energy_transmission_loss.get_dataframe(db, obj.ref_component, region_ids).to_excel(f"{obj_folder}/losses.xlsx")


def dump_json(file: str, fields: Set[str], obj: Any):
Expand Down
Loading
Loading