""" Modèles de données pour l'application Detection Créé par Marino ATOHOUN - FireWatch AI Project """ from django.db import models from django.utils import timezone import uuid import os def upload_to_images(instance, filename): """Fonction pour définir le chemin d'upload des images""" ext = filename.split('.')[-1] filename = f"{uuid.uuid4()}.{ext}" return os.path.join('uploads/images/', filename) def upload_to_videos(instance, filename): """Fonction pour définir le chemin d'upload des vidéos""" ext = filename.split('.')[-1] filename = f"{uuid.uuid4()}.{ext}" return os.path.join('uploads/videos/', filename) def upload_to_results(instance, filename): """Fonction pour définir le chemin d'upload des résultats""" ext = filename.split('.')[-1] filename = f"result_{uuid.uuid4()}.{ext}" return os.path.join('results/', filename) class Contact(models.Model): """ Modèle pour stocker les messages de contact Par Marino ATOHOUN """ name = models.CharField(max_length=100, verbose_name="Nom") email = models.EmailField(verbose_name="Email") message = models.TextField(verbose_name="Message") created_at = models.DateTimeField(auto_now_add=True, verbose_name="Date de création") is_read = models.BooleanField(default=False, verbose_name="Lu") class Meta: verbose_name = "Contact" verbose_name_plural = "Contacts" ordering = ['-created_at'] def __str__(self): return f"Message de {self.name} ({self.email}) - {self.created_at.strftime('%d/%m/%Y %H:%M')}" class DetectionSession(models.Model): """ Modèle pour stocker les sessions de détection Par Marino ATOHOUN """ DETECTION_TYPES = [ ('image', 'Image'), ('video', 'Vidéo'), ('camera', 'Caméra'), ] session_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) detection_type = models.CharField(max_length=10, choices=DETECTION_TYPES, verbose_name="Type de détection") original_file = models.FileField(upload_to=upload_to_images, null=True, blank=True, verbose_name="Fichier original") result_file = models.FileField(upload_to=upload_to_results, null=True, blank=True, verbose_name="Fichier résultat") created_at = models.DateTimeField(auto_now_add=True, verbose_name="Date de création") processing_time = models.FloatField(null=True, blank=True, verbose_name="Temps de traitement (secondes)") is_processed = models.BooleanField(default=False, verbose_name="Traité") class Meta: verbose_name = "Session de détection" verbose_name_plural = "Sessions de détection" ordering = ['-created_at'] def __str__(self): return f"Session {self.session_id} - {self.get_detection_type_display()} - {self.created_at.strftime('%d/%m/%Y %H:%M')}" class Detection(models.Model): """ Modèle pour stocker les résultats de détection individuels Par Marino ATOHOUN """ DETECTION_CLASSES = [ ('fire', 'Incendie'), ('smoke', 'Fumée'), ('person', 'Personne'), ('intrusion', 'Intrusion'), ('vehicle', 'Véhicule'), ('other', 'Autre'), ] session = models.ForeignKey(DetectionSession, on_delete=models.CASCADE, related_name='detections') class_name = models.CharField(max_length=20, choices=DETECTION_CLASSES, verbose_name="Classe détectée") confidence = models.FloatField(verbose_name="Confiance") bbox_x = models.FloatField(verbose_name="Boîte englobante X") bbox_y = models.FloatField(verbose_name="Boîte englobante Y") bbox_width = models.FloatField(verbose_name="Largeur boîte englobante") bbox_height = models.FloatField(verbose_name="Hauteur boîte englobante") frame_number = models.IntegerField(default=0, verbose_name="Numéro de frame (pour vidéo)") timestamp = models.FloatField(null=True, blank=True, verbose_name="Timestamp (pour vidéo)") class Meta: verbose_name = "Détection" verbose_name_plural = "Détections" ordering = ['-session__created_at', 'frame_number'] def __str__(self): return f"{self.get_class_name_display()} - {self.confidence:.2%} - Session {self.session.session_id}" @property def bbox_dict(self): """Retourne la bounding box sous forme de dictionnaire""" return { 'x': self.bbox_x, 'y': self.bbox_y, 'width': self.bbox_width, 'height': self.bbox_height } class AIModelStatus(models.Model): """ Modèle pour suivre le statut des modèles IA Par Marino ATOHOUN """ MODEL_TYPES = [ ('fire', 'Modèle Incendie'), ('intrusion', 'Modèle Intrusion'), ] model_type = models.CharField(max_length=20, choices=MODEL_TYPES, unique=True, verbose_name="Type de modèle") model_path = models.CharField(max_length=500, verbose_name="Chemin du modèle") is_loaded = models.BooleanField(default=False, verbose_name="Modèle chargé") last_loaded = models.DateTimeField(null=True, blank=True, verbose_name="Dernière fois chargé") model_version = models.CharField(max_length=50, null=True, blank=True, verbose_name="Version du modèle") accuracy = models.FloatField(null=True, blank=True, verbose_name="Précision du modèle") created_at = models.DateTimeField(auto_now_add=True, verbose_name="Date de création") updated_at = models.DateTimeField(auto_now=True, verbose_name="Date de mise à jour") class Meta: verbose_name = "Statut du modèle IA" verbose_name_plural = "Statuts des modèles IA" def __str__(self): status = "Chargé" if self.is_loaded else "Non chargé" return f"{self.get_model_type_display()} - {status}"