2026-03-22 01:09:09 +03:30
|
|
|
from django.db import models
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DashboardCardSnapshot(models.Model):
|
|
|
|
|
sensor_id = models.UUIDField(db_index=True)
|
|
|
|
|
card_name = models.CharField(max_length=128, db_index=True)
|
|
|
|
|
payload = models.JSONField(default=dict, blank=True)
|
|
|
|
|
generated_at = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
|
|
|
expires_at = models.DateTimeField(db_index=True)
|
|
|
|
|
source = models.CharField(max_length=32, default="computed")
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ["-generated_at"]
|
|
|
|
|
indexes = [
|
|
|
|
|
models.Index(fields=["sensor_id", "card_name", "-generated_at"]),
|
|
|
|
|
]
|
|
|
|
|
verbose_name = "Dashboard Card Snapshot"
|
|
|
|
|
verbose_name_plural = "Dashboard Card Snapshots"
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return f"{self.card_name} - {self.sensor_id} - {self.generated_at}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DashboardAiRequestLog(models.Model):
|
|
|
|
|
sensor_id = models.UUIDField(db_index=True)
|
|
|
|
|
request_payload = models.JSONField(default=dict, blank=True)
|
|
|
|
|
response_payload = models.JSONField(default=dict, blank=True)
|
|
|
|
|
status = models.CharField(max_length=32, default="pending")
|
|
|
|
|
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ["-created_at"]
|
|
|
|
|
verbose_name = "Dashboard AI Request Log"
|
|
|
|
|
verbose_name_plural = "Dashboard AI Request Logs"
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return f"{self.sensor_id} - {self.status} - {self.created_at}"
|
|
|
|
|
|
2026-03-22 03:08:27 +03:30
|
|
|
|
|
|
|
|
class NdviObservation(models.Model):
|
|
|
|
|
location = models.ForeignKey(
|
|
|
|
|
"location_data.SoilLocation",
|
|
|
|
|
on_delete=models.CASCADE,
|
|
|
|
|
related_name="ndvi_observations",
|
|
|
|
|
)
|
|
|
|
|
observation_date = models.DateField(db_index=True)
|
|
|
|
|
mean_ndvi = models.FloatField()
|
|
|
|
|
ndvi_map = models.JSONField(default=dict, blank=True)
|
|
|
|
|
vegetation_health_class = models.CharField(max_length=64)
|
|
|
|
|
satellite_source = models.CharField(max_length=64, default="sentinel-2")
|
|
|
|
|
cloud_cover = models.FloatField(null=True, blank=True)
|
|
|
|
|
metadata = models.JSONField(default=dict, blank=True)
|
|
|
|
|
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ["-observation_date", "-created_at"]
|
|
|
|
|
constraints = [
|
|
|
|
|
models.UniqueConstraint(
|
|
|
|
|
fields=["location", "observation_date", "satellite_source"],
|
|
|
|
|
name="ndvi_unique_location_date_source",
|
|
|
|
|
)
|
|
|
|
|
]
|
|
|
|
|
verbose_name = "NDVI Observation"
|
|
|
|
|
verbose_name_plural = "NDVI Observations"
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return f"NDVI {self.location_id} {self.observation_date} {self.satellite_source}"
|