🚜 USE CASE #06 - RISQUES CRITIQUES

Engins Mobiles

Détection Proactive des Risques Véhicules & Équipements Mobiles
Mobile Equipment & Vehicle Safety Risk Detection
📋 Contexte Opérationnel / Operational Context

🇫🇷 Français

Les engins mobiles (chariots élévateurs, véhicules lourds, équipements de chantier) représentent une source majeure d'accidents graves en milieu industriel. La surveillance en temps réel des quasi-collisions piétons, des excès de vitesse, du port de la ceinture, des zones à risque d'impacts et de la maintenance préventive est essentielle pour prévenir les incidents mortels.

🇬🇧 English

Mobile equipment (forklifts, heavy vehicles, construction equipment) represents a major source of serious accidents in industrial environments. Real-time monitoring of pedestrian near-misses, speed violations, seatbelt compliance, impact hotspot zones, and preventive maintenance is critical to prevent fatal incidents.

⚠️ Question Métier / Business Question: Comment identifier en temps réel les comportements à risque des engins mobiles et prévenir les collisions avec les piétons? / How to identify high-risk mobile equipment behaviors in real-time and prevent pedestrian collisions?
🕸️ Schéma de Graphe Neo4j / Neo4j Graph Schema
🚜 Architecture SafetyGraph - Engins Mobiles / Mobile Equipment
:Vehicle
🚜
Vehicle
:Worker
👷
Piéton
:Reading
🚨
Speed
:Trip
🛣️
Trajet
:Event
💥
Impact
:Service
🔧
Maintenance
:Zone
📍
Zone
AT
FROM
BY
AT
REQUIRES
AT
Vehicle - Véhicule / Engin mobile
Worker - Travailleur / Piéton
Reading:Speed - Lecture de vitesse
Trip - Trajet / Déplacement
Event:Impact - Événement d'impact
Service - Maintenance préventive
Zone - Zone géographique
⚠️ Requête #1 - Quasi-Collisions Piéton/Engin
🇫🇷 Objectif: Détecter les situations de proximité dangereuse entre véhicules et travailleurs à pied (quasi-collisions).
🇬🇧 Objective: Detect dangerous proximity situations between vehicles and pedestrian workers (near-misses).
💻 Requête Cypher Neo4j
// ⚠️ Détection: Quasi-collisions piéton/véhicule (proximité critique)
// Detection: Pedestrian/vehicle near-misses (critical proximity)

MATCH (v:Vehicle)-[:AT]->(z)-[:PART_OF]->(p {id: $projectId})
MATCH (w:Worker)-[:AT]->(z)
WHERE point.distance(point(v), point(w)) < $proximityM  // Distance critique (ex: 2-3m)
  AND w.timestamp >= $since
WITH v, w, z,
     point.distance(point(v), point(w)) AS distanceMeters,
     COUNT(*) AS nearMissCount
RETURN 
    v.id AS vehicleId,
    v.type AS vehicleType,
    v.operator AS operatorName,
    w.id AS workerId,
    w.name AS workerName,
    z.name AS zoneName,
    round(distanceMeters, 2) AS distanceMeters,
    nearMissCount,
    CASE
        WHEN distanceMeters < 1.0 THEN 'CRITICAL'
        WHEN distanceMeters < 2.0 THEN 'HIGH'
        ELSE 'MEDIUM'
    END AS riskLevel
ORDER BY distanceMeters ASC
📊 Exemple de Résultat / Result Example
{
  "vehicleId": "VEH-2024-FL-0847",
  "vehicleType": "Forklift / Chariot élévateur",
  "operatorName": "Jean Martineau",
  "workerId": "WRK-4783",
  "workerName": "Sophie Dubois",
  "zoneName": "Entrepôt A - Allée 5",
  "distanceMeters": 0.73,  // Moins de 1 mètre!
  "nearMissCount": 1,
  "riskLevel": "CRITICAL",
  "criticalityLevel": "🔴 CRITIQUE / CRITICAL",
  "requiredAction": "Alerte immédiate + coaching sécurité / Immediate alert + safety coaching"
}
🚨 Requête #2 - Vitesses Supérieures à la Limite
🇫🇷 Objectif: Identifier les véhicules circulant à une vitesse supérieure à la limite de la zone ou à la limite globale.
🇬🇧 Objective: Identify vehicles traveling at speeds exceeding the zone limit or global speed limit.
💻 Requête Cypher Neo4j
// 🚨 Détection: Vitesses supérieures à la limite de zone
// Detection: Speeds exceeding zone speed limit

