update simulation api

main
Cizz22 1 year ago
parent 970df9e179
commit f4a50706d1

@ -1,3 +1,5 @@
from typing import Optional
from uuid import UUID
import numpy as np
from sqlalchemy import Select, func, select
from sqlalchemy.orm import joinedload
@ -7,7 +9,7 @@ from src.scope.model import Scope
from src.database.core import DbSession
from src.scope.service import get_all
from .schema import CalculationTimeConstrainsParametersRead, CalculationTimeConstrainsParametersRetrive, CalculationTimeConstrainsParametersCreate
from .service import get_overhaul_cost_by_time_chart, get_corrective_cost_time_chart, create_param_and_data, get_calculation_data_by_id
from .service import get_calculation_by_reference_and_parameter, get_calculation_result, get_overhaul_cost_by_time_chart, get_corrective_cost_time_chart, create_param_and_data, get_calculation_data_by_id, create_calculation_result_service
from .model import CalculationResult
from .model import CalculationParam
@ -61,38 +63,40 @@ async def get_create_calculation_parameters(*, db_session: DbSession, calculatio
)
async def create_calculation(*, db_session: DbSession, calculation_time_constrains_in: CalculationTimeConstrainsParametersCreate, created_by:str):
days = 60
##
async def create_calculation(*, db_session: DbSession, calculation_time_constrains_in: CalculationTimeConstrainsParametersCreate, created_by: str):
calculation_data = await create_param_and_data(
db_session=db_session, calculation_param_in=calculation_time_constrains_in, created_by=created_by)
overhaul_cost_points = get_overhaul_cost_by_time_chart(
calculation_time_constrains_in.overhaulCost, days)
results = await create_calculation_result_service(db_session=db_session, calculation_id=calculation_data.id)
corrective_cost_points, dailyNumberOfFailure = get_corrective_cost_time_chart(
calculation_time_constrains_in.costPerFailure, days)
return results
total_cost = overhaul_cost_points + corrective_cost_points
optimumOH = np.argmin(total_cost)
numbersOfFailure = sum(dailyNumberOfFailure[:optimumOH])
async def get_or_create_scope_equipment_calculation(*, db_session: DbSession, scope_calculation_id, calculation_time_constrains_in: Optional[CalculationTimeConstrainsParametersCreate]):
scope_calculation = await get_calculation_data_by_id(db_session=db_session, calculation_id=scope_calculation_id)
# raise Exception(optimumOH)
calculation_results = []
for i in range(days):
result = CalculationResult(
parameter_id=calculation_data.parameter_id,
calculation_data_id=calculation_data.id,
day=(i + 1),
corrective_cost=float(corrective_cost_points[i]),
overhaul_cost=float(overhaul_cost_points[i]),
num_failures=int(dailyNumberOfFailure[i]),
if not scope_calculation:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="A data with this id does not exist.",
)
calculation_results.append(result)
db_session.add_all(calculation_results)
await db_session.commit()
# Check if calculation already exist
scope_equipment_calculation = await get_calculation_by_reference_and_parameter(
db_session=db_session, calculation_reference_id=calculation_time_constrains_in.assetnum, parameter_id=scope_calculation.parameter_id)
if not scope_equipment_calculation:
# Update Parameter input from scope calculation
calculation_time_constrains_in.costPerFailure = scope_calculation.parameter.avg_failure_cost
calculation_time_constrains_in.overhaulCost = scope_calculation.parameter.overhaul_cost
scope_equipment_calculation = await create_param_and_data(
db_session=db_session, calculation_param_in=calculation_time_constrains_in, created_by=scope_calculation.created_by, parameter_id=scope_calculation.parameter_id)
results = await create_calculation_result_service(db_session=db_session, calculation_id=scope_equipment_calculation.id)
return results
results = await get_calculation_result(db_session=db_session, calculation_id=scope_equipment_calculation.id)
return calculation_data.id
return results

@ -1,7 +1,7 @@
from enum import Enum
from typing import List, Union
from typing import List, Optional, Union
from sqlalchemy import UUID, Column, Float, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from src.database.core import Base, DbSession
@ -63,7 +63,8 @@ class CalculationData(Base, DefaultMixin, IdentityMixin):
parameter_id = Column(UUID(as_uuid=True), ForeignKey(
'oh_ms_calculation_param.id'), nullable=True)
overhaul_reference_type = Column(String(10), nullable=False)
reference_id = Column(UUID(as_uuid=True), nullable=False)
reference_id = Column(String, nullable=False)
optimum_oh_day = Column(Integer, nullable=True)
parameter = relationship(
"CalculationParam", back_populates="calculation_data")
@ -78,10 +79,12 @@ class CalculationData(Base, DefaultMixin, IdentityMixin):
overhaul_reference_type: str,
reference_id: Union[str, UUID],
db: DbSession,
avg_failure_cost: float,
overhaul_cost: float,
avg_failure_cost: Optional[float],
overhaul_cost: Optional[float],
created_by: str,
params_id: Optional[UUID]
):
if not params_id:
# Create Params
params = CalculationParam(
avg_failure_cost=avg_failure_cost,
@ -89,15 +92,15 @@ class CalculationData(Base, DefaultMixin, IdentityMixin):
created_by=created_by
)
db.add(params)
await db.flush()
params_id = params.id
calculation_data = cls(
overhaul_reference_type=overhaul_reference_type,
reference_id=reference_id,
reference_id=str(reference_id),
created_by=created_by,
parameter_id=params.id
parameter_id=params_id
)
db.add(calculation_data)

