From ef8620384c62af791bf4d0297832a86b344d5e3f Mon Sep 17 00:00:00 2001 From: Cizz22 Date: Thu, 31 Jul 2025 11:04:49 +0700 Subject: [PATCH] add ranking result add custom input simulation --- src/aeros_equipment/service.py | 31 +++++++++++++++++++++++----- src/aeros_simulation/model.py | 1 + src/aeros_simulation/router.py | 36 +++++++++++++++++++++++++++++---- src/aeros_simulation/schema.py | 3 +++ src/aeros_simulation/service.py | 31 +++++++++++++++++++++++++++- 5 files changed, 92 insertions(+), 10 deletions(-) diff --git a/src/aeros_equipment/service.py b/src/aeros_equipment/service.py index 70b7194..0f9862c 100644 --- a/src/aeros_equipment/service.py +++ b/src/aeros_equipment/service.py @@ -276,7 +276,7 @@ def get_asset_batch(location_tags: List[str], -async def update_equipment_for_simulation(*, db_session: DbSession, project_name: str, schematic_name: str): +async def update_equipment_for_simulation(*, db_session: DbSession, project_name: str, schematic_name: str, custom_input: Optional[dict] = None): log.info("Updating equipment for simulation") aeros_schematic = await get_aeros_schematic_by_name(db_session=db_session, schematic_name=schematic_name) @@ -302,29 +302,50 @@ async def update_equipment_for_simulation(*, db_session: DbSession, project_name reliability_data = get_asset_batch(reg_nodes) reqNodeInputs = [] + results = defaultdict() for eq in nodes_data: try: reliabiility = reliability_data.get(eq["equipmentName"], {}) + + if custom_input and eq["equipmentName"] in custom_input: + eq["cmDisP1"] = reliabiility.get("cmDisP1", 0) + eq["relDisType"] = "Fixed" + eq["relDisP1"] = custom_input[eq["equipmentName"]] + eq["relDisP2"] = 0 + + reqNodeInputs.append(eq) + results[eq["equipmentName"]] = { + "mttr": eq["cmDisP1"], + "distribution": eq["relDisType"], + "beta": eq["relDisP1"], + "eta": 0 + } + continue + eq["cmDisP1"] = reliabiility.get("cmDisP1", 0) eq["relDisType"] = "NHPPTTFF" eq["relDisP1"] = reliabiility.get("relDisP1", 0) eq["relDisP2"] = reliabiility.get("relDisP2", 0) reqNodeInputs.append(eq) + results[eq["equipmentName"]] = { + "mttr": eq["cmDisP1"], + "distribution": eq["relDisType"], + "beta": eq["relDisP1"], + "eta": eq["relDisP2"] + } except Exception as e: print(f"Error fetching data for {eq['equipmentName']}: {e}") # Add equipment with default values - eq["cmDisP1"] = 0 - eq["relDisType"] = "" - eq["relDisP1"] = 0 - eq["relDisP2"] = 0 reqNodeInputs.append(eq) print("Updating equipment for simulation") await update_node(db_session=db_session, equipment_nodes=reqNodeInputs, project_name=project_name) print("Updated equipment for simulation") + return results + # Optimized individual fetch functions async def get_equipment_mttr(*, location_tag: str, client: httpx.AsyncClient) -> float: diff --git a/src/aeros_simulation/model.py b/src/aeros_simulation/model.py index 2098d70..1c0b39f 100644 --- a/src/aeros_simulation/model.py +++ b/src/aeros_simulation/model.py @@ -16,6 +16,7 @@ class AerosSimulation(Base, DefaultMixin): error = Column(JSON, nullable=True) simulation_name = Column(String, nullable=False) schematic_name = Column(String, nullable=False) + reliability = Column(JSON, nullable=True) calc_results = relationship( "AerosSimulationCalcResult", back_populates="aeros_simulation", lazy="raise" diff --git a/src/aeros_simulation/router.py b/src/aeros_simulation/router.py index 213601c..d91cb49 100644 --- a/src/aeros_simulation/router.py +++ b/src/aeros_simulation/router.py @@ -15,7 +15,8 @@ from .schema import ( SimulationInput, SimulationPagination, SimulationPlotResult, - SimulationCalc + SimulationCalc, + SimulationData ) from .service import ( create_simulation, @@ -25,6 +26,8 @@ from .service import ( get_simulation_by_id, get_simulation_with_calc_result, get_simulation_with_plot_result, + update_simulation, + get_result_ranking ) router = APIRouter() @@ -43,6 +46,16 @@ async def get_all_simulation(db_session: DbSession, common: CommonParameters): "message": "Simulations result retrieved successfully", } +@router.get("/{simulation_id}", response_model=StandardResponse[SimulationData]) +async def get_simulation(db_session: DbSession, simulation_id): + """Get simulation.""" + result = await get_simulation_by_id(db_session=db_session, simulation_id=simulation_id) + + return { + "data": result, + "status": "success", + "message": "Simulation result retrieved successfully", + } @router.post("/run", response_model=StandardResponse[str]) async def run_simulations( @@ -67,12 +80,16 @@ async def run_simulations( ##background_tasks.add_task(execute_simulation, db_session=db_session ,simulation_id=simulation_id, sim_data=sim_data) - await update_equipment_for_simulation( - db_session=db_session, project_name=project.project_name, schematic_name=simulation_in.SchematicName + results = await update_equipment_for_simulation( + db_session=db_session, project_name=project.project_name, schematic_name=simulation_in.SchematicName, custom_input=simulation_in.CustomInput + ) + + await update_simulation( + db_session=db_session, simulation_id=simulation_id, data={"reliability": results} ) await execute_simulation( - db_session=db_session, simulation_id=simulation_id, sim_data=sim_data, is_saved=True + db_session=db_session, simulation_id=simulation_id, sim_data=sim_data, is_saved=True, eq_update=results ) return { @@ -120,6 +137,17 @@ async def get_simulation_result_plot(db_session: DbSession, simulation_id): "message": "Simulation result retrieved successfully", } +@router.get("/result/ranking/{simulation_id}", response_model=StandardResponse[List[SimulationCalc]]) +async def get_simulation_result_ranking(db_session: DbSession, simulation_id): + """Get simulation result.""" + simulation_result = await get_result_ranking(db_session=db_session, simulation_id=simulation_id) + + return { + "data": simulation_result, + "status": "success", + "message": "Simulation result retrieved successfully", + } + @router.get("/custom_parameters", response_model=StandardResponse[list]) async def get_custom_parameters_controller(db_session: DbSession): diff --git a/src/aeros_simulation/schema.py b/src/aeros_simulation/schema.py index 12fa03c..e4a52c5 100644 --- a/src/aeros_simulation/schema.py +++ b/src/aeros_simulation/schema.py @@ -15,6 +15,7 @@ class SimulationInput(BaseModel): DurationUnit: str = "UYear" SimNumRun: int = 1 SimulationName: str = "DefaultSimulation" + CustomInput: dict = {} class SimulationNode(BaseModel): @@ -55,6 +56,7 @@ class SimulationCalc(BaseModel): duration_below_ll: float duration_at_empty: float stg_input: float + eaf: float aeros_node: SimulationNode class SimulationPlot(BaseModel): @@ -86,6 +88,7 @@ class SimulationData(BaseModel): simulation_name: str status: str schematic_name: str + reliability: dict created_at: datetime diff --git a/src/aeros_simulation/service.py b/src/aeros_simulation/service.py index 2b14a11..bdfeece 100644 --- a/src/aeros_simulation/service.py +++ b/src/aeros_simulation/service.py @@ -4,7 +4,7 @@ from uuid import uuid4, uuid4, UUID import logging import httpx from fastapi import HTTPException, status -from sqlalchemy import delete, select +from sqlalchemy import delete, select, update from sqlalchemy.orm import selectinload from src.config import AEROS_BASE_URL, DEFAULT_PROJECT_NAME @@ -138,6 +138,7 @@ async def execute_simulation( simulation_id: Optional[UUID] = None, sim_data: dict, is_saved: bool = False, + eq_update: dict = {}, ): """Execute the actual simulation call""" print("Executing simulation with id: %s", simulation_id, sim_data["SchematicName"]) @@ -493,6 +494,28 @@ async def get_simulation_with_calc_result( return simulation.scalars().all() +async def get_result_ranking(*, db_session: DbSession, simulation_id: UUID): + + query = select(AerosSimulationCalcResult).where( + AerosSimulationCalcResult.aeros_simulation_id == simulation_id + ) + + query = query.join( + AerosNode, AerosNode.id == AerosSimulationCalcResult.aeros_node_id + ) + query = query.where(AerosNode.node_type == "RegularNode") + + query = query.order_by(AerosSimulationCalcResult.eaf.desc()).limit(10) + + + query = query.options( + selectinload(AerosSimulationCalcResult.aeros_node)) + + result = await db_session.execute(query) + + return result.scalars().all() + + async def get_simulation_with_plot_result( *, db_session: DbSession, simulation_id: UUID ): @@ -583,3 +606,9 @@ async def get_all_schematic_aeros(*, db_session: DbSession): query = select(AerosSchematic) results = await db_session.execute(query) return results.scalars().all() + + +async def update_simulation(*, db_session: DbSession, simulation_id: UUID, data: dict): + query = update(AerosSimulation).where(AerosSimulation.id == simulation_id).values(**data) + await db_session.execute(query) + await db_session.commit()