MATCH (r:Reading {type: 'Speed'})-[:FROM]->(v:Vehicle)-[:PART_OF]->(p {id: $projectId})
MATCH (v)-[:AT]->(z)
WHERE r.timestamp >= $since
  AND r.value > coalesce(z.speedLimit, $speedLimit)  // Limite zone ou limite globale
WITH v, z, 
     MAX(r.value) AS maxSpeed,
     AVG(r.value) AS avgSpeed,
     COUNT(r) AS violationCount,
     coalesce(z.speedLimit, $speedLimit) AS limit
RETURN 
    v.id AS vehicleId,
    v.type AS vehicleType,
    v.operator AS operatorName,
    z.name AS zoneName,
    round(maxSpeed, 1) AS maxSpeedKmh,
    round(avgSpeed, 1) AS avgSpeedKmh,
    limit AS speedLimitKmh,
    (maxSpeed - limit) AS excessSpeedKmh,
    violationCount,
    CASE
        WHEN maxSpeed > (limit * 1.5) THEN 'CRITICAL'
        WHEN maxSpeed > (limit * 1.2) THEN 'HIGH'
        ELSE 'MEDIUM'
    END AS riskLevel
ORDER BY excessSpeedKmh DESC
📊 Exemple de Résultat / Result Example
{
  "vehicleId": "VEH-2024-TRK-1293",
  "vehicleType": "Camion lourd / Heavy truck",
  "operatorName": "Michel Gagnon",
  "zoneName": "Zone de chargement B",
  "maxSpeedKmh": 47.3,  // Vitesse maximale enregistrée
  "avgSpeedKmh": 38.7,
  "speedLimitKmh": 20,  // Limite: 20 km/h en zone de chargement
  "excessSpeedKmh": 27.3,  // Dépassement de 27 km/h!
  "violationCount": 14,  // 14 lectures au-dessus de la limite
  "riskLevel": "CRITICAL",
  "criticalityLevel": "🔴 CRITIQUE / CRITICAL",
  "requiredAction": "Suspension immédiate + formation / Immediate suspension + training"
}
🔒 Requête #3 - Départs sans Ceinture de Sécurité
🇫🇷 Objectif: Détecter les trajets de véhicules démarrés sans confirmation du port de la ceinture de sécurité.
🇬🇧 Objective: Detect vehicle trips started without seatbelt confirmation.
💻 Requête Cypher Neo4j
// 🔒 Détection: Départs de véhicules sans ceinture attachée
// Detection: Vehicle trips started without seatbelt fastened

MATCH (trip:Trip)-[:BY]->(v:Vehicle)-[:PART_OF]->(p {id: $projectId})
WHERE NOT (:Event {type: 'SeatbeltOn'})-[:DURING]->(trip)
WITH trip, v,
     duration.between(trip.startTime, trip.endTime) AS tripDuration
RETURN 
    trip.id AS tripId,
    trip.startTime AS startTime,
    trip.endTime AS endTime,
    tripDuration.minutes AS durationMinutes,
    v.id AS vehicleId,
    v.type AS vehicleType,
    v.operator AS operatorName,
    trip.distanceKm AS distanceKm,
    'SEATBELT_NOT_FASTENED' AS violation,
    CASE
        WHEN tripDuration.minutes > 30 THEN 'CRITICAL'
        WHEN tripDuration.minutes > 10 THEN 'HIGH'
        ELSE 'MEDIUM'
    END AS riskLevel
ORDER BY tripDuration.minutes DESC
📊 Exemple de Résultat / Result Example
{
  "tripId": "TRIP-2024-11-04-0847",
  "startTime": "2024-11-04T08:15:00Z",
  "endTime": "2024-11-04T09:03:00Z",
  "durationMinutes": 48,  // 48 minutes sans ceinture!
  "vehicleId": "VEH-2024-VAN-0523",
  "vehicleType": "Camionnette / Van",
  "operatorName": "Pierre Lefebvre",
  "distanceKm": 23.7,
  "violation": "SEATBELT_NOT_FASTENED",
  "riskLevel": "CRITICAL",
  "criticalityLevel": "🔴 CRITIQUE / CRITICAL",
  "requiredAction": "Rencontre disciplinaire + rappel réglementaire / Disciplinary meeting + regulatory reminder"
}
💥 Requête #4 - Hotspots d'Impacts (Zones à Risque)
🇫🇷 Objectif: Identifier les zones géographiques avec le plus grand nombre d'événements d'impact (collisions, chocs).
🇬🇧 Objective: Identify geographic zones with the highest number of impact events (collisions, shocks).
💻 Requête Cypher Neo4j
// 💥 Détection: Zones à forte concentration d'impacts (hotspots)
// Detection: High-impact concentration zones (hotspots)