@ -6,18 +6,25 @@ from src.database.core import DbSession
from src.models import StandardResponse
from src.auth.service import CurrentUser
from .service import create_param_and_data, get_calculation_result
from .flows import get_create_calculation_parameters, create_calculation
from .flows import get_create_calculation_parameters, create_calculation, get_or_create_scope_equipment_calculation
from fastapi.params import Query
router = APIRouter()
@router.post("", response_model=StandardResponse[str])
async def create_calculation_time_constrains(db_session: DbSession, current_user: CurrentUser, calculation_time_constrains_in: CalculationTimeConstrainsParametersCreate):
@router.post("", response_model=StandardResponse[Union[str, CalculationTimeConstrainsRead]])
async def create_calculation_time_constrains(db_session: DbSession, current_user: CurrentUser, calculation_time_constrains_in: CalculationTimeConstrainsParametersCreate, scope_calculation_id: Optional[str] = Query(None), with_results: Optional[int] = Query(0)):
"""Save calculation time constrains Here"""
calculation_data = await create_calculation(db_session=db_session, calculation_time_constrains_in=calculation_time_constrains_in, created_by=current_user.name)
return StandardResponse(data=str(calculation_data), message="Data created successfully")
if scope_calculation_id:
results = await get_or_create_scope_equipment_calculation(db_session=db_session, scope_calculation_id=scope_calculation_id, calculation_time_constrains_in=calculation_time_constrains_in)
else:
results = await create_calculation(db_session=db_session, calculation_time_constrains_in=calculation_time_constrains_in, created_by=current_user.name)
if not with_results:
results = str(results.id)
return StandardResponse(data=results, message="Data created successfully")
@router.get("/parameters", response_model=StandardResponse[Union[CalculationTimeConstrainsParametersRetrive, CalculationTimeConstrainsParametersRead]])
@ -37,37 +44,23 @@ async def get_calculation_results(db_session: DbSession, calculation_id):
results = await get_calculation_result(db_session=db_session, calculation_id=calculation_id)
return StandardResponse(
data=CalculationTimeConstrainsRead(
id=calculation_id,
results=results
),
data=results,
message="Data retrieved successfully",
)
# @router.post("/parameters", response_model=StandardResponse[str])
# async def create_calculation_time_constrains_parameter(db_session: DbSession, current_user: CurrentUser, calculation_time_constrains_in: CalculationTimeConstrainsParametersCreate):
# """Save parameter Here"""
# parameters = await create_param(db_session=db_session, calculation_param_in=calculation_time_constrains_in, created_by=current_user.name)
# return StandardResponse(data=str(parameters.id), message="Parameter Data created successfully")
# @router.get("/simulation", response_model=StandardResponse[Dict[str, Any]])
# async def get_simulation_result():
# results = {
# "simulation": {
# "intervalDays": 45,
# "numberOfFailures": 75,
# "totalCost": 550000000,
# },
# "comparison": {
# "vsOptimal": {
# "failureDifference": 16,
# "costDifference": 50000000
# },
# }
# }
# return StandardResponse(data=results, message="Data retrieved successfully")
@router.post("/simulation", response_model=StandardResponse[Dict[str, Any]])
async def get_simulation_result():
results = {
"simulation": {
"intervalDays": 45,
"numberOfFailures": 75,
"totalCost": 550000000,
},
"comparison": {
"vsOptimal": {
"failureDifference": 16,
"costDifference": 50000000
},
}
}
return StandardResponse(data=results, message="Data retrieved successfully")

@ -36,10 +36,11 @@ class CalculationTimeConstrainsParametersRead(CalculationTimeConstrainsBase):
class CalculationTimeConstrainsParametersCreate(CalculationTimeConstrainsBase):
overhaulCost: float = Field(..., description="Overhaul cost")
overhaulCost: Optional[float] = Field(0, description="Overhaul cost")
scopeOH: Optional[str] = Field(None, description="Scope OH")
assetnum: Optional[str] = Field(None, description="Assetnum")
costPerFailure: float = Field(..., description="Cost per failure")
costPerFailure: Optional[float] = Field(0,
description="Cost per failure")
# class CalculationTimeConstrainsCreate(CalculationTimeConstrainsBase):
@ -57,7 +58,9 @@ class CalculationResultsRead(CalculationTimeConstrainsBase):
class CalculationTimeConstrainsRead(CalculationTimeConstrainsBase):
id: Union[UUID, str]
reference: str
results: List[CalculationResultsRead]
optimumOh: Dict[str, Any]
class CalculationTimeConstrainsSimulationRead(CalculationTimeConstrainsBase):

