Arpit-Bansal commited on
Commit
026e398
·
1 Parent(s): c7ea7db

aligning with backend

Browse files
api/greedyoptim_api.py CHANGED
@@ -53,7 +53,7 @@ app.add_middleware(
53
  class TrainsetStatusInput(BaseModel):
54
  """Single trainset operational status"""
55
  trainset_id: str
56
- operational_status: str = Field(..., description="Available, In-Service, Maintenance, Standby, Out-of-Order")
57
  last_maintenance_date: Optional[str] = None
58
  total_mileage_km: Optional[float] = None
59
  age_years: Optional[float] = None
@@ -63,7 +63,7 @@ class FitnessCertificateInput(BaseModel):
63
  """Fitness certificate for a trainset"""
64
  trainset_id: str
65
  department: str = Field(..., description="Safety, Operations, Technical, Electrical, Mechanical")
66
- status: str = Field(..., description="Valid, Expired, Expiring-Soon, Suspended")
67
  issue_date: Optional[str] = None
68
  expiry_date: Optional[str] = None
69
 
@@ -82,7 +82,7 @@ class ComponentHealthInput(BaseModel):
82
  """Component health status"""
83
  trainset_id: str
84
  component: str = Field(..., description="Brakes, HVAC, Doors, Propulsion, etc.")
85
- status: str = Field(..., description="Good, Fair, Warning, Critical")
86
  wear_level: Optional[float] = Field(None, ge=0, le=100)
87
  last_inspection: Optional[str] = None
88
 
 
53
  class TrainsetStatusInput(BaseModel):
54
  """Single trainset operational status"""
55
  trainset_id: str
56
+ operational_status: str = Field(..., description="IN_SERVICE, STANDBY, MAINTENANCE, OUT_OF_SERVICE, TESTING (or legacy: Available, In-Service, Maintenance, Standby, Out-of-Order)")
57
  last_maintenance_date: Optional[str] = None
58
  total_mileage_km: Optional[float] = None
59
  age_years: Optional[float] = None
 
63
  """Fitness certificate for a trainset"""
64
  trainset_id: str
65
  department: str = Field(..., description="Safety, Operations, Technical, Electrical, Mechanical")
66
+ status: str = Field(..., description="ISSUED, EXPIRED, SUSPENDED, PENDING, IN_PROGRESS, REVOKED, RENEWED, CANCELLED (or legacy: Valid, Expired, Expiring-Soon, Suspended)")
67
  issue_date: Optional[str] = None
68
  expiry_date: Optional[str] = None
69
 
 
82
  """Component health status"""
83
  trainset_id: str
84
  component: str = Field(..., description="Brakes, HVAC, Doors, Propulsion, etc.")
85
+ status: str = Field(..., description="EXCELLENT, GOOD, FAIR, POOR, CRITICAL, FAILED (or legacy: Good, Fair, Warning, Critical)")
86
  wear_level: Optional[float] = Field(None, ge=0, le=100)
87
  last_inspection: Optional[str] = None
88
 
greedyOptim/error_handling.py CHANGED
@@ -37,11 +37,57 @@ class DataValidator:
37
  'component_health': ['trainset_id', 'component', 'status']
38
  }
39
 
 
40
  VALID_STATUSES = {
41
- 'operational': ['Available', 'In-Service', 'Maintenance', 'Standby', 'Out-of-Order'],
42
- 'certificate': ['Valid', 'Expired', 'Expiring-Soon', 'Suspended'],
 
 
 
 
 
 
 
 
 
 
 
43
  'job': ['Open', 'In-Progress', 'Closed', 'Pending-Parts'],
44
- 'component': ['Good', 'Fair', 'Warning', 'Critical']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
46
 
47
  @classmethod
 
37
  'component_health': ['trainset_id', 'component', 'status']
38
  }
39
 