MATCH (ev:Event {type: 'Impact'})-[:AT]->(z:Zone)-[:PART_OF]->(p {id: $projectId})
WHERE ev.timestamp >= $since
WITH z, 
     COUNT(ev) AS impactCount,
     AVG(ev.severity) AS avgSeverity,
     MAX(ev.severity) AS maxSeverity,
     COLLECT {
         MATCH (ev)-[:INVOLVES]->(v:Vehicle)
         RETURN COUNT(DISTINCT v) AS vehicleCount
     }[0].vehicleCount AS distinctVehicles
RETURN 
    z.id AS zoneId,
    z.name AS zoneName,
    z.type AS zoneType,
    impactCount,
    round(avgSeverity, 2) AS avgSeverity,
    maxSeverity,
    distinctVehicles,
    CASE
        WHEN impactCount >= 10 THEN 'CRITICAL_HOTSPOT'
        WHEN impactCount >= 5 THEN 'HIGH_HOTSPOT'
        WHEN impactCount >= 3 THEN 'MEDIUM_HOTSPOT'
        ELSE 'LOW_RISK'
    END AS hotspotLevel
ORDER BY impactCount DESC
LIMIT 10
📊 Exemple de Résultat / Result Example
{
  "zoneId": "ZONE-INT-A-07",
  "zoneName": "Intersection A-07 (sortie quai)",
  "zoneType": "Intersection / Crossroad",
  "impactCount": 23,  // 23 impacts en 30 jours!
  "avgSeverity": 3.47,  // Sévérité moyenne (sur 10)
  "maxSeverity": 7.2,  // Sévérité maximale observée
  "distinctVehicles": 8,  // 8 véhicules différents impliqués
  "hotspotLevel": "CRITICAL_HOTSPOT",
  "criticalityLevel": "🔴 CRITIQUE / CRITICAL",
  "requiredAction": "Réaménagement zone + signalisation renforcée / Zone redesign + enhanced signage"
}
🔧 Requête #5 - Maintenance Véhicule en Retard
🇫🇷 Objectif: Identifier les véhicules dont la maintenance préventive est en retard (km ou jours dépassés).
🇬🇧 Objective: Identify vehicles with overdue preventive maintenance (km or days exceeded).
💻 Requête Cypher Neo4j
// 🔧 Détection: Maintenance préventive en retard (km ou temps)
// Detection: Overdue preventive maintenance (km or time)

MATCH (v:Vehicle)-[:PART_OF]->(p {id: $projectId})
WHERE coalesce(v.lastServiceKm, 0) + v.serviceIntervalKm < v.currentKm
   OR coalesce(v.lastServiceDate, date('1970-01-01')) + duration({days: v.serviceIntervalDays}) < date()
WITH v,
     v.currentKm - (coalesce(v.lastServiceKm, 0) + v.serviceIntervalKm) AS overdueKm,
     duration.between(
         coalesce(v.lastServiceDate, date('1970-01-01')) + duration({days: v.serviceIntervalDays}),
         date()
     ) AS overdueDuration
RETURN 
    v.id AS vehicleId,
    v.type AS vehicleType,
    v.make + ' ' + v.model AS makeModel,
    v.currentKm AS currentKm,
    v.lastServiceKm AS lastServiceKm,
    v.serviceIntervalKm AS intervalKm,
    v.lastServiceDate AS lastServiceDate,
    v.serviceIntervalDays AS intervalDays,
    overdueKm,
    overdueDuration.days AS overdueDays,
    'MAINTENANCE_OVERDUE' AS violation,
    CASE
        WHEN overdueKm > 5000 OR overdueDuration.days > 180 THEN 'CRITICAL'
        WHEN overdueKm > 2000 OR overdueDuration.days > 90 THEN 'HIGH'
        ELSE 'MEDIUM'
    END AS riskLevel
