11 KiB
ارتباط سرویسها با Plant و گیاهان
این سند توضیح میدهد که در پروژه، دادهی گیاه از کجا میآید، چطور در farm_data نگهداری میشود، چگونه به سرویسهای crop_simulation میرسد و در نهایت چطور در location_data برای پیشنهاد گیاه هر کلاستر استفاده میشود.
نمای کلی
در این پروژه سه لایه اصلی برای کار با گیاه وجود دارد:
plantfarm_datacrop_simulationوlocation_data
نقش هر لایه:
plant: مرجع canonical نام گیاه و aliasها است.farm_data: نسخه snapshot شدهی گیاهان Backend و assignment هر مزرعه به گیاهها را نگه میدارد.crop_simulation: از گیاه انتخابشده برای ساخت ورودی شبیهسازی استفاده میکند.location_data: دادهی کلاسترهای KMeans را با گیاههای مزرعه ترکیب میکند و پیشنهاد گیاه میسازد.
1) لایه plant
اپ plant مرجع اصلی برای resolve کردن نام گیاه است.
فایل مهم:
plant/apps.py
تابع مهم:
resolve_plant_name
رفتار این تابع:
- نام ورودی را میگیرد.
- اگر همان نام در جدول
plant.Plantوجود داشته باشد، همان را برمیگرداند. - اگر alias برای آن تعریف شده باشد، alias را به نام canonical تبدیل میکند.
- اگر از نظر نرمالسازی متنی با یک گیاه match شود، همان نام canonical را برمیگرداند.
در نتیجه:
- ورودیهایی مثل
plant_name،cropیاcrop_nameقبل از ورود به شبیهسازی، به نام استاندارد تبدیل میشوند.
2) لایه farm_data
اپ farm_data مدل read-model مربوط به گیاهان هر مزرعه را نگه میدارد.
مدلهای اصلی:
farm_data.models.PlantCatalogSnapshotfarm_data.models.FarmPlantAssignmentfarm_data.models.SensorData
PlantCatalogSnapshot
این مدل کپی محلی و خواندنی از کاتالوگ گیاه Backend است.
اطلاعاتی که در آن نگهداری میشود:
- نام گیاه
- توضیحات
growth_profileirrigation_profilehealth_profile- فصل کاشت، زمان برداشت، فاصله کاشت، کود و ...
این مدل منبع اصلی هوش مصنوعی برای خواندن پروفایل گیاه است، نه relation قدیمی SensorData.plants.
FarmPlantAssignment
این مدل مشخص میکند هر مزرعه چه گیاههایی دارد.
فیلدهای مهم:
farmplantpositionstagemetadata
یعنی هر مزرعه میتواند چند گیاه داشته باشد و ترتیب و مرحله رشد هرکدام هم ثبت میشود.
توابع مهم در farm_data/services.py
فایل مهم:
farm_data/services.py
توابع کلیدی:
sync_plant_catalog_from_backendassign_farm_plants_from_backend_idsget_farm_plant_assignmentsget_farm_plant_snapshotsget_primary_plant_snapshotget_farm_plant_snapshot_by_nameclone_snapshot_as_runtime_plantget_runtime_plant_for_farmlist_runtime_plants_for_farm
جریان داده در farm_data
- کاتالوگ گیاه از Backend خوانده میشود و داخل
PlantCatalogSnapshotذخیره میشود. - گیاههای انتخابشدهی هر مزرعه با
FarmPlantAssignmentثبت میشوند. - اگر سرویس شبیهسازی یک
plant_nameمشخص بگیرد، همان گیاه از assignmentها پیدا میشود. - اگر
plant_nameارسال نشود، گیاه اول مزرعه به عنوان پیشفرض انتخاب میشود.
Runtime Plant
تابع get_runtime_plant_for_farm یک snapshot را به یک object سبک runtime تبدیل میکند تا downstream serviceها بدون وابستگی مستقیم به مدل DB از آن استفاده کنند.
این object شامل فیلدهایی مثل:
namegrowth_profileirrigation_profilehealth_profileplanting_seasonharvest_time
است.
3) ورود گیاه به crop_simulation
فایلهای مهم:
crop_simulation/services.pycrop_simulation/growth_simulation.pycrop_simulation/harvest_prediction.pycrop_simulation/yield_prediction.py
build_simulation_payload_from_farm
مهمترین نقطه اتصال بین farm_data و crop_simulation این تابع است:
crop_simulation.services.build_simulation_payload_from_farm
این تابع:
- مزرعه را با
get_canonical_farm_recordپیدا میکند. - گیاه را با
get_runtime_plant_for_farmresolve میکند. - snapshot هوش مصنوعی مزرعه را میخواند.
- weather, soil, site_parameters را میسازد.
- از پروفایل گیاه،
crop_parametersو در صورت وجودagromanagementپیشفرض را استخراج میکند.
خروجی این تابع شامل این بخشهاست:
plantruntime_plantsweathersoilsite_parameterscrop_parametersagromanagement
یعنی تمام چیزی که موتور شبیهسازی لازم دارد.
استفاده در Growth Simulation
در crop_simulation/growth_simulation.py اگر farm_uuid داده شود:
build_growth_contextازbuild_simulation_payload_from_farmاستفاده میکند.- گیاه انتخابشده وارد context میشود.
- سپس شبیهسازی PCSE یا fallback projection روی همان گیاه اجرا میشود.
استفاده در Harvest Prediction
در crop_simulation/harvest_prediction.py اگر plant_name ارسال نشود:
- سرویس با
get_runtime_plant_for_farmگیاه پیشفرض مزرعه را پیدا میکند. - سپس از همان گیاه برای محاسبهی GDD و پیشبینی برداشت استفاده میشود.
استفاده در Yield Prediction
در crop_simulation/yield_prediction.py:
- سرویس chart فعلی مزرعه را صدا میزند.
- chart هم قبلاً گیاه را از مسیر canonical مزرعه resolve کرده است.
- بنابراین yield همیشه روی یک گیاه مشخص از assignmentهای مزرعه محاسبه میشود.
4) نقش serializerها در resolve کردن نام گیاه
فایل مهم:
crop_simulation/serializers.py
کلاس مهم:
PlantNameAliasMixin
این mixin:
plant_namecropcrop_name
را قبول میکند و با apps.get_app_config("plant").resolve_plant_name(...) آن را canonical میکند.
پس حتی اگر کلاینت نام گیاه را با alias بفرستد، سرویس شبیهسازی با نام استاندارد کار میکند.
5) ارتباط location_data با گیاهها
فایل مهم:
location_data/cluster_recommendation.py
تابع اصلی:
build_cluster_crop_recommendations
این تابع ارتباط بین کلاسترهای KMeans و گیاههای مزرعه را میسازد.
ورودی
farm_uuid
کارهایی که انجام میدهد
- مزرعه را از
farm_dataپیدا میکند. - لیست گیاههای ثبتشده را با
get_farm_plant_assignmentsمیخواند. - snapshot کلاسترهای
location_dataرا میگیرد. - برای هر گیاه ثبتشده، با
build_simulation_payload_from_farmیک payload پایه میسازد. - برای هر کلاستر:
- متریکهای همان کلاستر مثل
ndvi,ndwi,soil_vv,soil_vv_dbرا جمع میکند. - پارامترهای soil/site را با داده همان کلاستر override میکند.
- برای تکتک گیاههای مزرعه شبیهسازی اجرا میکند.
- خروجیها را بر اساس
yield_estimateرتبهبندی میکند.
- متریکهای همان کلاستر مثل
- بهترین گیاه را به عنوان
suggested_plantبرمیگرداند.
نتیجه
location_data خودش مرجع گیاه نیست؛ فقط:
- گیاهها را از
farm_data - نام canonical را از
plant - منطق شبیهسازی را از
crop_simulation
میگیرد و روی دادههای کلاستر اعمال میکند.
6) ترتیب مسئولیتها
برای جلوگیری از ابهام، مسئولیت هر بخش این است:
-
plant:- canonical name
- alias resolving
-
farm_data:- snapshot گیاه
- assignment گیاه به مزرعه
- تبدیل snapshot به runtime plant
-
crop_simulation:- ساخت payload شبیهسازی از مزرعه و گیاه
- اجرای شبیهسازی رشد، عملکرد و برداشت
-
location_data:- خواندن کلاسترهای KMeans
- مقایسه گیاههای مزرعه برای هر کلاستر
- پیشنهاد گیاه برای sub-block
7) نکات مهم طراحی
- relation قدیمی
SensorData.plantsمسیر legacy است و منبع canonical نیست. - مسیر canonical برای گیاههای مزرعه،
FarmPlantAssignmentوPlantCatalogSnapshotاست. - سرویسهای شبیهسازی نباید مستقیم از
plant.Plantبرای گیاه مزرعه استفاده کنند؛ مسیر درست،farm_data.services.get_runtime_plant_for_farmاست. - اگر
plant_nameصریح داده نشود، معمولاً گیاه اول assignmentهای مزرعه انتخاب میشود. - اگر چند گیاه برای مزرعه ثبت شده باشد، endpoint پیشنهاد کلاستر همهی آنها را compare میکند.
8) خلاصه جریان end-to-end
جریان کامل به این صورت است:
- Backend plant catalog ->
PlantCatalogSnapshot - farm selected plants ->
FarmPlantAssignment - client request with
farm_uuid - farm -> runtime plant resolution
- runtime plant + farm metrics -> simulation payload
- simulation payload -> PCSE/projection
- cluster metrics + plant candidates -> recommended crop per cluster
9) فایلهای کلیدی برای مرور سریع
plant/apps.pyfarm_data/models.pyfarm_data/services.pycrop_simulation/services.pycrop_simulation/growth_simulation.pycrop_simulation/harvest_prediction.pycrop_simulation/yield_prediction.pylocation_data/cluster_recommendation.py