2026-03-22 03:08:27 +03:30
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from dashboard_data.remote_sensing import fetch_or_get_ndvi_observation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _ndvi_explanation(observation, ai_bundle: dict | None = None) -> str:
|
|
|
|
|
ai_bundle = ai_bundle or {}
|
|
|
|
|
ai_payload = ai_bundle.get("ndviHealthCard", {}) if isinstance(ai_bundle, dict) else {}
|
|
|
|
|
explanation = ai_payload.get("explanation")
|
|
|
|
|
if isinstance(explanation, str) and explanation.strip():
|
|
|
|
|
return explanation.strip()
|
|
|
|
|
return (
|
|
|
|
|
f"میانگین NDVI مزرعه {observation.mean_ndvi} ثبت شده و کلاس سلامت پوشش گیاهی "
|
|
|
|
|
f"در وضعیت {observation.vegetation_health_class} قرار دارد."
|
|
|
|
|
)
|
2026-03-22 01:09:09 +03:30
|
|
|
|
|
|
|
|
|
|
|
|
|
def build_ndvi_health_card(sensor_id: str, context: dict | None = None, ai_bundle: dict | None = None) -> dict:
|
|
|
|
|
context = context or {}
|
2026-03-22 03:08:27 +03:30
|
|
|
location = context.get("location")
|
|
|
|
|
if location is None:
|
|
|
|
|
return {
|
|
|
|
|
"mean_ndvi": None,
|
|
|
|
|
"ndvi_map": {},
|
|
|
|
|
"vegetation_health_class": None,
|
|
|
|
|
"observation_date": None,
|
|
|
|
|
"satellite_source": None,
|
|
|
|
|
"healthData": [],
|
|
|
|
|
}
|
2026-03-22 01:09:09 +03:30
|
|
|
|
2026-03-22 03:08:27 +03:30
|
|
|
observation = fetch_or_get_ndvi_observation(location)
|
|
|
|
|
if observation is None:
|
|
|
|
|
return {
|
|
|
|
|
"mean_ndvi": None,
|
|
|
|
|
"ndvi_map": {},
|
|
|
|
|
"vegetation_health_class": "Unavailable",
|
|
|
|
|
"observation_date": None,
|
|
|
|
|
"satellite_source": None,
|
|
|
|
|
"healthData": [
|
|
|
|
|
{
|
|
|
|
|
"title": "وضعیت NDVI",
|
|
|
|
|
"value": "داده ماهوارهای موجود نیست",
|
|
|
|
|
"color": "warning",
|
|
|
|
|
"icon": "tabler-satellite-off",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
}
|
2026-03-22 01:09:09 +03:30
|
|
|
|
2026-03-22 03:08:27 +03:30
|
|
|
mean_value = round(observation.mean_ndvi, 2)
|
|
|
|
|
vegetation_class = observation.vegetation_health_class
|
2026-03-22 01:09:09 +03:30
|
|
|
return {
|
2026-03-22 03:08:27 +03:30
|
|
|
"ndviIndex": mean_value,
|
|
|
|
|
"mean_ndvi": mean_value,
|
|
|
|
|
"ndvi_map": observation.ndvi_map,
|
|
|
|
|
"vegetation_health_class": vegetation_class,
|
|
|
|
|
"observation_date": observation.observation_date.isoformat(),
|
|
|
|
|
"satellite_source": observation.satellite_source,
|
2026-03-22 01:09:09 +03:30
|
|
|
"healthData": [
|
|
|
|
|
{
|
2026-03-22 03:08:27 +03:30
|
|
|
"title": "سلامت پوشش گیاهی",
|
|
|
|
|
"value": vegetation_class,
|
|
|
|
|
"color": "success" if mean_value > 0.6 else "warning" if mean_value >= 0.4 else "error",
|
|
|
|
|
"icon": "tabler-plant",
|
2026-03-22 01:09:09 +03:30
|
|
|
},
|
|
|
|
|
{
|
2026-03-22 03:08:27 +03:30
|
|
|
"title": "تاریخ مشاهده",
|
|
|
|
|
"value": observation.observation_date.isoformat(),
|
|
|
|
|
"color": "info",
|
|
|
|
|
"icon": "tabler-calendar",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"title": "تفسیر",
|
|
|
|
|
"value": _ndvi_explanation(observation, ai_bundle=ai_bundle),
|
|
|
|
|
"color": "primary",
|
|
|
|
|
"icon": "tabler-message-2",
|
2026-03-22 01:09:09 +03:30
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
}
|