Compare commits

..

6 Commits

@ -337,6 +337,10 @@ def get_distribution_from_db(parameters: dict, is_repairable: bool = True, best_
if method == "NHPP":
beta = parameters.get("beta", 1.0)
eta = parameters.get("eta", 100000)
if eta < 100:
eta = 15000
return "NHPPTTFF", beta, eta
elif method == "Weibull-2P":
beta = parameters.get("beta", 1.0)
@ -362,18 +366,28 @@ def get_distribution_from_db(parameters: dict, is_repairable: bool = True, best_
sigma = parameters.get("sigma", 1)
return "Lognormal", mu, sigma
elif distribution == "Normal":
mu = parameters.get("mu", 0)
mu = parameters.get("mu", 100000)
sigma = parameters.get("sigma", 1)
if sigma > 1000 or sigma < 0:
sigma = 999
return "Normal", mu, sigma
elif distribution == "Weibull":
# Assuming Weibull parameters are available
beta = parameters.get("beta", 1.0)
eta = parameters.get("eta", 100000)
return "Weibull2", beta, eta
elif distribution == "Exponential-2P":
lambda_val = parameters.get("Lambda", 0.00001)
gamma = parameters.get("gamma", 0)
return "Exponential2", lambda_val, gamma
else:
# Default to Normal
mu = parameters.get("mu", 0)
mu = parameters.get("mu", 100000)
sigma = parameters.get("sigma", 1)
if sigma > 1000 or sigma < 0:
sigma = 999
if mu <=0 :
mu = 19000
return "Normal", mu, sigma
async def update_oh_interval_offset(*, aeros_db_session, overhaul_offset, overhaul_interval, project_name):
@ -594,7 +608,10 @@ async def update_equipment_for_simulation(
eq.setdefault("cmDisP3", 0)
eq.setdefault("relDisP1", 0)
eq.setdefault("relDisP2", 0)
eq.setdefault("relDisP3", 0)
if eq.get("relDisType") == "Normal":
sigma = eq.get("relDisP2", 0)
if sigma > 1000 or sigma < 0:
eq["relDisP2"] = 999
eq["ohDisType"] = "Fixed"
eq["ohDisP1"] = overhaul_duration
@ -618,13 +635,10 @@ async def update_equipment_for_simulation(
)
reqNodeInputs.append(eq)
# await update_node(
# db_session=db_session,
# equipment_nodes=reqNodeInputs,
# project_name=project_name
# )
return reqNodeInputs
return {
"equipment_nodes": reqNodeInputs,
"reliability": results
}
# Optimized individual fetch functions
async def get_equipment_mttr(*, location_tag: str, client: httpx.AsyncClient) -> float:

@ -717,7 +717,11 @@ async def calculate_contribution(
# )
await execute_simulation(
db_session=db_session, simulation_id=simulation.id, sim_data=sim_data, is_saved=True, eq_update=results
db_session=db_session,
simulation_id=simulation.id,
sim_data=sim_data,
is_saved=True,
eq_update=results['reliability']
)
eaf, edh, efficiency_uptime = await calculate_plant_eaf(db_session=db_session, simulation_id=simulation.id)

@ -271,7 +271,7 @@ async def calculate_plant_eaf(
# Calculate manual MO hours (full outage) and MD hours (derating)
manual_mo_outage_hours = 0.0
manual_mo_equiv_hours = 0.0
max_capacity = 630
max_capacity = 550
if manual_mo:
for mo in manual_mo:

@ -46,7 +46,7 @@ def calculate_eaf(
try:
# Calculate lost production
max_capacity = 630
max_capacity = 550
# Calculate total equivalent derate and outage hours
edh = calculate_equivalent_derate_hours(plot_data, max_flow_rate=max_capacity)

@ -41,14 +41,14 @@ class SimulationWorkflow:
await workflow.execute_activity(
execute_update_node,
{"projectName": sim_data['projectName'], "equipment_nodes": results},
{"projectName": sim_data['projectName'], "equipment_nodes": results['equipment_nodes']},
start_to_close_timeout=timedelta(days=1)
)
# 2. Execute simulation
await workflow.execute_activity(
execute_simulation_activity,
{"sim_data": sim_data, "eq_update": results},
{"sim_data": sim_data, "eq_update": results['reliability']},
start_to_close_timeout=timedelta(days=1)
)

@ -63,10 +63,10 @@ async def test_update_equipment_for_simulation_basic():
patch("src.aeros_equipment.service.get_aeros_equipment_by_location_tag", return_value=mock_nodes_data), \
patch("src.aeros_equipment.service.get_asset_batch", return_value=mock_reliability_data), \
patch("src.aeros_equipment.service.update_oh_interval_offset", return_value=None), \
patch("src.aeros_equipment.service.update_node", return_value=None) as mock_update_node:
patch("src.aeros_equipment.service.update_node", return_value=None):
# Run the function
results = await update_equipment_for_simulation(
res = await update_equipment_for_simulation(
db_session=db_session,
aeros_db_session=aeros_db_session,
project_name=project_name,
@ -77,15 +77,14 @@ async def test_update_equipment_for_simulation_basic():
schematic_name=schematic_name
)
results = res['reliability']
equipment_nodes = res['equipment_nodes']
# Assertions
assert "EQ001" in results
assert results["EQ001"]["distribution"] == "Weibull2"
assert results["EQ001"]["oh_duration"] == overhaul_duration
# Check if update_node was called with correct arguments
called_args = mock_update_node.call_args[1]
equipment_nodes = called_args["equipment_nodes"]
# Find EQ001 in equipment_nodes
eq001_node = next(node for node in equipment_nodes if node["equipmentName"] == "EQ001")
assert eq001_node["relDisType"] == "Weibull2"
@ -144,18 +143,20 @@ async def test_update_equipment_for_simulation_custom_input():
patch("src.aeros_equipment.service.update_node", return_value=None):
# Run
results = await update_equipment_for_simulation(
res = await update_equipment_for_simulation(
db_session=db_session,
aeros_db_session=aeros_db_session,
project_name=project_name,
simulation_duration=simulation_duration,
overhaul_duration=overhaul_duration,
overhaul_interval=overhaul_interval,
offset=offset,
overhaul_interval=8000,
offset=0,
schematic_name=schematic_name,
custom_input=custom_input
)
results = res['reliability']
assert "EQ001" in results
assert results["EQ001"]["mttr"] == 10
assert results["EQ001"]["distribution"] == "Exponential2"
@ -200,10 +201,10 @@ async def test_update_equipment_for_simulation_missing_reliability():
patch("src.aeros_equipment.service.get_aeros_equipment_by_location_tag", return_value=mock_nodes_data), \
patch("src.aeros_equipment.service.get_asset_batch", return_value={}), \
patch("src.aeros_equipment.service.update_oh_interval_offset", return_value=None), \
patch("src.aeros_equipment.service.update_node", return_value=None) as mock_update_node:
patch("src.aeros_equipment.service.update_node", return_value=None):
# Run
results = await update_equipment_for_simulation(
res = await update_equipment_for_simulation(
db_session=db_session,
aeros_db_session=aeros_db_session,
project_name=project_name,
@ -214,14 +215,87 @@ async def test_update_equipment_for_simulation_missing_reliability():
schematic_name=schematic_name
)
results = res['reliability']
equipment_nodes = res['equipment_nodes']
assert "EQ_MISSING" in results
# Default values when no reliability data
assert results["EQ_MISSING"]["mttr"] == 0
assert results["EQ_MISSING"]["distribution"] == "Fixed"
# Check defaults in update_node call
called_args = mock_update_node.call_args[1]
eq_node = called_args["equipment_nodes"][0]
# Check defaults in returned equipment_nodes
eq_node = equipment_nodes[0]
assert eq_node["cmDisUnitCode"] == "UHour"
assert eq_node["relDisUnitCode"] == "UHour"
assert eq_node["ohDisUnitCode"] == "UHour"
@pytest.mark.asyncio
async def test_update_equipment_for_simulation_sigma_constraint():
# Mock parameters
db_session = AsyncMock()
aeros_db_session = AsyncMock()
project_name = "TestProject"
simulation_duration = 8760
overhaul_duration = 72
overhaul_interval = 8000
offset = 0
schematic_name = "TestSchematic"
# Mock get_aeros_schematic_by_name
mock_schematic = MagicMock()
mock_schematic.id = 1
# Mock db_session.execute
mock_eq = MagicMock()
mock_eq.location_tag = "EQ_SIGMA"
mock_eq_result = MagicMock()
mock_eq_result.scalars.return_value.all.return_value = [mock_eq]
mock_empty_result = MagicMock()
mock_empty_result.scalars.return_value.all.return_value = []
db_session.execute.side_effect = [
mock_eq_result, # equipments
mock_empty_result, # rbd_group
mock_empty_result # non_repairable
]
# Mock nodes data
mock_nodes_data = [
{"equipmentName": "EQ_SIGMA", "relDisType": "Fixed", "relDisP1": 0}
]
# Mock reliability data with high sigma (> 1000)
mock_reliability_data = {
"EQ_SIGMA": {
"relDisType": "Normal",
"relDisP1": 100, # mu
"relDisP2": 1500, # sigma
"cmDisType": "Fixed",
"cmDisP1": 0,
"cmDisP2": 0
}
}
with patch("src.aeros_equipment.service.get_aeros_schematic_by_name", return_value=mock_schematic), \
patch("src.aeros_equipment.service.get_aeros_equipment_by_location_tag", return_value=mock_nodes_data), \
patch("src.aeros_equipment.service.get_asset_batch", return_value=mock_reliability_data), \
patch("src.aeros_equipment.service.update_oh_interval_offset", return_value=None), \
patch("src.aeros_equipment.service.update_node", return_value=None):
# Run
res = await update_equipment_for_simulation(
db_session=db_session,
aeros_db_session=aeros_db_session,
project_name=project_name,
simulation_duration=simulation_duration,
overhaul_duration=overhaul_duration,
overhaul_interval=overhaul_interval,
offset=offset,
schematic_name=schematic_name
)
# Check if sigma was constrained correctly in returned equipment_nodes
equipment_nodes = res['equipment_nodes']
eq_node = equipment_nodes[0]
assert eq_node["relDisP2"] == 999

Loading…
Cancel
Save