Détection proactive des incompatibilités de stockage, dépassements de VLE, contenants ouverts et proximité des kits de déversement via graphes de connaissances Neo4j
FR: Détecte les produits chimiques incompatibles stockés à proximité (acides près de bases, oxydants près de combustibles). Utilise la propriété group (ISO 14001, NFPA 704) et calculs géospatiaux.
EN: Detects incompatible chemicals stored in proximity (acids near bases, oxidizers near fuels). Uses group property (ISO 14001, NFPA 704) and geospatial calculations.
// 🚨 REQUÊTE #1 - Stockage Incompatible / Incompatible Storage MATCH (a:Chemical)-[:STORED_IN]->(z1:Zone)-[:PART_OF]->(p:Project{id:$projectId}), (b:Chemical)-[:STORED_IN]->(z2:Zone) // ☣️ Groupes incompatibles (NFPA 704, ISO 14001) WHERE a.group IN ['Acid', 'Oxidizer'] AND b.group IN ['Base', 'Fuel'] // 📏 Distance géospatiale < seuil minimum de séparation AND distance(point(z1), point(z2)) < $minSeparationM RETURN a.name AS chemical_A, a.group AS group_A, b.name AS chemical_B, b.group AS group_B, z1.name AS zone_A, z2.name AS zone_B, round(distance(point(z1), point(z2)), 2) AS distance_m, 'CRITIQUE' AS severity ORDER BY distance_m ASC
// 📊 Exemple de sortie JSON { "chemical_A": "Acide sulfurique 98%", "group_A": "Acid", "chemical_B": "Hydroxyde de sodium 50%", "group_B": "Base", "zone_A": "Entrepôt-Nord-A3", "zone_B": "Entrepôt-Nord-A5", "distance_m": 2.4, // < 6m minimum requis "severity": "CRITIQUE" }
⚡ Action: Arrêt immédiat, relocalisation urgente, signalisation périmètre exclusion
📏 Norme: NFPA 400 - Sépération minimale 6m (20 pieds)
FR: Identifie les produits chimiques périmés ou dont la date d'expiration approche (< 30 jours). Essentiel pour prévenir les réactions instables et maintenir la conformité réglementaire.
EN: Identifies expired chemicals or those with expiration approaching (< 30 days). Essential for preventing unstable reactions and maintaining regulatory compliance.
// ⏰ REQUÊTE #2 - Inventaire & Dates d'Expiration / Inventory & Expiration MATCH (chem:Chemical)-[:PART_OF]->(p:Project{id:$projectId}) // 📅 Filtre: expirés OU expiration dans 30 jours WHERE chem.expiryDate IS NOT NULL AND ( chem.expiryDate < date() // Déjà expirés OR chem.expiryDate < date() + duration({days: $warningDays}) // Expire bientôt ) // 🧮 Calcul jours restants WITH chem, duration.inDays(chem.expiryDate, date()).days AS daysRemaining RETURN chem.name AS chemical_name, chem.casNumber AS cas_number, chem.quantity AS quantity_L, toString(chem.expiryDate) AS expiry_date, daysRemaining, CASE WHEN daysRemaining < 0 THEN 'EXPIRÉ' WHEN daysRemaining <= 7 THEN 'CRITIQUE' WHEN daysRemaining <= 30 THEN 'AVERTISSEMENT' ELSE 'OK' END AS status ORDER BY daysRemaining ASC
// 📊 Exemple de sortie JSON { "chemical_name": "Peroxyde d'hydrogène 30%", "cas_number": "7722-84-1", "quantity_L": 25.0, "expiry_date": "2025-11-18", "daysRemaining": 14, "status": "AVERTISSEMENT" // < 30 jours }
⚡ Action: Planifier élimination sécuritaire, commander remplacements
📏 Norme: OSHA 1910.1200, WHMIS 2015
FR: Surveille les dépassements de valeurs limites d'exposition (VLE) pour gaz toxiques: H₂S (sulfure d'hydrogène), CO (monoxyde de carbone), VOC (composés organiques volatils). Analyse des lectures capteurs temps réel.
EN: Monitors occupational exposure limit (OEL) exceedances for toxic gases: H₂S (hydrogen sulfide), CO (carbon monoxide), VOC (volatile organic compounds). Real-time sensor analysis.
// 💨 REQUÊTE #3 - Dépassement VLE / OEL Exceedance MATCH (r:Reading)-[:AT]->(z:Zone)-[:PART_OF]->(p:Project{id:$projectId}) // 🧪 Types de gaz surveillés WHERE r.type IN ['VOC', 'H2S', 'CO'] // ⚠️ Valeur mesurée > Valeur Limite d'Exposition (OEL) AND r.value > r.oel // ⏱️ Dernières 24h (optionnel) AND r.timestamp > datetime() - duration({hours: 24}) RETURN z.name AS zone, r.type AS gas_type, max(r.value) AS peak_concentration_ppm, r.oel AS oel_limit_ppm, round(max(r.value) / r.oel * 100, 1) AS percentage_of_oel, count(r) AS exceedance_count, max(r.timestamp) AS last_exceedance ORDER BY percentage_of_oel DESC
// 📊 Exemple de sortie JSON { "zone": "Atelier-Soudure-B", "gas_type": "H2S", "peak_concentration_ppm": 12.3, "oel_limit_ppm": 10.0, // ACGIH TLV-TWA "percentage_of_oel": 123.0, // 23% au-dessus! "exceedance_count": 8, "last_exceedance": "2025-11-04T14:37:22Z" }
⚡ Action: Évacuation immédiate, ventilation forcée, EPI respiratoires autonomes
📏 Normes VLE: H₂S: 10ppm (ACGIH), CO: 25ppm (OSHA), VOC: 50ppm (NIOSH)
FR: Détecte les contenants de produits chimiques laissés ouverts au-delà du délai maximum autorisé. Prévient l'évaporation, la contamination et les réactions avec l'air ambiant.
EN: Detects chemical containers left open beyond maximum authorized time. Prevents evaporation, contamination and reactions with ambient air.
// ⏳ REQUÊTE #4 - Contenants Ouverts > Délai / Containers Open Too Long MATCH (cont:Container)-[:CONTAINS]->(chem:Chemical)-[:PART_OF]->(p:Project{id:$projectId}) // 📦 Filtre: contenants actuellement ouverts WHERE cont.openedAt IS NOT NULL // ⏰ Ouvert depuis plus de X heures (paramétrable) AND cont.openedAt + duration({hours: $maxOpenHours}) < datetime() // 🧮 Calcul durée d'ouverture WITH cont, chem, duration.inHours(cont.openedAt, datetime()).hours AS hoursOpen RETURN cont.id AS container_id, chem.name AS chemical_name, chem.group AS hazard_group, toString(cont.openedAt) AS opened_at, round(hoursOpen, 1) AS hours_open, CASE WHEN hoursOpen > 48 THEN 'ÉLEVÉ' WHEN hoursOpen > 24 THEN 'MOYEN' ELSE 'FAIBLE' END AS risk_level ORDER BY hours_open DESC
// 📊 Exemple de sortie JSON { "container_id": "CONT-2025-A347", "chemical_name": "Acétone", "hazard_group": "Flammable", "opened_at": "2025-11-02T08:15:00Z", "hours_open": 54.4, // > 48h = Évaporation significative "risk_level": "ÉLEVÉ" }
⚡ Action: Resceller immédiatement, vérifier concentration résiduelle, étiquetage date/heure
📏 Bonnes pratiques: Volatils (< 4h), Réactifs (< 8h), Autres (< 24h)
FR: Identifie les zones de stockage chimique sans kit de déversement à proximité immédiate (< 15m selon NFPA 400). Calcul géospatial 3D pour optimiser l'accessibilité en cas d'urgence.
EN: Identifies chemical storage zones without spill kits in immediate proximity (< 15m per NFPA 400). 3D geospatial calculation for emergency accessibility optimization.
// 🧰 REQUÊTE #5 - Kit Déversement Trop Loin / Spill Kit Too Far MATCH (z:Zone)-[:PART_OF]->(p:Project{id:$projectId}) // ☣️ Zones avec stockage de produits chimiques MATCH (chem:Chemical)-[:STORED_IN]->(z) // 🧰 Calcul distance au kit de déversement le plus proche WITH z, count(chem) AS chemicalCount, coalesce( min([ d IN [ (kit:Asset{class:'SpillKit'})-[:LOCATED_IN]->(z2:Zone) | distance(point(z), point(z2)) ] | d ]), 1e9 // Valeur infinie si aucun kit trouvé ) AS nearestKitDistance // ⚠️ Filtre: distance > seuil maximum autorisé WHERE nearestKitDistance > $maxDistanceM RETURN DISTINCT z.name AS zone_name, chemicalCount, round(nearestKitDistance, 2) AS nearest_kit_distance_m, CASE WHEN nearestKitDistance > 50 THEN 'CRITIQUE' WHEN nearestKitDistance > 30 THEN 'ÉLEVÉ' ELSE 'MOYEN' END AS response_time_risk ORDER BY nearest_kit_distance_m DESC
// 📊 Exemple de sortie JSON { "zone_name": "Entrepôt-Produits-Corrosifs-C", "chemicalCount": 23, "nearest_kit_distance_m": 47.8, // > 15m recommandé! "response_time_risk": "ÉLEVÉ" }
⚡ Action: Installer kit additionnel, signalisation claire, formation équipe proximité
📏 Norme: NFPA 400 - Kit à < 15m (50 pieds), OSHA 1910.120 - Temps accès < 30 sec
Déclenchement: Stockage incompatible, VLE dépassée
Action: Arrêt immédiat, évacuation, intervention urgence
Délai: < 5 minutes
Déclenchement: Kit trop éloigné, expiration < 7 jours
Action: Correction prioritaire, signalisation renforcée
Délai: < 24 heures
Déclenchement: Contenant ouvert > 24h, expiration < 30 jours
Action: Surveillance accrue, planification correction
Délai: < 72 heures
Déclenchement: Conformité OK, tous paramètres normaux
Action: Surveillance continue, maintenance préventive
Délai: Routine