40
+ # Accept both legacy and new backend formats
41
  VALID_STATUSES = {
42
+ 'operational': [
43
+ # Legacy format
44
+ 'Available', 'In-Service', 'Maintenance', 'Standby', 'Out-of-Order',
45
+ # New backend format
46
+ 'IN_SERVICE', 'STANDBY', 'MAINTENANCE', 'OUT_OF_SERVICE', 'TESTING'
47
+ ],
48
+ 'certificate': [
49
+ # Legacy format
50
+ 'Valid', 'Expired', 'Expiring-Soon', 'Suspended',
51
+ # New backend format
52
+ 'PENDING', 'IN_PROGRESS', 'ISSUED', 'EXPIRED', 'SUSPENDED',
53
+ 'REVOKED', 'RENEWED', 'CANCELLED'
54
+ ],
55
  'job': ['Open', 'In-Progress', 'Closed', 'Pending-Parts'],
56
+ 'component': [
57
+ # Legacy format
58
+ 'Good', 'Fair', 'Warning', 'Critical',
59
+ # New backend format
60
+ 'EXCELLENT', 'GOOD', 'FAIR', 'POOR', 'CRITICAL', 'FAILED'
61
+ ]
62
+ }
63
+
64
+ # Mapping from backend format to internal format for optimization logic
65
+ STATUS_MAPPINGS = {
66
+ 'operational': {
67
+ 'IN_SERVICE': 'In-Service',
68
+ 'STANDBY': 'Standby',
69
+ 'MAINTENANCE': 'Maintenance',
70
+ 'OUT_OF_SERVICE': 'Out-of-Order',
71
+ 'TESTING': 'Maintenance', # Treat testing as maintenance for optimization
72
+ },
73
+ 'certificate': {
74
+ 'PENDING': 'Expiring-Soon',
75
+ 'IN_PROGRESS': 'Expiring-Soon',
76
+ 'ISSUED': 'Valid',
77
+ 'EXPIRED': 'Expired',
78
+ 'SUSPENDED': 'Suspended',
79
+ 'REVOKED': 'Expired',
80
+ 'RENEWED': 'Valid',
81
+ 'CANCELLED': 'Expired',
82
+ },
83
+ 'component': {
84
+ 'EXCELLENT': 'Good',
85
+ 'GOOD': 'Good',
86
+ 'FAIR': 'Fair',
87
+ 'POOR': 'Warning',
88
+ 'CRITICAL': 'Critical',
89
+ 'FAILED': 'Critical',
90
+ }
91
  }
92
 
93
  @classmethod
greedyOptim/evaluator.py CHANGED
@@ -9,6 +9,38 @@ from typing import Dict, List, Tuple, Optional
9
  from .models import OptimizationConfig, TrainsetConstraints
10
 
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  class TrainsetSchedulingEvaluator:
13
  """Multi-objective evaluator for trainset scheduling optimization."""
14
 
@@ -68,7 +100,9 @@ class TrainsetSchedulingEvaluator:
68
  has_valid_certs = True
69
  if trainset_id in self.fitness_map:
70
  for dept, cert in self.fitness_map[trainset_id].items():
71
- if cert['status'] in ['Expired']:
 
 
72
  has_valid_certs = False
73
  break
74
  try:
@@ -94,7 +128,9 @@ class TrainsetSchedulingEvaluator:
94
  component_warnings = []
95
  if trainset_id in self.health_map:
96
  for health in self.health_map[trainset_id]:
97
- if health['status'] == 'Warning' and health['wear_level'] > 90:
 
 
98
  component_warnings.append(health['component'])
99
 
100
  # Check maintenance status
 
9
  from .models import OptimizationConfig, TrainsetConstraints
10
 
11
 
12
+ # Status normalization mappings (backend format -> internal format)
13
+ CERTIFICATE_STATUS_MAP = {
14
+ 'PENDING': 'Expiring-Soon',
15
+ 'IN_PROGRESS': 'Expiring-Soon',
16
+ 'ISSUED': 'Valid',
17
+ 'EXPIRED': 'Expired',
18
+ 'SUSPENDED': 'Suspended',
19
+ 'REVOKED': 'Expired',
20
+ 'RENEWED': 'Valid',
21
+ 'CANCELLED': 'Expired',
22
+ }
23
+
24
+ COMPONENT_STATUS_MAP = {
25
+ 'EXCELLENT': 'Good',
26
+ 'GOOD': 'Good',
27
+ 'FAIR': 'Fair',
28
+ 'POOR': 'Warning',
29
+ 'CRITICAL': 'Critical',
30
+ 'FAILED': 'Critical',
31
+ }
32
+
33
+
34
+ def normalize_certificate_status(status: str) -> str:
35
+ """Normalize certificate status to internal format."""
36
+ return CERTIFICATE_STATUS_MAP.get(status, status)
37
+
38
+
39
+ def normalize_component_status(status: str) -> str:
40
+ """Normalize component status to internal format."""
41
+ return COMPONENT_STATUS_MAP.get(status, status)
42
+
43
+
44
  class TrainsetSchedulingEvaluator:
45
  """Multi-objective evaluator for trainset scheduling optimization."""
46
 
 
100
  has_valid_certs = True
101
  if trainset_id in self.fitness_map:
102
  for dept, cert in self.fitness_map[trainset_id].items():
103
+ # Normalize status to handle both legacy and backend formats
104
+ status = normalize_certificate_status(cert['status'])
105
+ if status in ['Expired']:
106
  has_valid_certs = False
107
  break
108
  try:
 
128
  component_warnings = []
129
  if trainset_id in self.health_map:
130
  for health in self.health_map[trainset_id]:
131
+ # Normalize status to handle both legacy and backend formats
132
+ status = normalize_component_status(health['status'])
133
+ if status in ['Warning', 'Critical'] and health.get('wear_level', 0) > 90:
134
  component_warnings.append(health['component'])
135
 
136
  # Check maintenance status