This commit is contained in:
2026-04-30 02:10:15 +03:30
parent 46ba01e4cc
commit e2c70ec8b6
5 changed files with 141 additions and 94 deletions
+33 -11
View File
@@ -30,11 +30,33 @@ DEFAULT_STAGE_LABELS = {
"maturity": "رسیدگی",
}
ENGINE_LABELS = {
"pcse": "موتور شبیه سازی PCSE",
"growth_projection": "موتور برآورد رشد",
}
MODEL_LABELS = {
"growth_projection_v1": "مدل برآورد رشد نسخه ۱",
"wofost": "مدل ووفوست",
}
class GrowthSimulationError(Exception):
pass
def _fa_engine_name(name: str | None) -> str | None:
if not name:
return name
return ENGINE_LABELS.get(name, name)
def _fa_model_name(name: str | None) -> str | None:
if not name:
return name
return MODEL_LABELS.get(name, name)
@dataclass
class GrowthSimulationContext:
farm_uuid: str | None
@@ -469,7 +491,7 @@ def _run_simulation(context: GrowthSimulationContext) -> tuple[dict[str, Any], i
exc,
)
fallback_result = _run_projection_engine(context)
warning = f"Simulation engine failed, fallback projection used: {exc}"
warning = f"موتور شبیه سازی با خطا مواجه شد و برآورد جایگزین استفاده شد: {exc}"
return fallback_result, None, warning
@@ -622,8 +644,8 @@ def run_growth_simulation(payload: dict[str, Any], progress_callback=None) -> di
return {
"plant_name": context.plant_name,
"dynamic_parameters": context.dynamic_parameters,
"engine": simulation_result.get("engine"),
"model_name": simulation_result.get("model_name"),
"engine": _fa_engine_name(simulation_result.get("engine")),
"model_name": _fa_model_name(simulation_result.get("model_name")),
"scenario_id": scenario_id,
"simulation_warning": simulation_error,
"summary_metrics": simulation_result.get("metrics", {}),
@@ -665,7 +687,7 @@ def _build_current_farm_chart_payload(
"title": "تعداد برگ تخمینی",
"subtitle": "وضعیت فعلی",
"amount": round(_estimate_leaf_count(latest_lai), 2),
"unit": "leaf",
"unit": "برگ",
"avatarColor": "success",
"avatarIcon": "tabler-leaf",
},
@@ -673,7 +695,7 @@ def _build_current_farm_chart_payload(
"title": "وزن بیوماس",
"subtitle": "برآورد فعلی",
"amount": round(latest_biomass, 2),
"unit": "kg/ha",
"unit": "کیلوگرم در هکتار",
"avatarColor": "primary",
"avatarIcon": "tabler-chart-bar",
},
@@ -681,7 +703,7 @@ def _build_current_farm_chart_payload(
"title": "وزن محصول",
"subtitle": "برآورد فعلی",
"amount": round(latest_storage, 2),
"unit": "kg/ha",
"unit": "کیلوگرم در هکتار",
"avatarColor": "warning",
"avatarIcon": "tabler-scale",
},
@@ -698,8 +720,8 @@ def _build_current_farm_chart_payload(
return {
"farm_uuid": context.farm_uuid,
"plant_name": context.plant_name,
"engine": simulation_result.get("engine"),
"model_name": simulation_result.get("model_name"),
"engine": _fa_engine_name(simulation_result.get("engine")),
"model_name": _fa_model_name(simulation_result.get("model_name")),
"scenario_id": scenario_id,
"simulation_warning": simulation_warning,
"categories": categories,
@@ -731,7 +753,7 @@ class CurrentFarmChartSimulator:
def simulate(self, *, farm_uuid: str, plant_name: str | None = None) -> dict[str, Any]:
if not farm_uuid:
raise GrowthSimulationError("farm_uuid is required.")
raise GrowthSimulationError("ارسال farm_uuid الزامی است.")
resolved_plant_name = plant_name
if not resolved_plant_name:
@@ -741,10 +763,10 @@ class CurrentFarmChartSimulator:
.first()
)
if sensor is None:
raise GrowthSimulationError("Farm not found.")
raise GrowthSimulationError("مزرعه پیدا نشد.")
plant = sensor.plants.first()
if plant is None:
raise GrowthSimulationError("Plant not found for the selected farm.")
raise GrowthSimulationError("گیاهی برای مزرعه انتخاب شده پیدا نشد.")
resolved_plant_name = plant.name
context = build_growth_context(