ORDER BY overdueKm DESC, overdueDuration.days DESC
📊 Exemple de Résultat / Result Example
{
  "vehicleId": "VEH-2024-FL-0312",
  "vehicleType": "Forklift / Chariot élévateur",
  "makeModel": "Toyota 8FGU32",
  "currentKm": 12847,  // Kilométrage actuel
  "lastServiceKm": 5230,  // Dernier entretien à 5230 km
  "intervalKm": 2000,  // Entretien requis tous les 2000 km
  "lastServiceDate": "2023-11-15",
  "intervalDays": 180,  // Entretien requis tous les 6 mois
  "overdueKm": 5617,  // Retard de 5617 km!
  "overdueDays": 174,  // Retard de 174 jours (presque 6 mois)
  "violation": "MAINTENANCE_OVERDUE",
  "riskLevel": "CRITICAL",
  "criticalityLevel": "🔴 CRITIQUE / CRITICAL",
  "requiredAction": "Retrait immédiat du service + entretien urgent / Immediate service removal + urgent maintenance"
}
⚠️ Matrice de Criticité & Actions / Criticality Matrix & Actions
🔴 CRITIQUE / CRITICAL
Violations:
• Proximité piéton < 1m
• Vitesse > 150% limite
• Trajet > 30 min sans ceinture
• Hotspot ≥ 10 impacts
• Maintenance > 5000 km retard

Actions:
• Intervention immédiate
• Retrait équipement / Equipment removal
• Investigation < 1h
🟠 ÉLEVÉ / HIGH
Violations:
• Proximité 1-2m
• Vitesse 120-150% limite
• Trajet 10-30 min sans ceinture
• Hotspot 5-9 impacts
• Maintenance 2000-5000 km retard

Actions:
• Coaching sécurité / Safety coaching
• Planification maintenance
• Correction < 24h
🟡 MOYEN / MEDIUM
Violations:
• Proximité 2-3m
• Vitesse 100-120% limite
• Trajet < 10 min sans ceinture
• Hotspot 3-4 impacts
• Maintenance < 2000 km retard

Actions:
• Rappel procédures / Procedure reminder
• Surveillance accrue
• Correction < 7 jours
🟢 FAIBLE / LOW
Conformité:
• Distances sécuritaires OK
• Vitesses respectées / Speeds compliant
• Ceinture portée / Seatbelt fastened
• Zones sans incidents
• Maintenance à jour / Maintenance current

Actions:
• Monitoring continu
• Reconnaissance / Recognition
📚 Normes & Références / Standards & References
🚜 OSHA 1910.178
🇨🇦 CSA B335
🇨🇦 CNESST Art. 246-256
🌍 ISO 3691
⚠️ ANSI B56
🔧 SAE J1234
🚨 NHTSA FMVSS
📋 ASME B56.1
🏗️ ITA Powered
🇪🇺 EN 16307
📖 OSHA 1910.178 - Powered Industrial Trucks: Port obligatoire de la ceinture pour véhicules équipés. Zones piétonnes séparées. Limites de vitesse affichées. Maintenance préventive documentée. / Mandatory seatbelt use for equipped vehicles. Separated pedestrian zones. Posted speed limits. Documented preventive maintenance.
🤖 Agents AgenticX5 / AI Agents
🚜
FleetAI
FR: Surveillance en temps réel de la flotte complète, détection comportements à risque, analytics prédictives des incidents véhicules.

EN: Real-time full fleet monitoring, risky behavior detection, predictive vehicle incident analytics.
⚠️
ProximityAI
FR: Détection ultra-précise des quasi-collisions piétons-véhicules, alertes immédiates opérateurs et superviseurs.

EN: Ultra-precise pedestrian-vehicle near-miss detection, immediate operator and supervisor alerts.
🚨
SpeedAI
FR: Monitoring continu vitesses par zone, détection excès, scoring conducteurs avec recommandations coaching.

EN: Continuous zone-based speed monitoring, excess detection, driver scoring with coaching recommendations.
🔒
ComplianceAI
FR: Vérification automatique conformité (ceinture, permis, formations), alertes manquements réglementaires.

EN: Automatic compliance verification (seatbelt, permits, training), regulatory violation alerts.
💥
HotspotAI
FR: Cartographie dynamique zones à risque, analyses causales impacts, recommandations réaménagement infrastructures.

EN: Dynamic risk zone mapping, impact root cause analysis, infrastructure redesign recommendations.
🔧
MaintenanceAI
FR: Planification prédictive maintenance basée utilisation réelle, alertes proactives, optimisation cycles entretien.

EN: Predictive maintenance scheduling based on actual usage, proactive alerts, maintenance cycle optimization.