File size: 5,731 Bytes
aac4780
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
"""Modèles Pydantic pour le MCP Server ADEME."""

from pydantic import BaseModel, Field
from typing import Any


class EmissionFactor(BaseModel):
    """Facteur d'émission unifié (AGRIBALYSE ou Base Carbone)."""
    
    source: str = Field(description="Source: 'agribalyse' ou 'base_carbone'")
    id: str = Field(description="Identifiant unique")
    name: str = Field(description="Nom en français")
    value: float = Field(description="Valeur du FE en kgCO2e")
    unit: str = Field(description="Unité (kgCO2e/kg, kgCO2e/km, etc.)")
    category: str = Field(description="Catégorie")
    
    # Qualité
    uncertainty: float | None = Field(default=None, description="Incertitude en %")
    dqr: float | None = Field(default=None, description="Data Quality Rating (1-5)")
    
    # Métadonnées
    methodology_source: str | None = Field(default=None, description="Source méthodologique")
    validity_period: str | None = Field(default=None, description="Période de validité")
    status: str | None = Field(default=None, description="Statut (Valide, Archivé)")


class FoodItem(BaseModel):
    """Aliment AGRIBALYSE avec impacts environnementaux."""
    
    code_ciqual: int = Field(description="Code CIQUAL")
    code_agb: str = Field(description="Code AGRIBALYSE")
    name_fr: str = Field(description="Nom en français")
    name_en: str | None = Field(default=None, description="Nom en anglais")
    
    group: str = Field(description="Groupe d'aliment")
    subgroup: str = Field(description="Sous-groupe d'aliment")
    
    # Impact climatique
    climate_change: float = Field(description="Impact changement climatique (kgCO2e/kg)")
    climate_change_fossil: float | None = Field(default=None, description="Émissions fossiles")
    climate_change_biogenic: float | None = Field(default=None, description="Émissions biogéniques")
    climate_change_land_use: float | None = Field(default=None, description="Changement d'affectation des sols")
    
    # Score global
    ef_score: float | None = Field(default=None, description="Score unique EF")
    dqr: float | None = Field(default=None, description="Data Quality Rating")
    
    # Contexte
    delivery: str | None = Field(default=None, description="Mode de livraison")
    preparation: str | None = Field(default=None, description="Mode de préparation")
    packaging: str | None = Field(default=None, description="Type d'emballage")
    by_plane: bool = Field(default=False, description="Transport par avion")


class TransportFactor(BaseModel):
    """Facteur d'émission transport."""
    
    id: str
    vehicle_type: str = Field(description="Type de véhicule")
    fuel_type: str | None = Field(default=None, description="Type de carburant")
    attribute: str | None = Field(default=None, description="Attribut (tonnage, etc.)")
    
    value: float = Field(description="Valeur en kgCO2e")
    unit: str = Field(description="Unité (kgCO2e/km, kgCO2e/t.km, etc.)")
    
    uncertainty: float | None = Field(default=None, description="Incertitude %")
    source: str | None = Field(default=None, description="Source")
    status: str | None = Field(default=None, description="Statut")


class EnergyFactor(BaseModel):
    """Facteur d'émission énergie."""
    
    id: str
    energy_type: str = Field(description="Type d'énergie")
    specification: str | None = Field(default=None, description="Spécification")
    
    value: float = Field(description="Valeur en kgCO2e")
    unit: str = Field(description="Unité (kgCO2e/kWh, kgCO2e/kg, etc.)")
    
    # Décomposition par gaz
    co2_fossil: float | None = Field(default=None, description="CO2 fossile")
    co2_biogenic: float | None = Field(default=None, description="CO2 biogénique")
    ch4: float | None = Field(default=None, description="Méthane")
    n2o: float | None = Field(default=None, description="Protoxyde d'azote")
    
    uncertainty: float | None = Field(default=None, description="Incertitude %")
    source: str | None = Field(default=None, description="Source")


class WasteFactor(BaseModel):
    """Facteur d'émission déchets."""
    
    id: str
    waste_type: str = Field(description="Type de déchet")
    treatment: str = Field(description="Traitement (compost, incinération, etc.)")
    
    value: float = Field(description="Valeur en kgCO2e/tonne")
    unit: str = Field(default="kgCO2e/tonne", description="Unité")
    
    # Décomposition par gaz
    co2_fossil: float | None = None
    co2_biogenic: float | None = None
    ch4: float | None = None
    n2o: float | None = None
    
    uncertainty: float | None = None
    source: str | None = None


class ComparisonResult(BaseModel):
    """Résultat de comparaison entre 2 facteurs d'émission."""
    
    factor1: EmissionFactor
    factor2: EmissionFactor
    
    absolute_difference: float = Field(description="Différence absolue (FE2 - FE1)")
    relative_difference: float = Field(description="Différence relative en %")
    
    # Analyse
    lower_bound_diff: float | None = Field(
        default=None,
        description="Différence min compte tenu des incertitudes"
    )
    upper_bound_diff: float | None = Field(
        default=None,
        description="Différence max compte tenu des incertitudes"
    )
    
    recommendation: str | None = Field(
        default=None,
        description="Recommandation d'usage"
    )


class SearchResult(BaseModel):
    """Résultat de recherche unifiée."""
    
    total: int = Field(description="Nombre total de résultats")
    results: list[EmissionFactor] = Field(description="Facteurs d'émission trouvés")
    sources: dict[str, int] = Field(
        description="Nombre de résultats par source"
    )