@ -1,11 +1,13 @@
from typing import Optional
from uuid import UUID
import numpy as np
from sqlalchemy import select
from sqlalchemy import and_, select
from sqlalchemy.orm import joinedload
from src.database.core import DbSession
from .schema import CalculationTimeConstrainsParametersCreate
from .schema import CalculationTimeConstrainsParametersCreate, CalculationTimeConstrainsRead
from .model import CalculationParam, OverhaulReferenceType, CalculationData, CalculationResult
from fastapi import HTTPException, status
from src.scope.service import get_by_scope_name
from src.scope.service import get_by_scope_name, get
def get_overhaul_cost_by_time_chart(overhaul_cost: float, days: int) -> list:
@ -35,7 +37,7 @@ def get_corrective_cost_time_chart(cost_per_failure: float, days: int) -> list:
return corrective_costs, failure_counts
async def create_param_and_data(*, db_session: DbSession, calculation_param_in: CalculationTimeConstrainsParametersCreate, created_by: str):
async def create_param_and_data(*, db_session: DbSession, calculation_param_in: CalculationTimeConstrainsParametersCreate, created_by: str, parameter_id: Optional[UUID] = None):
"""Creates a new document."""
if calculation_param_in.scopeOH is None and calculation_param_in.assetnum is None:
raise HTTPException(
@ -67,18 +69,37 @@ async def create_param_and_data(*, db_session: DbSession, calculation_param_in:
avg_failure_cost=calculation_param_in.costPerFailure,
overhaul_cost=calculation_param_in.overhaulCost,
created_by=created_by,
params_id=parameter_id
)
return calculationData
async def get_calculation_result(db_session: DbSession, calculation_id: str):
calculation = await get_calculation_data_by_id(db_session=db_session, calculation_id=calculation_id)
reference = calculation.reference_id if calculation.overhaul_reference_type == OverhaulReferenceType.ASSET else await get(db_session=db_session, scope_id=calculation.reference_id)
stmt = select(CalculationResult).filter(
CalculationResult.calculation_data_id == calculation_id).order_by(CalculationResult.day)
results = await db_session.execute(stmt)
return results.scalars().all()
optimum = stmt.filter(CalculationResult.day == calculation.optimum_oh_day)
results = await db_session.execute(stmt)
optimumOh = await db_session.scalar(optimum)
optimumRes = {
"overhaulCost": optimumOh.overhaul_cost,
"correctiveCost": optimumOh.corrective_cost,
"numOfFailures": optimumOh.num_failures,
"days": optimumOh.day
}
return CalculationTimeConstrainsRead(
id=calculation.id,
reference=reference if isinstance(
reference, str) else reference.scope_name,
results=results.scalars().all(),
optimumOh=optimumRes
)
async def get_calculation_data_by_id(db_session: DbSession, calculation_id) -> CalculationData:
@ -87,3 +108,68 @@ async def get_calculation_data_by_id(db_session: DbSession, calculation_id) -> C
result = await db_session.execute(stmt)
return result.unique().scalar()
async def create_calculation_result_service(db_session: DbSession, calculation_id: UUID):
days = 60
calculation = await get_calculation_data_by_id(db_session=db_session, calculation_id=calculation_id)
reference = calculation.reference_id if calculation.overhaul_reference_type == OverhaulReferenceType.ASSET else await get(db_session=db_session, scope_id=calculation.reference_id)
# Parameter
overhaulCost = calculation.parameter.overhaul_cost
costPerFailure = calculation.parameter.avg_failure_cost
overhaul_cost_points = get_overhaul_cost_by_time_chart(
overhaulCost, days=days)
corrective_cost_points, dailyNumberOfFailure = get_corrective_cost_time_chart(
costPerFailure, days)
total_cost = overhaul_cost_points + corrective_cost_points
optimumOHIndex = np.argmin(total_cost)
numbersOfFailure = sum(dailyNumberOfFailure[:optimumOHIndex])
optimum = {
"overhaulCost": float(overhaul_cost_points[optimumOHIndex]),
"correctiveCost": float(corrective_cost_points[optimumOHIndex]),
"numOfFailures": int(numbersOfFailure),
"days": int(optimumOHIndex+1)
}
calculation_results = []
for i in range(days):
result = CalculationResult(
parameter_id=calculation.parameter_id,
calculation_data_id=calculation.id,
day=(i + 1),
corrective_cost=float(corrective_cost_points[i]),
overhaul_cost=float(overhaul_cost_points[i]),
num_failures=int(dailyNumberOfFailure[i]),
)
calculation_results.append(result)
calculation.optimum_oh_day = int(optimumOHIndex+1)
db_session.add_all(calculation_results)
await db_session.commit()
return CalculationTimeConstrainsRead(
id=calculation.id,
reference=reference if isinstance(
reference, str) else reference.scope_name,
results=calculation_results,
optimumOh=optimum
)
async def get_calculation_by_reference_and_parameter(*, db_session: DbSession, calculation_reference_id, parameter_id):
stmt = select(CalculationData).filter(and_(
CalculationData.reference_id == calculation_reference_id,
CalculationData.parameter_id == parameter_id,
))
result = await db_session.execute(stmt)
return result.scalar()

Loading…
Cancel
Save