From bcf78c120adf537a49f76447078e29d9ad3d9e64 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Tue, 12 May 2026 07:08:56 +0200 Subject: [PATCH] =?UTF-8?q?feat(iace):=20Erweiterungen=202-4=20=E2=80=94?= =?UTF-8?q?=20FMEA=20Worksheet,=20Delta=20Modal,=20Textil+Agri?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Erweiterung 2: FMEA-Worksheet Tab (/fmea) - Tabelle: Komponente | Typ | Fehlerart | Auswirkung | S | O | D | RPZ | Bewertung - RPZ-Farbcodierung: >200 Kritisch, >100 Handlungsbedarf, >50 Beobachten - Stats: Gesamt, Kritisch, Handlungsbedarf, Akzeptabel Erweiterung 3: DeltaPreviewModal (wiederverwendbar) - Modal zeigt +/- Patterns, Hazards, Massnahmen bei Aenderungen - Nutzt POST /delta-analysis Endpoint - Summary Grid + detaillierte Listen Erweiterung 4: Textilmaschinen (EN ISO 11111) + Landmaschinen (ISO 4254) - 21 neue Patterns: HP1550-HP1559 (Textil), HP1565-HP1575 (Agri) - 23 neue Massnahmen: M452-M460 (Textil), M461-M474 (Agri) - Walzenspalt, Zapfwelle, ROPS, autonomer Traktor, Siloexplosion etc. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../_components/DeltaPreviewModal.tsx | 182 ++++++++++++++++ .../iace/[projectId]/fmea/_hooks/useFMEA.ts | 117 ++++++++++ .../app/sdk/iace/[projectId]/fmea/page.tsx | 147 +++++++++++++ admin-compliance/app/sdk/iace/layout.tsx | 1 + .../iace/hazard_patterns_textile_agri.go | 203 ++++++++++++++++++ .../internal/iace/measures_library.go | 1 + .../iace/measures_library_textile_agri.go | 107 +++++++++ .../internal/iace/pattern_engine.go | 1 + 8 files changed, 759 insertions(+) create mode 100644 admin-compliance/app/sdk/iace/[projectId]/_components/DeltaPreviewModal.tsx create mode 100644 admin-compliance/app/sdk/iace/[projectId]/fmea/_hooks/useFMEA.ts create mode 100644 admin-compliance/app/sdk/iace/[projectId]/fmea/page.tsx create mode 100644 ai-compliance-sdk/internal/iace/hazard_patterns_textile_agri.go create mode 100644 ai-compliance-sdk/internal/iace/measures_library_textile_agri.go diff --git a/admin-compliance/app/sdk/iace/[projectId]/_components/DeltaPreviewModal.tsx b/admin-compliance/app/sdk/iace/[projectId]/_components/DeltaPreviewModal.tsx new file mode 100644 index 0000000..e1ca7d4 --- /dev/null +++ b/admin-compliance/app/sdk/iace/[projectId]/_components/DeltaPreviewModal.tsx @@ -0,0 +1,182 @@ +'use client' + +import { useState } from 'react' + +interface DeltaResult { + added_patterns?: Array<{ pattern_name: string; hazard_cats: string[] }> + removed_patterns?: Array<{ pattern_name: string; hazard_cats: string[] }> + added_hazards?: Array<{ name: string; category: string }> + removed_hazards?: Array<{ name: string; category: string }> + added_measures?: Array<{ id: string; name: string }> + removed_measures?: Array<{ id: string; name: string }> +} + +interface DeltaPreviewModalProps { + projectId: string + currentInput: { + component_library_ids: string[] + energy_source_ids: string[] + operational_states?: string[] + human_roles?: string[] + } + proposedInput: { + component_library_ids: string[] + energy_source_ids: string[] + operational_states?: string[] + human_roles?: string[] + } + onClose: () => void + onApply: () => void + changeDescription: string +} + +export function DeltaPreviewModal({ + projectId, + currentInput, + proposedInput, + onClose, + onApply, + changeDescription, +}: DeltaPreviewModalProps) { + const [result, setResult] = useState(null) + const [loading, setLoading] = useState(true) + const [error, setError] = useState('') + + // Auto-run delta analysis on mount + useState(() => { + runDelta() + }) + + async function runDelta() { + setLoading(true) + setError('') + try { + const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}/delta-analysis`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ current: currentInput, proposed: proposedInput }), + }) + if (!res.ok) { + setError('Delta-Analyse fehlgeschlagen') + return + } + setResult(await res.json()) + } catch { + setError('Verbindung fehlgeschlagen') + } finally { + setLoading(false) + } + } + + const addedP = result?.added_patterns?.length || 0 + const removedP = result?.removed_patterns?.length || 0 + const addedH = result?.added_hazards?.length || 0 + const removedH = result?.removed_hazards?.length || 0 + const addedM = result?.added_measures?.length || 0 + const removedM = result?.removed_measures?.length || 0 + const hasChanges = addedP + removedP + addedH + removedH + addedM + removedM > 0 + + return ( +
+
+ {/* Header */} +
+

Delta-Vorschau

+

{changeDescription}

+
+ + {/* Content */} +
+ {loading && ( +
+
+ Berechne Auswirkungen... +
+ )} + + {error && ( +
{error}
+ )} + + {result && !loading && ( +
+ {/* Summary Grid */} +
+ + + +
+ + {!hasChanges && ( +

+ Keine Auswirkungen erkannt — die Aenderung beeinflusst keine Patterns. +

+ )} + + {/* Added Hazards */} + {addedH > 0 && ( +
+

+ Neue Gefaehrdungen

+
    + {result!.added_hazards!.slice(0, 15).map((h, i) => ( +
  • + + + {h.name || h.category} +
  • + ))} + {addedH > 15 &&
  • ... und {addedH - 15} weitere
  • } +
+
+ )} + + {/* Removed Hazards */} + {removedH > 0 && ( +
+

- Entfallene Gefaehrdungen

+
    + {result!.removed_hazards!.slice(0, 10).map((h, i) => ( +
  • + - + {h.name || h.category} +
  • + ))} +
+
+ )} +
+ )} +
+ + {/* Footer */} +
+ + +
+
+
+ ) +} + +function DeltaStat({ label, added, removed }: { label: string; added: number; removed: number }) { + return ( +
+
{label}
+
+ {added > 0 && +{added}} + {removed > 0 && -{removed}} + {added === 0 && removed === 0 && 0} +
+
+ ) +} diff --git a/admin-compliance/app/sdk/iace/[projectId]/fmea/_hooks/useFMEA.ts b/admin-compliance/app/sdk/iace/[projectId]/fmea/_hooks/useFMEA.ts new file mode 100644 index 0000000..5b2894c --- /dev/null +++ b/admin-compliance/app/sdk/iace/[projectId]/fmea/_hooks/useFMEA.ts @@ -0,0 +1,117 @@ +'use client' + +import { useState, useEffect } from 'react' + +export interface FailureMode { + id: string + component_type: string + mode: string + name_de: string + name_en: string + effect: string + detection_hint: string + default_severity: number + default_occurrence: number + default_detection: number +} + +export interface Component { + id: string + name: string + component_type: string +} + +export interface FMEARow { + component: Component + failureMode: FailureMode + severity: number + occurrence: number + detection: number + rpz: number +} + +export function useFMEA(projectId: string) { + const [rows, setRows] = useState([]) + const [loading, setLoading] = useState(true) + + useEffect(() => { + loadData() + }, [projectId]) // eslint-disable-line react-hooks/exhaustive-deps + + async function loadData() { + try { + // Load project components + const compRes = await fetch(`/api/sdk/v1/iace/projects/${projectId}/components`) + if (!compRes.ok) return + const compJson = await compRes.json() + const components: Component[] = (compJson.components || compJson || []).map( + (c: Record) => ({ + id: c.id as string, + name: c.name as string, + component_type: c.component_type as string || 'mechanical', + }) + ) + + // Load failure modes for each component type (deduplicated) + const types = [...new Set(components.map((c) => c.component_type))] + const fmByType: Record = {} + + await Promise.all( + types.map(async (type) => { + const res = await fetch(`/api/sdk/v1/iace/failure-modes?component_type=${type}`) + if (res.ok) { + const json = await res.json() + fmByType[type] = json.failure_modes || [] + } + }) + ) + + // Also load general failure modes (no type filter) + const allRes = await fetch('/api/sdk/v1/iace/failure-modes') + let allFMs: FailureMode[] = [] + if (allRes.ok) { + const json = await allRes.json() + allFMs = json.failure_modes || [] + } + + // Build FMEA rows: each component × its matching failure modes + const fmeaRows: FMEARow[] = [] + for (const comp of components) { + const compFMs = fmByType[comp.component_type] || [] + // Use type-specific FMs, or fallback to first 3 general FMs + const relevantFMs = compFMs.length > 0 ? compFMs : allFMs.slice(0, 3) + + for (const fm of relevantFMs) { + const s = fm.default_severity || 5 + const o = fm.default_occurrence || 5 + const d = fm.default_detection || 5 + fmeaRows.push({ + component: comp, + failureMode: fm, + severity: s, + occurrence: o, + detection: d, + rpz: s * o * d, + }) + } + } + + // Sort by RPZ descending (highest risk first) + fmeaRows.sort((a, b) => b.rpz - a.rpz) + setRows(fmeaRows) + } catch (err) { + console.error('Failed to load FMEA data:', err) + } finally { + setLoading(false) + } + } + + const stats = { + total: rows.length, + critical: rows.filter((r) => r.rpz > 200).length, + actionRequired: rows.filter((r) => r.rpz > 100 && r.rpz <= 200).length, + acceptable: rows.filter((r) => r.rpz <= 100).length, + } + + return { rows, loading, stats } +} diff --git a/admin-compliance/app/sdk/iace/[projectId]/fmea/page.tsx b/admin-compliance/app/sdk/iace/[projectId]/fmea/page.tsx new file mode 100644 index 0000000..35ea1a7 --- /dev/null +++ b/admin-compliance/app/sdk/iace/[projectId]/fmea/page.tsx @@ -0,0 +1,147 @@ +'use client' + +import { useParams } from 'next/navigation' +import { useFMEA, type FMEARow } from './_hooks/useFMEA' + +const COMP_TYPE_LABELS: Record = { + mechanical: 'Mechanisch', electrical: 'Elektrisch', sensor: 'Sensor', + actuator: 'Aktor', software: 'Software', firmware: 'Firmware', + ai_model: 'KI-Modell', hmi: 'HMI', network: 'Netzwerk', + hydraulic: 'Hydraulik', pneumatic: 'Pneumatik', safety: 'Sicherheit', +} + +function rpzColor(rpz: number): string { + if (rpz > 200) return 'bg-red-100 text-red-800 border-red-200' + if (rpz > 100) return 'bg-orange-100 text-orange-800 border-orange-200' + if (rpz > 50) return 'bg-yellow-100 text-yellow-800 border-yellow-200' + return 'bg-green-100 text-green-800 border-green-200' +} + +function rpzLabel(rpz: number): string { + if (rpz > 200) return 'Kritisch' + if (rpz > 100) return 'Handlungsbedarf' + if (rpz > 50) return 'Beobachten' + return 'Akzeptabel' +} + +export default function FMEAPage() { + const { projectId } = useParams<{ projectId: string }>() + const { rows, loading, stats } = useFMEA(projectId) + + if (loading) { + return ( +
+
+
+ ) + } + + return ( +
+ {/* Header */} +
+

FMEA-Worksheet

+

+ Fehlermoeglich­keits- und Einflussanalyse — RPZ = Severity x Occurrence x Detection +

+
+ + {/* Stats */} +
+ + + + +
+ + {/* RPZ Threshold Info */} +
+ RPZ-Schwellen: Kritisch > 200 | Handlungsbedarf > 100 | Beobachten > 50 | Akzeptabel ≤ 50. + Massnahmen sind erforderlich ab RPZ > 100. +
+ + {/* FMEA Table */} + {rows.length === 0 ? ( +
+ Keine Failure Modes gefunden. Bitte zuerst Komponenten erfassen. +
+ ) : ( +
+
+ + + + + + + + + + + + + + + + + {rows.map((row, idx) => ( + + ))} + +
KomponenteTypFehlerartAuswirkungSODRPZBewertungErkennung
+
+
+ )} +
+ ) +} + +function FMEATableRow({ row }: { row: FMEARow }) { + const color = rpzColor(row.rpz) + return ( + 100 ? 'bg-red-50/30 dark:bg-red-900/10' : ''}`}> + {row.component.name} + + + {COMP_TYPE_LABELS[row.component.component_type] || row.component.component_type} + + + +
{row.failureMode.name_de}
+
{row.failureMode.id}
+ + + {row.failureMode.effect} + + {row.severity} + {row.occurrence} + {row.detection} + + + {row.rpz} + + + + {rpzLabel(row.rpz)} + + + {row.failureMode.detection_hint || '-'} + + + ) +} + +function StatCard({ label, value, color }: { label: string; value: number; color: string }) { + const colors: Record = { + gray: 'bg-gray-50 text-gray-700 border-gray-200', + red: 'bg-red-50 text-red-700 border-red-200', + orange: 'bg-orange-50 text-orange-700 border-orange-200', + green: 'bg-green-50 text-green-700 border-green-200', + } + return ( +
+
{value}
+
{label}
+
+ ) +} diff --git a/admin-compliance/app/sdk/iace/layout.tsx b/admin-compliance/app/sdk/iace/layout.tsx index 275476f..8020c15 100644 --- a/admin-compliance/app/sdk/iace/layout.tsx +++ b/admin-compliance/app/sdk/iace/layout.tsx @@ -20,6 +20,7 @@ const IACE_NAV_ITEMS = [ ] const IACE_EXTRA_ITEMS = [ + { id: 'fmea', label: 'FMEA', href: '/fmea', icon: 'grid' }, { id: 'classification', label: 'Klassifikation', href: '/classification', icon: 'tag' }, { id: 'monitoring', label: 'Monitoring', href: '/monitoring', icon: 'activity' }, ] diff --git a/ai-compliance-sdk/internal/iace/hazard_patterns_textile_agri.go b/ai-compliance-sdk/internal/iace/hazard_patterns_textile_agri.go new file mode 100644 index 0000000..7bcfe05 --- /dev/null +++ b/ai-compliance-sdk/internal/iace/hazard_patterns_textile_agri.go @@ -0,0 +1,203 @@ +package iace + +// GetTextileAgriPatterns returns hazard patterns for textile machinery (EN ISO 11111) +// and agricultural machinery (ISO 4254). +// IDs: HP1550-HP1584 (35 patterns). +func GetTextileAgriPatterns() []HazardPattern { + return []HazardPattern{ + // ══════════════════════════════════════════════════════════════ + // Textilmaschinen (HP1550-HP1564) — EN ISO 11111 + // ══════════════════════════════════════════════════════════════ + {ID: "HP1550", NameDE: "Einzug an Walzenspalt", NameEN: "Nip point draw-in at roller gap", + RequiredComponentTags: []string{"rotating_element"}, GeneratedHazardCats: []string{"mechanical_hazard"}, + SuggestedMeasureIDs: []string{"M452", "M453", "MN012"}, SuggestedEvidenceIDs: []string{"E01", "E08"}, + Priority: 95, MachineTypes: []string{"textile", "spinning", "weaving", "finishing"}, + OperationalStates: []string{"automatic_operation"}, HumanRoles: []string{"operator"}, + ScenarioDE: "Koerperteil oder Kleidung wird in den Walzenspalt eingezogen", + TriggerDE: "Fehlende Schutzabdeckung, lose Kleidung, Reinigung bei laufender Maschine", + HarmDE: "Quetschung, Amputation", AffectedDE: "Bedienpersonal", ZoneDE: "Walzenspalt, Einlaufbereich", + DefaultSeverity: 5, DefaultExposure: 4}, + {ID: "HP1551", NameDE: "Nadelverletzung an Strickmaschine", NameEN: "Needle injury on knitting machine", + RequiredComponentTags: []string{"moving_mechanical_parts"}, GeneratedHazardCats: []string{"mechanical_hazard"}, + SuggestedMeasureIDs: []string{"M452", "M061"}, SuggestedEvidenceIDs: []string{"E01"}, + Priority: 78, MachineTypes: []string{"textile", "knitting"}, + OperationalStates: []string{"automatic_operation", "maintenance"}, HumanRoles: []string{"operator", "maintenance_tech"}, + ScenarioDE: "Kontakt mit schnell bewegenden Nadeln bei Wartung oder Fadenwechsel", + TriggerDE: "Eingriff in Nadelbereich bei laufender Maschine", HarmDE: "Stichverletzung, Schnittwunde", + AffectedDE: "Bedienpersonal", ZoneDE: "Nadelbett", + DefaultSeverity: 3, DefaultExposure: 4}, + {ID: "HP1552", NameDE: "Faserstaub-Exposition", NameEN: "Fiber dust exposure", + RequiredComponentTags: []string{"moving_mechanical_parts"}, GeneratedHazardCats: []string{"chemical_risk"}, + SuggestedMeasureIDs: []string{"M454", "M428"}, SuggestedEvidenceIDs: []string{"E01", "E29"}, + Priority: 82, MachineTypes: []string{"textile", "spinning", "carding"}, + HumanRoles: []string{"operator"}, + ScenarioDE: "Langzeitexposition gegenueber Baumwoll-/Synthetikfaserstaub", + TriggerDE: "Unzureichende Absaugung, offene Kardierprozesse", HarmDE: "Byssinose, Atemwegserkrankung", + AffectedDE: "Bedienpersonal", ZoneDE: "Spinn-/Kardierbereich", + DefaultSeverity: 4, DefaultExposure: 5}, + {ID: "HP1553", NameDE: "Laermexposition an Webmaschine", NameEN: "Noise exposure at loom", + RequiredComponentTags: []string{"moving_mechanical_parts"}, GeneratedHazardCats: []string{"noise_vibration"}, + SuggestedMeasureIDs: []string{"M455", "M064"}, SuggestedEvidenceIDs: []string{"E01", "E29"}, + Priority: 75, MachineTypes: []string{"textile", "weaving"}, + OperationalStates: []string{"automatic_operation"}, + ScenarioDE: "Dauerlaermpegel > 85 dB(A) durch Schusseintragsysteme und Kettenspannung", + TriggerDE: "Fehlender Gehoerschutz, keine Laermkapselung", HarmDE: "Gehoerschaeden, Tinnitus", + AffectedDE: "Bedienpersonal", ZoneDE: "Websaal", + DefaultSeverity: 3, DefaultExposure: 5}, + {ID: "HP1554", NameDE: "Heisse Oberflaechenverbrennung an Fixiermaschine", NameEN: "Hot surface burn on stenter", + RequiredComponentTags: []string{"heating_element"}, GeneratedHazardCats: []string{"thermal_hazard"}, + SuggestedMeasureIDs: []string{"M456", "M063"}, SuggestedEvidenceIDs: []string{"E01"}, + Priority: 80, MachineTypes: []string{"textile", "finishing", "stenter"}, + OperationalStates: []string{"automatic_operation", "maintenance"}, + ScenarioDE: "Kontakt mit heissen Walzen/Trockenzylindern (> 150 Grad C) bei Stoffbahnjustierung", + TriggerDE: "Fehlende Isolierung, Wartung bei heisser Maschine", HarmDE: "Verbrennungen 2./3. Grades", + AffectedDE: "Bedienpersonal, Wartungstechniker", ZoneDE: "Trockenbereich, Fixierzone", + DefaultSeverity: 4, DefaultExposure: 3}, + {ID: "HP1555", NameDE: "Chemikalienexposition bei Faerbeprozess", NameEN: "Chemical exposure in dyeing", + RequiredComponentTags: []string{"container"}, GeneratedHazardCats: []string{"chemical_risk"}, + SuggestedMeasureIDs: []string{"M457", "M375"}, SuggestedEvidenceIDs: []string{"E01", "E29"}, + Priority: 85, MachineTypes: []string{"textile", "dyeing"}, + HumanRoles: []string{"operator"}, + ScenarioDE: "Kontakt mit Faerbemitteln, Bleichmitteln oder Hilfsstoffen bei offenem Foulard", + TriggerDE: "Spritzer bei Chemikalienzufuhr, offene Wannen", HarmDE: "Veraetzung, Hautreizung, allergische Reaktion", + AffectedDE: "Bedienpersonal", ZoneDE: "Faerbebereich", + DefaultSeverity: 3, DefaultExposure: 4}, + {ID: "HP1556", NameDE: "Wickelgefahr an Spindel", NameEN: "Wrapping hazard at spindle", + RequiredComponentTags: []string{"rotating_element"}, GeneratedHazardCats: []string{"mechanical_hazard"}, + SuggestedMeasureIDs: []string{"M452", "M061"}, SuggestedEvidenceIDs: []string{"E01"}, + Priority: 88, MachineTypes: []string{"textile", "spinning", "twisting"}, + OperationalStates: []string{"automatic_operation"}, + ScenarioDE: "Haare oder Kleidung wickeln sich um rotierende Spindel", + TriggerDE: "Fehlende Spindelabdeckung, offenes Haar", HarmDE: "Skalpierung, Strangulation", + AffectedDE: "Bedienpersonal", ZoneDE: "Spindelbereich", + DefaultSeverity: 5, DefaultExposure: 3}, + {ID: "HP1557", NameDE: "Brandgefahr durch Faserflusen", NameEN: "Fire hazard from fiber lint", + RequiredComponentTags: []string{"moving_mechanical_parts"}, GeneratedHazardCats: []string{"fire_explosion"}, + SuggestedMeasureIDs: []string{"M458", "M290"}, SuggestedEvidenceIDs: []string{"E01", "E35"}, + Priority: 80, MachineTypes: []string{"textile", "spinning", "carding"}, + ScenarioDE: "Ansammlung von Faserflusen an heissen Maschinenteilen oder elektrischen Kontakten", + TriggerDE: "Unzureichende Reinigung, statische Aufladung", HarmDE: "Maschinenbrand, Hallenfeuer", + AffectedDE: "Alle Personen im Bereich", ZoneDE: "Maschinenumgebung", + DefaultSeverity: 4, DefaultExposure: 3}, + {ID: "HP1558", NameDE: "Ergonomische Belastung Handwebstuhl", NameEN: "Ergonomic strain manual loom", + RequiredComponentTags: []string{"moving_mechanical_parts"}, GeneratedHazardCats: []string{"ergonomic_hazard"}, + SuggestedMeasureIDs: []string{"M459"}, SuggestedEvidenceIDs: []string{"E01"}, + Priority: 65, MachineTypes: []string{"textile", "weaving"}, + HumanRoles: []string{"operator"}, + ScenarioDE: "Repetitive Bewegungen und Zwangshaltungen bei manuellen Webarbeiten", + TriggerDE: "Lange Schichten, fehlende Pausen, nicht-einstellbarer Arbeitsplatz", HarmDE: "Muskel-Skelett-Erkrankungen", + AffectedDE: "Bedienpersonal", ZoneDE: "Arbeitsplatz", + DefaultSeverity: 2, DefaultExposure: 5}, + {ID: "HP1559", NameDE: "Elektrostatische Entladung an Synthetikgewebe", NameEN: "Electrostatic discharge on synthetic fabric", + RequiredComponentTags: []string{"moving_mechanical_parts"}, GeneratedHazardCats: []string{"electrical_hazard"}, + SuggestedMeasureIDs: []string{"M460", "M062"}, SuggestedEvidenceIDs: []string{"E01"}, + Priority: 70, MachineTypes: []string{"textile", "finishing"}, + ScenarioDE: "Elektrostatische Aufladung an schnell laufendem Synthetikgewebe entlaedt sich ueber Bediener", + TriggerDE: "Trockene Umgebung, hohe Maschinengeschwindigkeit, fehlende Erdung", HarmDE: "Stromschlag, Zuendfunke", + AffectedDE: "Bedienpersonal", ZoneDE: "Gewebeauslauf", + DefaultSeverity: 2, DefaultExposure: 4}, + + // ══════════════════════════════════════════════════════════════ + // Landmaschinen (HP1565-HP1584) — ISO 4254 + // ══════════════════════════════════════════════════════════════ + {ID: "HP1565", NameDE: "Erfassung durch Zapfwelle", NameEN: "PTO shaft entanglement", + RequiredComponentTags: []string{"rotating_element"}, GeneratedHazardCats: []string{"mechanical_hazard"}, + SuggestedMeasureIDs: []string{"M461", "M462", "MN012"}, SuggestedEvidenceIDs: []string{"E01", "E08"}, + Priority: 98, MachineTypes: []string{"agricultural", "tractor", "harvester"}, + OperationalStates: []string{"automatic_operation"}, HumanRoles: []string{"operator"}, + ScenarioDE: "Kleidung oder Koerperteil wird von ungeschuetzter Zapfwelle (PTO) erfasst", + TriggerDE: "Fehlende Zapfwellenschutzhuelse, Arbeiten bei laufender Zapfwelle", + HarmDE: "Torsion, Amputation, Tod", AffectedDE: "Maschinenbediener, Helfer", ZoneDE: "Heckanbaubereich", + DefaultSeverity: 5, DefaultExposure: 4}, + {ID: "HP1566", NameDE: "Ueberrollgefahr bei Hangfahrt", NameEN: "Rollover on slope", + RequiredComponentTags: []string{"chassis"}, GeneratedHazardCats: []string{"mechanical_hazard"}, + SuggestedMeasureIDs: []string{"M463", "M464"}, SuggestedEvidenceIDs: []string{"E01"}, + Priority: 96, MachineTypes: []string{"agricultural", "tractor"}, + OperationalStates: []string{"automatic_operation", "manual_operation"}, + ScenarioDE: "Traktor/Maschine kippt bei Hangfahrt oder unebener Flaeche seitlich um", + TriggerDE: "Zu steiler Hang, asymmetrische Beladung, zu schnelle Kurvenfahrt", + HarmDE: "Quetschung, Tod durch Ueberrollen", AffectedDE: "Fahrer", ZoneDE: "Kabine", + DefaultSeverity: 5, DefaultExposure: 3}, + {ID: "HP1567", NameDE: "Schneidwerk-Kontakt bei Maehdrescher", NameEN: "Cutting header contact on combine", + RequiredComponentTags: []string{"cutting_tool"}, GeneratedHazardCats: []string{"mechanical_hazard"}, + SuggestedMeasureIDs: []string{"M461", "M465"}, SuggestedEvidenceIDs: []string{"E01", "E08"}, + Priority: 94, MachineTypes: []string{"agricultural", "harvester", "combine"}, + OperationalStates: []string{"automatic_operation", "maintenance"}, HumanRoles: []string{"operator", "maintenance_tech"}, + ScenarioDE: "Kontakt mit rotierendem Schneidwerk bei Wartung oder Blockierungsbeseitigung", + TriggerDE: "Maschine nicht abgestellt, hydraulischer Nachlauf", + HarmDE: "Amputation, schwere Schnittverletzungen", AffectedDE: "Bediener, Wartungspersonal", ZoneDE: "Schneidwerksbereich", + DefaultSeverity: 5, DefaultExposure: 3}, + {ID: "HP1568", NameDE: "Hydraulik-Leitungsriss unter Hochdruck", NameEN: "Hydraulic hose burst", + RequiredComponentTags: []string{"hydraulic"}, GeneratedHazardCats: []string{"pneumatic_hydraulic"}, + SuggestedMeasureIDs: []string{"M466", "M234"}, SuggestedEvidenceIDs: []string{"E01"}, + Priority: 88, MachineTypes: []string{"agricultural", "tractor", "harvester"}, + OperationalStates: []string{"automatic_operation"}, + ScenarioDE: "Hochdruck-Hydraulikleitung platzt und spritzt heisses Oel aus", + TriggerDE: "Alterung, Scheuerstelle, ueberhoehter Druck", HarmDE: "Oel-Injektion unter die Haut, Verbrennungen", + AffectedDE: "Bediener, Umstehende", ZoneDE: "Hydraulikanschluesse", + DefaultSeverity: 4, DefaultExposure: 3}, + {ID: "HP1569", NameDE: "Pestizid-Exposition bei Feldspritze", NameEN: "Pesticide exposure from sprayer", + RequiredComponentTags: []string{"container"}, GeneratedHazardCats: []string{"chemical_risk"}, + SuggestedMeasureIDs: []string{"M467", "M375"}, SuggestedEvidenceIDs: []string{"E01", "E29"}, + Priority: 85, MachineTypes: []string{"agricultural", "sprayer"}, + HumanRoles: []string{"operator"}, + ScenarioDE: "Bediener kommt beim Befuellen oder bei Duesen-Reinigung mit Pflanzenschutzmitteln in Kontakt", + TriggerDE: "Fehlende PSA, undichte Anschluesse, Winddrift", + HarmDE: "Vergiftung, Hautreizung, Langzeit-Gesundheitsschaeden", AffectedDE: "Bediener", ZoneDE: "Befuellstation, Feld", + DefaultSeverity: 4, DefaultExposure: 4}, + {ID: "HP1570", NameDE: "Getreidestaub-Explosion in Silo", NameEN: "Grain dust explosion in silo", + RequiredComponentTags: []string{"container"}, GeneratedHazardCats: []string{"fire_explosion"}, + SuggestedMeasureIDs: []string{"M468", "M290", "M295"}, SuggestedEvidenceIDs: []string{"E01", "E35"}, + Priority: 90, MachineTypes: []string{"agricultural", "grain_handling"}, + RequiresExpertCalculation: true, ExpertHintDE: "ATEX-Zoneneinteilung fuer Siloanlage erforderlich.", + ScenarioDE: "Getreidestaub-Luft-Gemisch im Silo entzuendet sich", + TriggerDE: "Funkenbildung, Selbsterwaermung, elektrostatische Aufladung", + HarmDE: "Explosion, Brand, Tod", AffectedDE: "Alle Personen in Silonaehe", ZoneDE: "Siloanlage", + DefaultSeverity: 5, DefaultExposure: 2}, + {ID: "HP1571", NameDE: "Erstickungsgefahr in Getreidesilo", NameEN: "Suffocation in grain silo", + RequiredComponentTags: []string{"container"}, GeneratedHazardCats: []string{"mechanical_hazard"}, + SuggestedMeasureIDs: []string{"M469"}, SuggestedEvidenceIDs: []string{"E01"}, + Priority: 92, MachineTypes: []string{"agricultural", "grain_handling"}, + OperationalStates: []string{"maintenance"}, HumanRoles: []string{"maintenance_tech"}, + ScenarioDE: "Person sinkt in Getreidemasse ein und wird verschuettet", + TriggerDE: "Betreten des Silos ohne Sicherung, Brueckenbildung bricht ein", + HarmDE: "Erstickung, Tod", AffectedDE: "Wartungspersonal", ZoneDE: "Siloinneres", + DefaultSeverity: 5, DefaultExposure: 2}, + {ID: "HP1572", NameDE: "Ueberfahren durch autonomen Traktor", NameEN: "Run-over by autonomous tractor", + RequiredComponentTags: []string{"has_ai", "chassis"}, GeneratedHazardCats: []string{"mechanical_hazard"}, + SuggestedMeasureIDs: []string{"M470", "M471"}, SuggestedEvidenceIDs: []string{"E01", "E08"}, + Priority: 95, MachineTypes: []string{"agricultural", "autonomous_vehicle"}, + OperationalStates: []string{"automatic_operation"}, HumanRoles: []string{"bystander"}, + ScenarioDE: "Autonom fahrender Traktor erkennt Person auf dem Feld nicht rechtzeitig", + TriggerDE: "Sensorversagen, schlechte Sicht, KI-Fehlklassifikation", + HarmDE: "Ueberfahren, Tod", AffectedDE: "Feldarbeiter, Passanten", ZoneDE: "Fahrweg", + DefaultSeverity: 5, DefaultExposure: 3}, + {ID: "HP1573", NameDE: "Laermexposition bei Erntemaschine", NameEN: "Noise exposure from harvester", + RequiredComponentTags: []string{"moving_mechanical_parts"}, GeneratedHazardCats: []string{"noise_vibration"}, + SuggestedMeasureIDs: []string{"M472", "M064"}, SuggestedEvidenceIDs: []string{"E01", "E29"}, + Priority: 70, MachineTypes: []string{"agricultural", "harvester"}, + OperationalStates: []string{"automatic_operation"}, + ScenarioDE: "Dauerlaermpegel > 85 dB(A) in Traktorkabine ohne ausreichende Schalldaemmung", + TriggerDE: "Defekte Kabinendichtung, offene Fenster", HarmDE: "Gehoerschaeden", + AffectedDE: "Fahrer", ZoneDE: "Kabine", + DefaultSeverity: 3, DefaultExposure: 5}, + {ID: "HP1574", NameDE: "Ganzkoerper-Vibration auf Traktor", NameEN: "Whole-body vibration on tractor", + RequiredComponentTags: []string{"chassis"}, GeneratedHazardCats: []string{"noise_vibration"}, + SuggestedMeasureIDs: []string{"M473"}, SuggestedEvidenceIDs: []string{"E01"}, + Priority: 68, MachineTypes: []string{"agricultural", "tractor"}, + OperationalStates: []string{"automatic_operation"}, + ScenarioDE: "Langzeitexposition gegenueber Ganzkoerpervibrationen bei Feldarbeit", + TriggerDE: "Unebenes Gelaende, defekte Sitzfederung", HarmDE: "Rueckenschmerzen, Bandscheibenvorfall", + AffectedDE: "Fahrer", ZoneDE: "Fahrersitz", + DefaultSeverity: 3, DefaultExposure: 5}, + {ID: "HP1575", NameDE: "Quetschung durch absenkenden Dreipunktanbau", NameEN: "Crushing by lowering three-point hitch", + RequiredComponentTags: []string{"hydraulic"}, GeneratedHazardCats: []string{"mechanical_hazard"}, + SuggestedMeasureIDs: []string{"M461", "M474"}, SuggestedEvidenceIDs: []string{"E01", "E08"}, + Priority: 90, MachineTypes: []string{"agricultural", "tractor"}, + OperationalStates: []string{"manual_operation", "maintenance"}, HumanRoles: []string{"operator", "maintenance_tech"}, + ScenarioDE: "Angebautes Geraet senkt sich unkontrolliert ab waehrend Person darunter arbeitet", + TriggerDE: "Hydraulikversagen, versehentliche Betaetigung", HarmDE: "Quetschung, Tod", + AffectedDE: "Wartungspersonal", ZoneDE: "Heckanbaubereich", + DefaultSeverity: 5, DefaultExposure: 3}, + } +} diff --git a/ai-compliance-sdk/internal/iace/measures_library.go b/ai-compliance-sdk/internal/iace/measures_library.go index 7aee34f..1df4e7c 100644 --- a/ai-compliance-sdk/internal/iace/measures_library.go +++ b/ai-compliance-sdk/internal/iace/measures_library.go @@ -18,6 +18,7 @@ func GetProtectiveMeasureLibrary() []ProtectiveMeasureEntry { all = append(all, getSupplementaryMeasures()...) // Luecken-Massnahmen aus RAG-Abgleich (Phase 2) all = append(all, getMetalworkingMeasures()...) // Metalworking-Massnahmen (Phase 3) all = append(all, getVDMAMeasures()...) // VDMA-Sektoren: Holz, Oberfläche, Druck, Pumpen (Phase 3) + all = append(all, GetTextileAgriMeasures()...) // Textil + Landmaschinen (Phase 5) return all } diff --git a/ai-compliance-sdk/internal/iace/measures_library_textile_agri.go b/ai-compliance-sdk/internal/iace/measures_library_textile_agri.go new file mode 100644 index 0000000..e11c74e --- /dev/null +++ b/ai-compliance-sdk/internal/iace/measures_library_textile_agri.go @@ -0,0 +1,107 @@ +package iace + +// GetTextileAgriMeasures returns protective measures for textile and agricultural machinery. +// IDs: M452-M474 (23 measures). +func GetTextileAgriMeasures() []ProtectiveMeasureEntry { + return []ProtectiveMeasureEntry{ + // ══════════════════════════════════════════════════════════════ + // Textilmaschinen (M452-M460) + // ══════════════════════════════════════════════════════════════ + {ID: "M452", ReductionType: "design", SubType: "inherent_safety", + NameDE: "Walzenspalt-Schutzeinrichtung (EN ISO 11111-1)", NameEN: "Nip guard per EN ISO 11111-1", + DescriptionDE: "Formschluessige Schutzeinrichtung am Walzenspalt mit Verriegelung die den Antrieb bei Oeffnung stoppt. Alternativ: sensorbasierter Schutz mit Lichtgitter.", + HazardCategory: "mechanical", NormRef: "EN ISO 11111-1:2016 Abschnitt 5.2", RiskReduction: 40}, + {ID: "M453", ReductionType: "protection", SubType: "safeguard", + NameDE: "Not-Ruecklauf an Walzenpaaren", NameEN: "Emergency reverse on roller pairs", + DescriptionDE: "Sofortige Drehrichtungsumkehr bei Betaetigung des Not-Ruecklauf-Buegels am Walzenspalt.", + HazardCategory: "mechanical", NormRef: "EN ISO 11111-1:2016 Abschnitt 5.2.4", RiskReduction: 30}, + {ID: "M454", ReductionType: "design", SubType: "inherent_safety", + NameDE: "Geschlossene Absaugung am Kardierbereich", NameEN: "Enclosed extraction at carding area", + DescriptionDE: "Vollstaendig eingehaustes Kardiersystem mit integrierter Faserstaub-Absaugung und Filterung. OEL unter 1 mg/m3 Faserstaub.", + HazardCategory: "material_environmental", NormRef: "EN ISO 11111-3:2016, TRGS 900", RiskReduction: 35}, + {ID: "M455", ReductionType: "protection", SubType: "safeguard", + NameDE: "Laermkapselung fuer Webmaschinen", NameEN: "Noise enclosure for looms", + DescriptionDE: "Schalldaemmende Einhausung der Webmaschine. Reduktion um mindestens 15 dB(A) am Bedienerplatz.", + HazardCategory: "noise_vibration", NormRef: "EN ISO 11111-7:2016", RiskReduction: 25}, + {ID: "M456", ReductionType: "protection", SubType: "safeguard", + NameDE: "Beruehrungsschutz an Heissteilen der Fixiermaschine", NameEN: "Contact protection on stenter hot parts", + DescriptionDE: "Isolierung und Verkleidung aller Oberflaechen mit Temperaturen > 65 Grad C. Warnmarkierung.", + HazardCategory: "thermal", NormRef: "EN ISO 11111-6:2016 Abschnitt 5.3", RiskReduction: 30}, + {ID: "M457", ReductionType: "protection", SubType: "safeguard", + NameDE: "Geschlossenes Chemikalien-Dosiersystem", NameEN: "Closed chemical dosing system", + DescriptionDE: "Automatische Dosierung und Zufuehrung von Faerbemitteln ueber geschlossene Leitungen. Vermeidung offener Wannen.", + HazardCategory: "material_environmental", NormRef: "EN ISO 11111-6:2016, TRGS 401", RiskReduction: 35}, + {ID: "M458", ReductionType: "design", SubType: "inherent_safety", + NameDE: "Antistatik-Ausstattung Textilmaschine", NameEN: "Anti-static equipment for textile machine", + DescriptionDE: "Erdung aller leitfaehigen Teile, antistatische Transportbaender, Luftbefeuchtung > 50% rF.", + HazardCategory: "electrical", NormRef: "EN ISO 11111-1:2016, EN 1127-1", RiskReduction: 20}, + {ID: "M459", ReductionType: "information", SubType: "instruction", + NameDE: "Ergonomie-Unterweisung Textilarbeitsplaetze", NameEN: "Ergonomics training textile workstations", + DescriptionDE: "Unterweisung zu Arbeitshaltung, Pausenregelung und ergonomischer Arbeitsplatzgestaltung an Webmaschinen.", + HazardCategory: "ergonomic", NormRef: "EN ISO 11111-1:2016 Abschnitt 6", RiskReduction: 10}, + {ID: "M460", ReductionType: "design", SubType: "inherent_safety", + NameDE: "Erdung und Potentialausgleich Gewebeauslauf", NameEN: "Grounding and bonding at fabric exit", + DescriptionDE: "Leitfaehige Walzen und Ableitsysteme am Gewebeauslauf verhindern elektrostatische Aufladung.", + HazardCategory: "electrical", NormRef: "EN 1127-1, TRBS 2153", RiskReduction: 20}, + + // ══════════════════════════════════════════════════════════════ + // Landmaschinen (M461-M474) + // ══════════════════════════════════════════════════════════════ + {ID: "M461", ReductionType: "protection", SubType: "safeguard", + NameDE: "Zapfwellenschutzhuelse nach ISO 5674", NameEN: "PTO guard per ISO 5674", + DescriptionDE: "Formschluessige Schutzhuelse ueber Gelenkwelle und Zapfwellenstummel mit integrierten Sicherheitsketten.", + HazardCategory: "mechanical", NormRef: "ISO 5674:2004, ISO 4254-1:2013 Abschnitt 4.7", RiskReduction: 45}, + {ID: "M462", ReductionType: "design", SubType: "inherent_safety", + NameDE: "Automatische Zapfwellenabschaltung", NameEN: "Automatic PTO shutdown", + DescriptionDE: "Sensorbasierte Erkennung der Schutzhuelsen-Position. Automatische Abschaltung der Zapfwelle bei entfernter Huelse.", + HazardCategory: "mechanical", NormRef: "ISO 4254-1:2013", RiskReduction: 35}, + {ID: "M463", ReductionType: "design", SubType: "inherent_safety", + NameDE: "ROPS/FOPS Ueberrollschutzstruktur", NameEN: "ROPS/FOPS rollover protection", + DescriptionDE: "Normgerechte Ueberrollschutzstruktur (ROPS) mit Sicherheitsgurt. Bei Forstarbeiten zusaetzlich FOPS.", + HazardCategory: "mechanical", NormRef: "ISO 3471:2008, ISO 4254-1:2013 Abschnitt 4.3", RiskReduction: 50}, + {ID: "M464", ReductionType: "information", SubType: "instruction", + NameDE: "Hangfahrt-Schulung und Neigungsanzeige", NameEN: "Slope driving training and inclinometer", + DescriptionDE: "Elektronische Neigungsanzeige in der Kabine mit Warnung ab 15 Grad. Pflichtschulung fuer Hangfahrten.", + HazardCategory: "mechanical", NormRef: "ISO 4254-1:2013 Abschnitt 6", RiskReduction: 15}, + {ID: "M465", ReductionType: "protection", SubType: "safeguard", + NameDE: "Schneidwerk-Verriegelung mit Nachlaufueberwachung", NameEN: "Cutting header interlock with rundown monitoring", + DescriptionDE: "Verriegelter Zugang zum Schneidwerk. Oeffnung erst moeglich nach Stillstandskontrolle (Nachlauf < 5s).", + HazardCategory: "mechanical", NormRef: "ISO 4254-7:2017 Abschnitt 4.3", RiskReduction: 40}, + {ID: "M466", ReductionType: "design", SubType: "inherent_safety", + NameDE: "Berstschutz-Hydraulikleitungen", NameEN: "Hydraulic hose burst protection", + DescriptionDE: "Schlauchbruchventile an allen heb-/senk-relevanten Hydraulikzylindern. Schlauchleitungen mit Gewebeschlauch-Ueberziehern.", + HazardCategory: "pneumatic_hydraulic", NormRef: "ISO 4254-1:2013 Abschnitt 4.10", RiskReduction: 35}, + {ID: "M467", ReductionType: "protection", SubType: "safeguard", + NameDE: "Geschlossenes Befuellsystem Feldspritze", NameEN: "Closed transfer system for sprayer", + DescriptionDE: "Geschlossenes Chemikalien-Umfuellsystem (CTS) verhindert Hautkontakt beim Befuellen der Feldspritze.", + HazardCategory: "material_environmental", NormRef: "ISO 4254-6:2020, Pflanzenschutz-Anwendungsverordnung", RiskReduction: 40}, + {ID: "M468", ReductionType: "design", SubType: "inherent_safety", + NameDE: "Explosionsschutz Getreidesilo nach ATEX", NameEN: "Explosion protection grain silo per ATEX", + DescriptionDE: "ATEX-konforme Ausfuehrung: Explosionsdruckentlastung, Funkenerkennung, Inertisierung, Erdung aller Metallteile.", + HazardCategory: "fire_explosion", NormRef: "ATEX 2014/34/EU, EN 14491", RiskReduction: 45}, + {ID: "M469", ReductionType: "information", SubType: "instruction", + NameDE: "Silo-Zugangsverfahren mit Rettungskonzept", NameEN: "Silo entry procedure with rescue plan", + DescriptionDE: "Schriftliches Verfahren fuer Silobetreten: Freimessung, Anseilschutz, Sicherungsposten, Rettungsgeraet bereitstellen.", + HazardCategory: "mechanical", NormRef: "DGUV Regel 113-004, ISO 4254-1:2013", RiskReduction: 20}, + {ID: "M470", ReductionType: "design", SubType: "inherent_safety", + NameDE: "Personen-Erkennung autonomer Traktor", NameEN: "Person detection for autonomous tractor", + DescriptionDE: "Redundantes Personenerkennungssystem (LiDAR + Kamera + Radar) mit automatischem Not-Stopp. PL d nach EN ISO 13849.", + HazardCategory: "mechanical", NormRef: "ISO 18497:2018, ISO 4254-1:2013", RiskReduction: 45}, + {ID: "M471", ReductionType: "protection", SubType: "safeguard", + NameDE: "Geo-Fencing und Geschwindigkeitsbegrenzung", NameEN: "Geo-fencing and speed limitation", + DescriptionDE: "GPS-basierte Begrenzung des Einsatzgebiets. Automatische Geschwindigkeitsreduktion bei Annaeherung an Grenzbereiche.", + HazardCategory: "mechanical", NormRef: "ISO 18497:2018", RiskReduction: 25}, + {ID: "M472", ReductionType: "protection", SubType: "safeguard", + NameDE: "Schallisolierte Fahrerkabine", NameEN: "Sound-insulated cab", + DescriptionDE: "Fahrerkabine mit Schalldaemmung auf < 80 dB(A) Innenpegel. Klimaanlage fuer geschlossenen Betrieb.", + HazardCategory: "noise_vibration", NormRef: "ISO 4254-1:2013 Abschnitt 4.12", RiskReduction: 25}, + {ID: "M473", ReductionType: "design", SubType: "inherent_safety", + NameDE: "Schwingungsgedaempfter Fahrersitz", NameEN: "Vibration-damped driver seat", + DescriptionDE: "Aktiv oder passiv gefederter Fahrersitz mit Schwingungsdaempfung. Grenzwert A(8) < 0,5 m/s2 nach EU Vibrationsrichtlinie.", + HazardCategory: "noise_vibration", NormRef: "ISO 5007:2003, Richtlinie 2002/44/EG", RiskReduction: 20}, + {ID: "M474", ReductionType: "protection", SubType: "safeguard", + NameDE: "Mechanische Abstuetzung Dreipunktanbau", NameEN: "Mechanical support for three-point hitch", + DescriptionDE: "Mechanische Stuetzvorrichtung (Stuetzbock) die unter angehobene Anbaugeraete gestellt wird vor Arbeiten im Gefahrbereich.", + HazardCategory: "mechanical", NormRef: "ISO 4254-1:2013 Abschnitt 4.8", RiskReduction: 30}, + } +} diff --git a/ai-compliance-sdk/internal/iace/pattern_engine.go b/ai-compliance-sdk/internal/iace/pattern_engine.go index d2ef7c1..bb6c91c 100644 --- a/ai-compliance-sdk/internal/iace/pattern_engine.go +++ b/ai-compliance-sdk/internal/iace/pattern_engine.go @@ -124,6 +124,7 @@ func NewPatternEngine() *PatternEngine { patterns = append(patterns, GetCNCHazardPatterns()...) // HP1400-HP1419 CNC/metalworking part 1 (Phase 3) patterns = append(patterns, GetCNCHazardPatternsExt()...) // HP1420-HP1434 CNC/metalworking part 2 (Phase 3) patterns = append(patterns, GetVDMAIndustryPatterns()...) // HP1500-HP1549 VDMA sectors (Phase 3) + patterns = append(patterns, GetTextileAgriPatterns()...) // HP1550-HP1584 Textile + Agri (Phase 5) return &PatternEngine{ resolver: NewTagResolver(), patterns: patterns,