diff --git a/src/aeros_simulation/router.py b/src/aeros_simulation/router.py index 4d01e9b..f1f581a 100644 --- a/src/aeros_simulation/router.py +++ b/src/aeros_simulation/router.py @@ -207,7 +207,7 @@ async def get_simulation_result_plot(db_session: DbSession, simulation_id): "status": "success", "message": "Simulation result retrieved successfully", } - + @router.get( "/result/plot/{simulation_id}/{node_id}", @@ -248,6 +248,88 @@ async def get_simulation_result_ranking(db_session: DbSession, simulation_id, li } + +@router.get("/result/critical/{simulation_id}]", response_model=StandardResponse[List[SimulationCalc]]) +async def get_critical_equipment(db_session:DbSession, simulation_id: str): + # Step 1: Get all failure events for this simulation + if simulation_id == 'default': + simulation = await get_default_simulation(db_session=db_session) + simulation_id = simulation.id + + + failure_query = text(""" + SELECT DISTINCT + (elem ->> 'currentEvent') AS jenis, + (elem ->> 'cumulativeTime')::numeric AS cumulative_time + FROM rbd_tr_aeros_simulation_plot_result AS a + JOIN public.rbd_ms_aeros_node AS b + ON a.aeros_node_id = b.id + JOIN LATERAL jsonb_array_elements(a.timestamp_outs) AS elem ON TRUE + WHERE a.aeros_simulation_id = :simulation_id + AND b.node_name = '- TJB - Unit 3 -' + AND (elem ->> 'currentEQStatus') = 'OoS' + AND (elem ->> 'currentEvent') != 'ON_OH' + ORDER BY cumulative_time; + """) + + query = await db_session.execute(failure_query, { + "simulation_id": simulation_id, + }) + + failures = query.fetchall() + + results = [] + + # Step 2: For each failure, find which equipment caused it + for fail in failures: + cumulative_time = fail.cumulative_time + jenis = fail.jenis + + equipment_query = text(""" + SELECT b.id + FROM rbd_tr_aeros_simulation_plot_result AS a + JOIN public.rbd_ms_aeros_node AS b ON a.aeros_node_id = b.id + WHERE EXISTS ( + SELECT 1 + FROM jsonb_array_elements(a.timestamp_outs) AS elem + WHERE + (elem ->> 'currentEQStatus') = 'OoS' AND + (elem ->> 'cumulativeTime')::numeric = :cumulative_time + ) + AND a.aeros_simulation_id = :simulation_id + AND b.node_type = 'RegularNode'; + """) + + equipment = (await db_session.execute(equipment_query, { + "simulation_id": simulation_id, + "cumulative_time": cumulative_time + })).fetchall() + + equipment_list = [eq.id for eq in equipment] + + results.extend(equipment_list) + + query = (select(AerosSimulationCalcResult).filter( + AerosSimulationCalcResult.aeros_simulation_id == simulation_id)).filter(AerosSimulationCalcResult.aeros_node_id.in_(results)) + + query = query.options( + selectinload(AerosSimulationCalcResult.aeros_node).options( + selectinload(AerosNode.equipment) + )) + + data = await db_session.execute(query) + + equipments = data.scalars.all() + + return { + "data": equipments, + "status": "success", + "message": "Success", + } + + + + @router.get("/custom_parameters", response_model=StandardResponse[list]) async def get_custom_parameters_controller(db_session: DbSession): """Get simulation result.""" @@ -385,83 +467,3 @@ async def calculate_contribution( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e) ) - -@router.get("/result/critical/{simulation_id}]", response_model=StandardResponse[List[SimulationCalc]]) -async def get_critical_equipment(db_session:DbSession, simulation_id: str): - # Step 1: Get all failure events for this simulation - if simulation_id == 'default': - simulation = await get_default_simulation(db_session=db_session) - simulation_id = simulation.id - - - failure_query = text(""" - SELECT DISTINCT - (elem ->> 'currentEvent') AS jenis, - (elem ->> 'cumulativeTime')::numeric AS cumulative_time - FROM rbd_tr_aeros_simulation_plot_result AS a - JOIN public.rbd_ms_aeros_node AS b - ON a.aeros_node_id = b.id - JOIN LATERAL jsonb_array_elements(a.timestamp_outs) AS elem ON TRUE - WHERE a.aeros_simulation_id = :simulation_id - AND b.node_name = '- TJB - Unit 3 -' - AND (elem ->> 'currentEQStatus') = 'OoS' - AND (elem ->> 'currentEvent') != 'ON_OH' - ORDER BY cumulative_time; - """) - - query = await db_session.execute(failure_query, { - "simulation_id": simulation_id, - }) - - failures = query.fetchall() - - results = [] - - # Step 2: For each failure, find which equipment caused it - for fail in failures: - cumulative_time = fail.cumulative_time - jenis = fail.jenis - - equipment_query = text(""" - SELECT b.id - FROM rbd_tr_aeros_simulation_plot_result AS a - JOIN public.rbd_ms_aeros_node AS b ON a.aeros_node_id = b.id - WHERE EXISTS ( - SELECT 1 - FROM jsonb_array_elements(a.timestamp_outs) AS elem - WHERE - (elem ->> 'currentEQStatus') = 'OoS' AND - (elem ->> 'cumulativeTime')::numeric = :cumulative_time - ) - AND a.aeros_simulation_id = :simulation_id - AND b.node_type = 'RegularNode'; - """) - - equipment = (await db_session.execute(equipment_query, { - "simulation_id": simulation_id, - "cumulative_time": cumulative_time - })).fetchall() - - equipment_list = [eq.id for eq in equipment] - - results.extend(equipment_list) - - query = (select(AerosSimulationCalcResult).filter( - AerosSimulationCalcResult.aeros_simulation_id == simulation_id)).filter(AerosSimulationCalcResult.aeros_node_id.in_(results)) - - query = query.options( - selectinload(AerosSimulationCalcResult.aeros_node).options( - selectinload(AerosNode.equipment) - )) - - data = await db_session.execute(query) - - equipments = data.scalars.all() - - return { - "data": equipments, - "status": "success", - "message": "Success", - } - - \ No newline at end of file