17 KiB
توضیح location_data/apps.py و farm_data/apps.py
این فایل یک توضیح کوتاه ولی کاربردی از دو فایل تنظیمات اپ Django در پروژه میدهد:
location_data/apps.pyfarm_data/apps.py
همچنین برای فهم بهتر، به فیلدهای مهم مدلهای مرتبط هم اشاره میکند تا معلوم شود این دو app در عمل چه دادههایی را مدیریت میکنند.
1) فایل location_data/apps.py
این فایل AppConfig مربوط به اپ location_data را تعریف میکند.
کلاس اصلی:
class SoilDataConfig(AppConfig):
فیلدها و بخشها
default_auto_field = "django.db.models.BigAutoField"
- مشخص میکند اگر در مدلهای این اپ برای primary key چیزی تعریف نشده باشد، Django بهصورت پیشفرض از
BigAutoFieldاستفاده کند. BigAutoFieldیک شناسه عددی auto-increment بزرگ است.- این گزینه بیشتر برای مدلهایی مفید است که قرار است رکوردهای زیادی داشته باشند.
name = "location_data"
- نام کامل اپ Django است.
- Django با این مقدار اپ را register میکند.
- این مقدار باید با مسیر ماژول اپ یکی باشد.
verbose_name = "Soil Data (SoilGrids)"
- نام نمایشی اپ در Django admin یا جاهایی است که Django نام انسانی اپ را نشان میدهد.
- این مقدار بیشتر جنبه نمایشی دارد و روی منطق برنامه اثر مستقیم ندارد.
propertyها و سرویسها در location_data/apps.py
این فایل فقط metadata اپ را نگه نمیدارد؛ دو سرویس reusable هم از طریق AppConfig در اختیار بقیه پروژه میگذارد.
@cached_property def ndvi_health_service(self)
- این property یک نمونه از
NdviHealthServiceمیسازد. - import آن از فایل
.ndviانجام میشود. - به دلیل
cached_propertyفقط یک بار ساخته میشود و بعد همان instance دوباره استفاده میشود.
کاربرد:
- برای تحلیل یا سرویسهای مرتبط با NDVI
- جلوگیری از ساخت مکرر object
@cached_property def soil_data_adapter(self)
این property adapter مناسب برای داده خاک را بر اساس تنظیمات پروژه انتخاب میکند.
دو adapter پشتیبانی میشوند:
SoilGridsAdapterMockSoilDataAdapter
منطق انتخاب provider
مقدار provider از این setting خوانده میشود:
settings.SOIL_DATA_PROVIDER
اگر وجود نداشته باشد، مقدار پیشفرض:
"mock"
حالت اول: provider == "soilgrids"
در این حالت:
- از
SoilGridsAdapterاستفاده میشود - timeout آن از این setting میآید:
settings.SOILGRIDS_TIMEOUT_SECONDS
اگر این setting هم نباشد، مقدار پیشفرض:
60
یعنی درخواست به provider واقعی SoilGrids حداکثر 60 ثانیه صبر میکند.
حالت دوم: provider == "mock"
در این حالت:
- از
MockSoilDataAdapterاستفاده میشود - delay آن از این setting میآید:
settings.SOIL_MOCK_DELAY_SECONDS
اگر این setting هم نباشد، مقدار پیشفرض:
0.8
یعنی adapter تستی/نمایشی با تاخیر مصنوعی 0.8 ثانیه کار میکند.
حالت نامعتبر
اگر SOIL_DATA_PROVIDER چیزی غیر از soilgrids یا mock باشد:
ValueErrorرخ میدهد- یعنی config پروژه اشتباه است و provider شناخته نشده
ارتباط location_data/apps.py با فیلدهای واقعی داده
این فایل خودش مدل تعریف نمیکند، اما بهصورت مستقیم برای کار با مدلهای اپ location_data استفاده میشود؛ مهمترین آنها اینها هستند:
location_data.models.SoilLocationlocation_data.models.SoilDepthDatalocation_data.models.NdviObservation
فیلدهای مهم SoilLocation
latitude
- عرض جغرافیایی مرکز زمین
- نوع آن
DecimalFieldاست - روی آن index وجود دارد
- این نقطه معمولاً مرکز هندسی مزرعه است، نه لزوماً یکی از گوشههای مرز
longitude
- طول جغرافیایی مرکز زمین
- مثل
latitudeبرای lookup و resolve کردن دادههای خاک استفاده میشود
task_id
- شناسه تسک Celery برای پردازشهای async
- وقتی fetch داده خاک یا پردازش مرتبط در صف باشد، میتوان با این فیلد وضعیت را track کرد
farm_boundary
- مرز مزرعه را بهصورت JSON نگه میدارد
- معمولاً بهشکل
Polygonیا ساختار corner-based ذخیره میشود - این فیلد خیلی مهم است چون فقط یک نقطه center نگه نمیدارید، بلکه شکل کلی زمین هم ثبت میشود
created_at / updated_at
- زمان ایجاد و آخرین بهروزرسانی رکورد
propertyهای مهم SoilLocation
center_latitude
- فقط alias برای
latitudeاست
center_longitude
- فقط alias برای
longitudeاست
is_complete
- بررسی میکند آیا هر سه لایه خاک برای این location ثبت شدهاند یا نه
- شرط آن این است که تعداد
depthsدقیقاً 3 باشد
فیلدهای مهم SoilDepthData
این مدل برای هر location سه رکورد عمق خاک نگه میدارد:
0-5cm5-15cm15-30cm
فیلدهای اصلی:
soil_location: ارتباط بهSoilLocationdepth_label: مشخص میکند داده برای کدام عمق استbdod: چگالی ظاهری خاکcec: ظرفیت تبادل کاتیونیcfvo: حجم قطعات درشت خاکclay: درصد رسnitrogen: مقدار نیتروژنocdوocs: شاخصهای کربن آلیphh2o: pH خاکsand: درصد شنsilt: درصد سیلتsoc: کربن آلی خاکwv0010: رطوبت حجمی در فشار 10 kPawv0033: رطوبت در حدود ظرفیت زراعیwv1500: رطوبت در نقطه پژمردگی دائم
این فیلدها برای شبیهسازی، آبیاری، و تخمین وضعیت واقعی خاک مهم هستند.
فیلدهای مهم NdviObservation
location: ارتباط باSoilLocationobservation_date: تاریخ مشاهدهmean_ndvi: میانگین NDVIndvi_map: داده مکانی NDVIvegetation_health_class: کلاس سلامت پوشش گیاهیsatellite_source: منبع تصویر مثلsentinel-2cloud_cover: درصد پوشش ابرmetadata: داده تکمیلی
نکته مهم: grid بندی زمین انجام میشود
بله، در لایه داده و سنجش از دور، مفهوم grid بندی وجود دارد.
اما این grid بندی در پروژه بیشتر در این دو سطح دیده میشود:
1) grid در NDVI map
در location_data/remote_sensing.py داده NDVI بهصورت grid محاسبه و ذخیره میشود.
یعنی:
- تصویر ماهوارهای به خانههای کوچکتر تقسیم میشود
- برای هر خانه مقدار NDVI محاسبه میشود
- خروجی در
ndvi_mapمعمولاً بهشکل grid نگهداری میشود
این یعنی وضعیت سلامت گیاه فقط بهصورت یک عدد کلی نیست، بلکه میتواند روی بخشهای مختلف زمین map شود.
2) grid/cell در adapter خاک
در location_data/soil_adapters.py هم منطق cell/grid دیده میشود، مخصوصاً در adapterهای mock یا interpolation-based.
یعنی:
- مختصات lat/lon به cellهای شبکهای نگاشت میشود
- در بعضی محاسبات از
grid_xوgrid_yاستفاده میشود - این کمک میکند داده خاک برای ناحیههای نزدیک، رفتار مکانی منطقیتری داشته باشد
نتیجه مهم
خود مدل SoilLocation یک مرکز زمین را نگه میدارد، ولی مرز مزرعه و NDVI grid باعث میشوند سیستم فقط point-based نباشد.
یعنی:
- مرکز زمین برای lookup سریع و اتصال به داده خاک/هوا استفاده میشود
- مرز مزرعه برای شکل واقعی زمین ذخیره میشود
- grid بندی برای تحلیل مکانی، مخصوصاً در NDVI، انجام میشود
مرکز زمین چطور از مرز مزرعه بهدست میآید
در farm_data/services.py از روی farm_boundary، مرکز هندسی polygon محاسبه میشود.
پس flow کلی اینطور است:
- مرز مزرعه ارسال میشود
- polygon نرمال میشود
- centroid هندسی آن محاسبه میشود
- یک
SoilLocationبرای center ساخته یا پیدا میشود - بعد داده خاک، NDVI و هوا به این location متصل میشوند
پس زمین فقط با یک نقطه خام ثبت نمیشود؛ اول مرز دارد، بعد center از روی آن بهدست میآید.
متدهای کمکی location_data/apps.py
get_ndvi_health_service()
- خروجی
self.ndvi_health_serviceرا برمیگرداند - یک accessor ساده برای گرفتن سرویس NDVI است
get_soil_data_adapter()
- خروجی
self.soil_data_adapterرا برمیگرداند - بقیه بخشهای پروژه از این متد برای گرفتن adapter فعال استفاده میکنند /
فیلدها و settingهای مهم مرتبط با location_data/apps.py
فیلدهای AppConfig
default_auto_field: نوع primary key پیشفرض مدلهاname: نام داخلی اپverbose_name: نام نمایشی اپ
settingهای استفادهشده
SOIL_DATA_PROVIDER: انتخاب provider فعال خاکSOILGRIDS_TIMEOUT_SECONDS: timeout برای provider واقعی SoilGridsSOIL_MOCK_DELAY_SECONDS: تاخیر مصنوعی برای provider mock
2) فایل farm_data/apps.py
این فایل AppConfig مربوط به اپ farm_data را تعریف میکند.
کلاس اصلی:
class FarmDataConfig(AppConfig):
فیلدها
default_auto_field = "django.db.models.BigAutoField"
- مثل اپ قبلی، تعیین میکند primary key پیشفرض مدلهای این اپ از نوع
BigAutoFieldباشد.
name = "farm_data"
- نام داخلی و ماژول اپ Django است.
- برای شناسایی اپ در
INSTALLED_APPSو registry داخلی Django استفاده میشود.
label = "sensor_data"
- label داخلی اپ در registry Django است.
- این فیلد زمانی مهم میشود که:
- بخواهید نام registry اپ با
nameفرق داشته باشد - یا از تداخل نام اپها جلوگیری کنید
- بخواهید نام registry اپ با
- در این پروژه، اپ
farm_dataبا label داخلیsensor_dataشناخته میشود.
نکته:
labelباید در کل پروژه یکتا باشد.- این مقدار ممکن است در migrationها، relationها یا lookupهای app registry اثر داشته باشد.
verbose_name = "farm-data"
- نام نمایشی اپ است.
- بیشتر برای admin و نمایش انسانی استفاده میشود.
نکته مهم درباره farm_data/apps.py
برخلاف location_data/apps.py، این فایل:
cached_propertyندارد- service locator ندارد
- adapter یا provider انتخاب نمیکند
یعنی فعلاً فقط نقش config پایه اپ را دارد.
ارتباط farm_data/apps.py با فیلدهای واقعی داده
این app بیشتر دادههای farm-level و sensor-level را نگه میدارد. مهمترین مدلهایش:
farm_data.models.SensorDatafarm_data.models.SensorParameterfarm_data.models.ParameterUpdateLog
فیلدهای مهم SensorData
farm_uuid
- شناسه یکتای مزرعه
- primary key این مدل است
- هر رکورد
SensorDataنماینده یک مزرعه است
center_location
- ارتباط به
location_data.SoilLocation - یعنی این مزرعه به یک location مرکزی وصل است
- از همین نقطه مرکزی برای weather/soil/simulation استفاده میشود
weather_forecast
- ارتباط اختیاری با
weather.WeatherForecast - اگر موجود باشد، forecast منتخب یا آخرین forecast به مزرعه وصل میشود
sensor_payload
- مهمترین فیلد این مدل است
- داده سنسورها بهصورت JSON نگهداری میشود
- ساختار معمول آن شبیه این است:
{
"sensor-7-1": {
"soil_moisture": 25.5,
"soil_temperature": 22.3,
"soil_ph": 7.2
}
}
مزیت این ساختار:
- چند سنسور در یک مزرعه پشتیبانی میشود
- هر سنسور میتواند فیلدهای خاص خودش را داشته باشد
- schema سنسورها rigid نیست
plants
- رابطه چندبهچند با
plant.Plant - یعنی یک farm میتواند چند گیاه مرتبط داشته باشد
irrigation_method
- روش آبیاری انتخابشده برای مزرعه
- برای recommendation و planning مهم است
created_at / updated_at
- زمان ایجاد و آخرین ویرایش رکورد
propertyهای مهم SensorPayloadMixin
مدل SensorData از SensorPayloadMixin ارث میگیرد و این helperها را دارد:
_payload()
- payload را فقط وقتی dict معتبر باشد برمیگرداند
get_sensor_block(sensor_key=None)
- اگر
sensor_keyبدهید، همان بلوک سنسور را برمیگرداند - اگر ندهید، اولین بلوک معتبر را برمیگرداند
get_metric(metric_name, sensor_key=None)
- یک metric خاص را از payload پیدا میکند
- اول در sensor مشخصشده میگردد
- اگر پیدا نشد، در بقیه blockها جستجو میکند
propertyهای آماده
این propertyها shortcut هستند:
soil_moisturesoil_temperaturesoil_phelectrical_conductivitynitrogenphosphoruspotassium
یعنی بهجای parse دستی JSON، مستقیم میتوان این متریکها را خواند.
فیلدهای مهم SensorParameter
این مدل dictionary پارامترهای سنسور را نگه میدارد.
sensor_key
- کلید سنسور مثل
sensor-7-1
code
- کد پارامتر مثل
soil_moisture
name_fa
- نام فارسی پارامتر
unit
- واحد پارامتر مثل
%یاdS/m
data_type
- نوع داده مثل
float,int,string,bool
metadata
- داده تکمیلی برای UI یا validation
- مثلاً:
- بازه مجاز
- توضیح
- تنظیمات نمایش
فیلدهای مهم ParameterUpdateLog
parameter: ارتباط بهSensorParameteraction: نوع عملیات مثلaddedیاmodifiedpayload: خلاصه تغییراتupdated_at: زمان ثبت لاگ
این مدل برای audit و پیگیری تغییرات پارامترها مفید است.
جمعبندی
location_data/apps.py
- هم metadata اپ را نگه میدارد
- هم سرویس و adapter در اختیار پروژه میگذارد
- هم از settingها برای انتخاب provider واقعی یا mock استفاده میکند
- و در عمل با location center، مرز مزرعه، داده لایههای خاک و gridهای NDVI کار میکند
farm_data/apps.py
- فقط config پایه AppConfig را تعریف میکند
- نقش آن بیشتر register کردن اپ با نام و label مشخص است
- اما دادههای اصلی مزرعه مثل
farm_uuid،sensor_payload، گیاه، روش آبیاری و اتصال به center location در مدلهای همین app نگهداری میشوند