add statistic

main
Cizz22 3 months ago
parent 1252a153cc
commit 2204bac92b

@ -73,7 +73,7 @@ async def wait_for_workflow(simulation_id, max_retries=3):
print(f"✅ Workflow {workflow_id} finished with status: {status}") print(f"✅ Workflow {workflow_id} finished with status: {status}")
break break
print(f"⏳ Workflow {workflow_id} still {status}, checking again in 30s...") print(f"⏳ Workflow {workflow_id} still {status}, checking again in 10s...")
except Exception as e: except Exception as e:
retries += 1 retries += 1
@ -86,6 +86,6 @@ async def wait_for_workflow(simulation_id, max_retries=3):
continue continue
retries = 0 # reset retries if describe() worked retries = 0 # reset retries if describe() worked
await asyncio.sleep(30) await asyncio.sleep(10)
return simulation_id return simulation_id

@ -71,6 +71,8 @@ class CalculationData(Base, DefaultMixin, IdentityMixin):
max_interval = Column(Integer, nullable=True) max_interval = Column(Integer, nullable=True)
rbd_simulation_id = Column(UUID(as_uuid=True), nullable=True) rbd_simulation_id = Column(UUID(as_uuid=True), nullable=True)
optimum_analysis = Column(JSON, nullable=True)
session = relationship("OverhaulScope", lazy="raise") session = relationship("OverhaulScope", lazy="raise")
@ -80,7 +82,9 @@ class CalculationData(Base, DefaultMixin, IdentityMixin):
"CalculationEquipmentResult", lazy="raise", viewonly=True "CalculationEquipmentResult", lazy="raise", viewonly=True
) )
results = relationship("CalculationResult", lazy="raise", viewonly=True) results = relationship("CalculationResult", lazy="raise", viewonly=True)
@classmethod @classmethod
async def create_with_param( async def create_with_param(

@ -25,7 +25,7 @@ router = APIRouter()
@router.post( @router.post(
"", response_model=StandardResponse[Union[str, CalculationTimeConstrainsRead]] "", response_model=StandardResponse[Union[dict, CalculationTimeConstrainsRead]]
) )
async def create_calculation_time_constrains( async def create_calculation_time_constrains(
token: Token, token: Token,
@ -55,7 +55,7 @@ async def create_calculation_time_constrains(
simulation_id=simulation_id simulation_id=simulation_id
) )
return StandardResponse(data=str(results), message="Data created successfully") return StandardResponse(data=results, message="Data created successfully")
@router.get( @router.get(

@ -334,7 +334,7 @@ class OptimumCostModelWithSpareparts:
async def calculate_cost_all_equipment_with_spareparts(self, db_session,collector_db_session ,equipments: List, async def calculate_cost_all_equipment_with_spareparts(self, db_session,collector_db_session ,equipments: List,
calculation, preventive_cost: float, calculation, preventive_cost: float,
simulation_id: str = "default") -> Dict: simulation_id: str = "default"):
""" """
Calculate optimal overhaul timing for entire fleet considering sparepart constraints Calculate optimal overhaul timing for entire fleet considering sparepart constraints
""" """
@ -373,7 +373,13 @@ class OptimumCostModelWithSpareparts:
plant_capacity_loss_money = [metrics['derated_mwh'] * COST_PER_MWH for metrics in plant_monthly_metrics.values()] plant_capacity_loss_money = [metrics['derated_mwh'] * COST_PER_MWH for metrics in plant_monthly_metrics.values()]
cumulative_loss_money = np.cumsum(plant_capacity_loss_money) cumulative_loss_money = np.cumsum(plant_capacity_loss_money)
total_simulation_period = int((importance_results["plant_result"]['total_downtime'] + importance_results["plant_result"]['total_uptime'])/720)
loss_production_per_month = np.arange(0, total_simulation_period)
k = 5
loss_exp = (importance_results["plant_result"]['total_downtime'] * 660 * 500_000) * (np.exp(k * (loss_production_per_month / total_simulation_period)) - 1) / (np.exp(k) - 1)
for equipment in equipments: for equipment in equipments:
@ -434,7 +440,7 @@ class OptimumCostModelWithSpareparts:
# Phase 3: Generate final results and database objects # Phase 3: Generate final results and database objects
fleet_results = [] fleet_results = []
total_corrective_costs = np.zeros(max_interval) + cumulative_loss_money[0:max_interval] total_corrective_costs = np.zeros(max_interval) + loss_exp[0:max_interval]
total_preventive_costs = np.zeros(max_interval) total_preventive_costs = np.zeros(max_interval)
total_procurement_costs = np.zeros(max_interval) total_procurement_costs = np.zeros(max_interval)
total_costs = np.zeros(max_interval) total_costs = np.zeros(max_interval)
@ -507,7 +513,7 @@ class OptimumCostModelWithSpareparts:
f"(Procurement cost: ${cost_data['procurement_cost']:,.2f})") f"(Procurement cost: ${cost_data['procurement_cost']:,.2f})")
# Calculate fleet optimal interval # Calculate fleet optimal interval
fleet_optimal_index = np.argmin(total_costs) fleet_optimal_index = np.argmin(total_corrective_costs + total_preventive_costs)
fleet_optimal_cost = total_costs[fleet_optimal_index] fleet_optimal_cost = total_costs[fleet_optimal_index]
# Generate procurement optimization report # Generate procurement optimization report
@ -528,26 +534,7 @@ class OptimumCostModelWithSpareparts:
self.logger.info(f" - Total procurement cost: ${total_fleet_procurement_cost:,.2f}") self.logger.info(f" - Total procurement cost: ${total_fleet_procurement_cost:,.2f}")
self.logger.info(f" - Equipment with sparepart constraints: {len([r for r in individual_results.values() if not r['sparepart_available']])}") self.logger.info(f" - Equipment with sparepart constraints: {len([r for r in individual_results.values() if not r['sparepart_available']])}")
return { return fleet_optimal_index
'id': calculation.id,
'fleet_results': fleet_results,
'fleet_optimal_interval': fleet_optimal_index + 1,
'fleet_optimal_cost': fleet_optimal_cost,
'total_corrective_costs': total_corrective_costs.tolist(),
'total_preventive_costs': total_preventive_costs.tolist(),
'total_procurement_costs': total_procurement_costs.tolist(),
'individual_results': individual_results,
'optimized_plan': improved_plan,
'procurement_plan': procurement_plan,
'total_fleet_procurement_cost': total_fleet_procurement_cost,
'analysis_parameters': {
'planned_oh_months': self.planned_oh_months,
'analysis_window_months': self.time_window_months,
'last_oh_date': self.last_oh_date.isoformat(),
'next_oh_date': self.next_oh_date.isoformat(),
'sparepart_optimization_enabled': True
}
}
def _optimize_fleet_with_sparepart_constraints(self, individual_results: Dict, equipments: List, def _optimize_fleet_with_sparepart_constraints(self, individual_results: Dict, equipments: List,
equipment_birnbaum: Dict, simulation_id: str) -> List[Tuple[str, int]]: equipment_birnbaum: Dict, simulation_id: str) -> List[Tuple[str, int]]:
@ -713,27 +700,58 @@ async def run_simulation_with_spareparts(*, db_session, calculation, token: str,
base_url=RBD_SERVICE_API, base_url=RBD_SERVICE_API,
sparepart_manager=sparepart_manager sparepart_manager=sparepart_manager
) )
simulation_ids = ["41a9b376-fe55-4cec-9234-db4951019b8a",
"ea3c8d32-fb1e-417c-914a-296ba08516a1",
"ed586b3d-c215-4b58-a6a8-7577f91e0b6b",
"97357934-8703-4ef5-90c8-858d3a5c5a35",
"f674918f-af74-4601-99a3-96f44bfdb4e4",
"a2a7fc3e-f638-4c88-830c-88232b45d2f5",
"18012150-9458-419a-9537-de8f096f2e36",
"835d5027-6abf-47d8-af04-f3428634d118",
"37c68489-23e2-4def-ae31-81dc79df7851",
"ce7a1d4f-c9c4-41c1-97ee-20911d354bba"]
try: try:
# Run fleet optimization with sparepart management optimum_collection = []
results = await optimum_oh_model.calculate_cost_all_equipment_with_spareparts(
db_session=db_session, for sim_id in simulation_ids:
collector_db_session=collector_db_session, # Run fleet optimization with sparepart management
equipments=equipments, results = await optimum_oh_model.calculate_cost_all_equipment_with_spareparts(
calculation=calculation_data, db_session=db_session,
preventive_cost=calculation_data.parameter.overhaul_cost, collector_db_session=collector_db_session,
simulation_id=simulation_id equipments=equipments,
) calculation=calculation_data,
preventive_cost=calculation_data.parameter.overhaul_cost,
# Generate sparepart report simulation_id=sim_id
# sparepart_report = optimum_oh_model.generate_sparepart_report(results) )
# print(sparepart_report)
optimum_collection.append(results)
return results
finally: finally:
await optimum_oh_model._close_session() await optimum_oh_model._close_session()
np_optimum = np.array(optimum_collection)
stats = {
'min': float(np.min(np_optimum)),
'max': float(np.max(np_optimum)),
'mean': float(np.mean(np_optimum)),
'median': float(np.median(np_optimum)),
'std': float(np.std(np_optimum)),
'variance': float(np.var(np_optimum)),
'range': float(np.ptp(np_optimum)), # max - min
}
calculation_data.optimum_analysis = stats
await db_session.commit()
return {
"id": calculation_data.id,
"optimum": stats
}
async def create_param_and_data( async def create_param_and_data(
@ -992,7 +1010,8 @@ async def get_calculation_result(db_session: DbSession, calculation_id: str, tok
"next_planned_overhaul": scope_overhaul.start_date.isoformat(), "next_planned_overhaul": scope_overhaul.start_date.isoformat(),
"calculation_type": "sparepart_optimized" if fleet_statistics['equipment_with_sparepart_constraints'] > 0 else "standard", "calculation_type": "sparepart_optimized" if fleet_statistics['equipment_with_sparepart_constraints'] > 0 else "standard",
"total_equipment_analyzed": len(all_equipment), "total_equipment_analyzed": len(all_equipment),
"included_in_optimization": len(included_equipment) "included_in_optimization": len(included_equipment),
"optimal_stat": scope_calculation.optimum_analysis
} }
) )

Loading…
Cancel
Save