|
|
|
@ -9,6 +9,7 @@ from temporalio.client import Client
|
|
|
|
from src.aeros_contribution.service import update_contribution_bulk_mappings
|
|
|
|
from src.aeros_contribution.service import update_contribution_bulk_mappings
|
|
|
|
from src.aeros_equipment.model import AerosEquipment
|
|
|
|
from src.aeros_equipment.model import AerosEquipment
|
|
|
|
from src.aeros_simulation.model import AerosSimulationCalcResult, EafContribution, AerosNode
|
|
|
|
from src.aeros_simulation.model import AerosSimulationCalcResult, EafContribution, AerosNode
|
|
|
|
|
|
|
|
from src.aeros_simulation.utils import date_to_utc, hours_between, year_window_utc
|
|
|
|
from src.auth.service import CurrentUser
|
|
|
|
from src.auth.service import CurrentUser
|
|
|
|
from src.config import TEMPORAL_URL
|
|
|
|
from src.config import TEMPORAL_URL
|
|
|
|
from src.database.core import CollectorDbSession, DbSession
|
|
|
|
from src.database.core import CollectorDbSession, DbSession
|
|
|
|
@ -26,7 +27,8 @@ from .schema import (
|
|
|
|
SimulationPlotResult,
|
|
|
|
SimulationPlotResult,
|
|
|
|
SimulationCalc,
|
|
|
|
SimulationCalc,
|
|
|
|
SimulationData,
|
|
|
|
SimulationData,
|
|
|
|
SimulationRankingParameters
|
|
|
|
SimulationRankingParameters,
|
|
|
|
|
|
|
|
YearlySimulationInput
|
|
|
|
)
|
|
|
|
)
|
|
|
|
from .service import (
|
|
|
|
from .service import (
|
|
|
|
create_simulation,
|
|
|
|
create_simulation,
|
|
|
|
@ -108,6 +110,107 @@ async def run_simulations(
|
|
|
|
"message": "Simulation started successfully",
|
|
|
|
"message": "Simulation started successfully",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/run/yearly", response_model=StandardResponse[str])
|
|
|
|
|
|
|
|
async def run_yearly_simulation(
|
|
|
|
|
|
|
|
db_session: DbSession,
|
|
|
|
|
|
|
|
yearly_in: YearlySimulationInput,
|
|
|
|
|
|
|
|
current_user: CurrentUser
|
|
|
|
|
|
|
|
):
|
|
|
|
|
|
|
|
year = yearly_in.year
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sim_start, sim_end = year_window_utc(year)
|
|
|
|
|
|
|
|
sim_duration_hours = hours_between(sim_start, sim_end)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Fetch last overhaul data
|
|
|
|
|
|
|
|
last_oh_query = text("""
|
|
|
|
|
|
|
|
SELECT start_date, end_date, duration_oh
|
|
|
|
|
|
|
|
FROM public.oh_ms_overhaul
|
|
|
|
|
|
|
|
WHERE end_date <= :sim_start
|
|
|
|
|
|
|
|
ORDER BY end_date DESC
|
|
|
|
|
|
|
|
LIMIT 1;
|
|
|
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
next_oh_query = text("""
|
|
|
|
|
|
|
|
SELECT start_date, end_date, duration_oh
|
|
|
|
|
|
|
|
FROM public.oh_ms_overhaul
|
|
|
|
|
|
|
|
WHERE start_date >= :sim_start
|
|
|
|
|
|
|
|
ORDER BY start_date ASC
|
|
|
|
|
|
|
|
LIMIT 1;
|
|
|
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
last_overhaul = (await db_session.execute(
|
|
|
|
|
|
|
|
last_oh_query,
|
|
|
|
|
|
|
|
{"sim_start": sim_start.date()}
|
|
|
|
|
|
|
|
)).mappings().first()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
next_overhaul = (await db_session.execute(
|
|
|
|
|
|
|
|
next_oh_query,
|
|
|
|
|
|
|
|
{"sim_start": sim_start.date()}
|
|
|
|
|
|
|
|
)).mappings().first()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if last_overhaul:
|
|
|
|
|
|
|
|
last_oh_dt = date_to_utc(last_overhaul["end_date"])
|
|
|
|
|
|
|
|
offset_hours = max(
|
|
|
|
|
|
|
|
int((sim_start - last_oh_dt).total_seconds() // 3600),
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if next_overhaul:
|
|
|
|
|
|
|
|
next_oh_start = date_to_utc(next_overhaul["start_date"])
|
|
|
|
|
|
|
|
next_oh_duration_hours = next_overhaul["duration_oh"] * 24
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
overhaul_interval = int(
|
|
|
|
|
|
|
|
(next_oh_start - last_oh_dt).total_seconds() // 3600
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
overhaul_duration = next_oh_duration_hours
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
simulation_input = SimulationInput(
|
|
|
|
|
|
|
|
SimDuration=sim_duration_hours,
|
|
|
|
|
|
|
|
DurationUnit="UHour",
|
|
|
|
|
|
|
|
OffSet=offset_hours,
|
|
|
|
|
|
|
|
OverhaulInterval=overhaul_interval,
|
|
|
|
|
|
|
|
MaintenanceOutages=0,
|
|
|
|
|
|
|
|
SimulationName=f"Simulation {year} LCCA",
|
|
|
|
|
|
|
|
IsDefault=False,
|
|
|
|
|
|
|
|
OverhaulDuration=overhaul_duration,
|
|
|
|
|
|
|
|
AhmJobId=None
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
temporal_client = await Client.connect(TEMPORAL_URL)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
simulation = await create_simulation(
|
|
|
|
|
|
|
|
db_session=db_session,
|
|
|
|
|
|
|
|
simulation_in=simulation_input,
|
|
|
|
|
|
|
|
current_user=current_user
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
project = await get_project(db_session=db_session)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sim_data = simulation_input.model_dump()
|
|
|
|
|
|
|
|
sim_data["HubCnnId"] = str(simulation.id)
|
|
|
|
|
|
|
|
sim_data["SimulationStart"] = sim_start.isoformat()
|
|
|
|
|
|
|
|
sim_data["SimulationEnd"] = sim_end.isoformat()
|
|
|
|
|
|
|
|
sim_data["HubCnnId"] = str(simulation.id)
|
|
|
|
|
|
|
|
sim_data["projectName"] = project.project_name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await temporal_client.start_workflow(
|
|
|
|
|
|
|
|
SimulationWorkflow.run,
|
|
|
|
|
|
|
|
sim_data,
|
|
|
|
|
|
|
|
id=f"simulation-{simulation.id}",
|
|
|
|
|
|
|
|
task_queue="simulation-task-queue",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
"data": str(simulation.id),
|
|
|
|
|
|
|
|
"status": "success",
|
|
|
|
|
|
|
|
"message": f"Yearly simulation {year} started (UHour mode)",
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get(
|
|
|
|
@router.get(
|
|
|
|
"/result/calc/{simulation_id}",
|
|
|
|
"/result/calc/{simulation_id}",
|
|
|
|
response_model=StandardResponse[List[SimulationCalc]],
|
|
|
|
response_model=StandardResponse[List[SimulationCalc]],
|
|
|
|
|