84 lines
3.7 KiB
Python
84 lines
3.7 KiB
Python
from dashboard_data.card_utils import average, safe_number
|
||
|
||
|
||
def build_farm_overview_kpis(sensor_id: str, context: dict | None = None, ai_bundle: dict | None = None) -> dict:
|
||
context = context or {}
|
||
sensor = context.get("sensor")
|
||
forecasts = context.get("forecasts", [])
|
||
if sensor is None:
|
||
return {"kpis": []}
|
||
|
||
moisture = safe_number(sensor.soil_moisture, 0)
|
||
ph = safe_number(sensor.soil_ph, 7)
|
||
ec = safe_number(sensor.electrical_conductivity, 0)
|
||
humidity = average([forecast.humidity_mean for forecast in forecasts[:3]], default=45)
|
||
health_score = max(0, min(100, round(100 - abs(65 - moisture) - (abs(6.8 - ph) * 10) - (ec * 5))))
|
||
water_stress = max(0, min(100, round(35 - (moisture / 2))))
|
||
disease_risk = max(0, min(100, round((humidity * 0.4) + (safe_number(sensor.soil_temperature, 0) * 0.6) - 20)))
|
||
yield_prediction = round(max(5, (health_score / 2.1)), 1)
|
||
|
||
return {
|
||
"kpis": [
|
||
{
|
||
"id": "farm_health_score",
|
||
"title": "امتیاز سلامت مزرعه",
|
||
"subtitle": "تحلیل هوشمند",
|
||
"stats": f"{health_score}%",
|
||
"avatarColor": "success" if health_score >= 70 else "warning",
|
||
"avatarIcon": "tabler-heartbeat",
|
||
"chipText": "خوب" if health_score >= 70 else "متوسط",
|
||
"chipColor": "success" if health_score >= 70 else "warning",
|
||
},
|
||
{
|
||
"id": "water_stress_index",
|
||
"title": "شاخص تنش آبی",
|
||
"subtitle": "فعلی",
|
||
"stats": f"{water_stress}%",
|
||
"avatarColor": "info",
|
||
"avatarIcon": "tabler-droplet",
|
||
"chipText": "پایین" if water_stress <= 20 else "متوسط",
|
||
"chipColor": "success" if water_stress <= 20 else "warning",
|
||
},
|
||
{
|
||
"id": "disease_risk",
|
||
"title": "ریسک بیماری",
|
||
"subtitle": "۷ روز اخیر",
|
||
"stats": "پایین" if disease_risk < 30 else "متوسط",
|
||
"avatarColor": "success" if disease_risk < 30 else "warning",
|
||
"avatarIcon": "tabler-bug",
|
||
"chipText": f"{disease_risk}%",
|
||
"chipColor": "success" if disease_risk < 30 else "warning",
|
||
},
|
||
{
|
||
"id": "avg_soil_moisture",
|
||
"title": "میانگین رطوبت خاک",
|
||
"subtitle": "کل مزرعه",
|
||
"stats": f"{round(moisture)}%",
|
||
"avatarColor": "primary",
|
||
"avatarIcon": "tabler-plant-2",
|
||
"chipText": "بهینه" if 45 <= moisture <= 75 else "نیازمند بررسی",
|
||
"chipColor": "success" if 45 <= moisture <= 75 else "warning",
|
||
},
|
||
{
|
||
"id": "yield_prediction",
|
||
"title": "پیشبینی عملکرد",
|
||
"subtitle": "این فصل",
|
||
"stats": f"{yield_prediction} تن",
|
||
"avatarColor": "secondary",
|
||
"avatarIcon": "tabler-chart-bar",
|
||
"chipText": f"+{max(0, health_score - 50)}%",
|
||
"chipColor": "success",
|
||
},
|
||
{
|
||
"id": "pest_risk",
|
||
"title": "ریسک آفات",
|
||
"subtitle": "پیشبینی هوشمند",
|
||
"stats": f"{max(5, round(disease_risk * 0.7))}%",
|
||
"avatarColor": "warning",
|
||
"avatarIcon": "tabler-bug-off",
|
||
"chipText": "تحت نظر",
|
||
"chipColor": "warning",
|
||
},
|
||
]
|
||
}
|