add yearly simulation run

main
Cizz22 3 weeks ago
parent b9dec05768
commit fe875a3677

@ -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]],

@ -120,3 +120,6 @@ class SimulationPagination(Pagination):
class AhmMetricInput(BaseModel): class AhmMetricInput(BaseModel):
target_simulation_id: str target_simulation_id: str
baseline_simulation_id: Optional[str] = Field(None) baseline_simulation_id: Optional[str] = Field(None)
class YearlySimulationInput(BaseModel):
year: int

@ -1,3 +1,4 @@
from datetime import datetime
import json import json
import logging import logging
@ -7,6 +8,24 @@ from src.logging import setup_logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
setup_logging(log) setup_logging(log)
def date_to_utc(date_val):
return datetime.combine(
date_val,
datetime.min.time(),
)
def hours_between(start: datetime, end: datetime) -> int:
return int((end - start).total_seconds() // 3600)
def year_window_utc(year: int):
start = datetime(year, 1, 1, 0, 0, 0)
end = datetime(year + 1, 1, 1, 0, 0, 0)
return start, end
def calculate_eaf( def calculate_eaf(
available_hours: float, available_hours: float,
period_hours: float, period_hours: float,

Loading…
Cancel
Save