feat(iace): add missing measures (EMV, Potentialausgleich, KSS) + norm caps

Measures: M410-M420 (Potentialausgleich, Ableitstroeme, Kriechstrecken,
EMV-Installation, EMV-Pruefung, KSS-Leitungssicherheit)
Norms: per-type caps (A:5, B1:8, B2:10, C:10) for ~33 max suggestions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-13 10:19:45 +02:00
parent b2c1f0ae84
commit 7a5301064c
2 changed files with 45 additions and 6 deletions
@@ -66,5 +66,26 @@ func getSupplementaryMeasures() []ProtectiveMeasureEntry {
// ══════════════════════════════════════════════════════════════
{ID: "M402", ReductionType: "protection", SubType: "monitoring", Name: "Sicherheitsbeleuchtung an Fluchtwegen und Arbeitsplaetzen", Description: "Fluchtwege und sicherheitsrelevante Arbeitsplaetze erhalten eine Sicherheitsbeleuchtung die bei Ausfall der allgemeinen Beleuchtung automatisch aktiviert wird.", HazardCategory: "general", Examples: []string{"Notbeleuchtung mit Batteriepufferung", "Nachleuchtende Leitmarkierung am Boden"}, NormReferences: []string{"ASR A3.4 — Beleuchtung", "ASR A2.3 — Fluchtwege"}},
{ID: "M403", ReductionType: "protection", SubType: "safety_control", Name: "Quetschschutz an kraftbetaetigten Tueren und Toren", Description: "Kraftbetaetigte Tueren und Tore erhalten Schutzeinrichtungen gegen Quetschen, Scheren und Einziehen an allen Schliesskanten.", HazardCategory: "mechanical", Examples: []string{"Schaltleiste an Schiebetorunterkante", "Lichtschranke an Rolltoroeffnung"}, NormReferences: []string{"ASR A1.7 — Tueren und Tore", "EN 12453"}},
// ══════════════════════════════════════════════════════════════
// Elektrische Sicherheit — Potentialausgleich & Ableitstroeme
// Gap: GT-Benchmark 2.12 (Potentialausgleich), 2.4 (Ableitstroeme)
// ══════════════════════════════════════════════════════════════
{ID: "M410", ReductionType: "design", SubType: "electrical_safety", Name: "Potentialausgleich zwischen Anlagenteilen", Description: "Alle leitfaehigen Anlagenteile mit unterschiedlicher Energieversorgung werden ueber einen Potentialausgleichsleiter verbunden um gefaehrliche Beruehrungsspannungen zu vermeiden.", HazardCategory: "electrical", Examples: []string{"Potentialausgleich zwischen Roboterzelle und Werkzeugmaschine", "Potentialausgleichsschiene im Schaltschrank"}, NormReferences: []string{"IEC 60204-1 Ziff. 8.2", "IEC 61439-1"}},
{ID: "M411", ReductionType: "design", SubType: "electrical_safety", Name: "Schutz bei erhoehten Ableitstroemen", Description: "Bei Ableitstroemen ueber 10 mA wird der Schutzleiter mechanisch geschuetzt oder ein zusaetzlicher Schutzleiter verlegt und die Verbindung ueberwacht.", HazardCategory: "electrical", Examples: []string{"Schutzrohr fuer Schutzleiter an Frequenzumrichter", "Doppelter Schutzleiter mit Ueberwachung"}, NormReferences: []string{"IEC 60204-1 Ziff. 8.2.6"}},
{ID: "M412", ReductionType: "design", SubType: "electrical_safety", Name: "Dimensionierung von Luft- und Kriechstrecken", Description: "Luft- und Kriechstrecken werden entsprechend der elektrischen Beanspruchung und Verschmutzungsgrad dimensioniert um Kurzschluesse und gefaehrliche Beruehrungsspannungen zu vermeiden.", HazardCategory: "electrical", Examples: []string{"Mindestabstaende in Schaltgeraetekombinationen einhalten", "Isolationsueberwachung installieren"}, NormReferences: []string{"IEC 60204-1 Ziff. 6.2", "IEC 61439-1"}},
// ══════════════════════════════════════════════════════════════
// EMV-Sicherheit
// Gap: GT-Benchmark 6.1 (EMV-Stoereinfluss auf Sicherheitsfunktionen)
// ══════════════════════════════════════════════════════════════
{ID: "M415", ReductionType: "design", SubType: "emc_safety", Name: "EMV-konforme Installation und Verkabelung", Description: "Alle sicherheitsrelevanten Komponenten und Sub-Systeme werden nach EMV-Richtlinien installiert und verkabelt um Stoereinfluss auf Sicherheitsfunktionen zu verhindern.", HazardCategory: "electrical", Examples: []string{"Geschirmte Steuerleitungen verwenden", "Getrennte Kabelkanaele fuer Leistungs- und Signalleitungen"}, NormReferences: []string{"IEC 61000-6-2", "EN 16090-1 Ziff. 5.8.7"}},
{ID: "M416", ReductionType: "design", SubType: "emc_safety", Name: "EMV-Pruefung sicherheitsrelevanter Systeme", Description: "Sicherheitsrelevante Steuerungen und Antriebe werden auf Stoerfestigkeit gegenueber elektromagnetischen Einflussgroessen geprueft.", HazardCategory: "electrical", Examples: []string{"Burst/Surge-Pruefung nach IEC 61000-4", "Stoerfestigkeitspruefung der Sicherheits-SPS"}, NormReferences: []string{"IEC 61000-4-4", "IEC 61000-4-5", "IEC 62061"}},
// ══════════════════════════════════════════════════════════════
// Kuehlschmierstoff-Leitungssicherheit
// Gap: GT-Benchmark 2.10 (KSS-Leckage fuehrt zu Brand)
// ══════════════════════════════════════════════════════════════
{ID: "M420", ReductionType: "design", SubType: "fluid_safety", Name: "Druckfeste Auslegung von KSS-Leitungen", Description: "Schlaeuche, Dichtungen, Verbindungsstuecke und Befestigungen des Kuehlschmierstoffsystems werden auf den Nenndruck der jeweiligen Komponente ausgelegt und gegen Abspringen gesichert.", HazardCategory: "mechanical", Examples: []string{"Druckschlaeuche auf maximalen Betriebsdruck dimensionieren", "Schlauchbruchsicherungen an kritischen Verbindungen"}, NormReferences: []string{"IEC 60204-1 Ziff. 11.3", "EN ISO 4414"}},
}
}
@@ -142,7 +142,17 @@ func matchNorm(norm NormReference, machineType string, hazardSet, tagSet map[str
}
}
// groupByType sorts suggestions by confidence and groups them by norm type.
// Per-type caps for norm suggestions to avoid overwhelming the user.
// A professional typically references 3-5 A-norms, 5-10 B-norms, and 3-8 C-norms.
const (
maxANorms = 5
maxB1Norms = 8
maxB2Norms = 10
maxCNorms = 10
)
// groupByType sorts suggestions by confidence, groups them by norm type,
// and applies per-type caps to keep the list manageable.
func groupByType(suggestions []NormSuggestion) *NormSuggestionResult {
sort.Slice(suggestions, func(i, j int) bool {
return suggestions[i].Confidence > suggestions[j].Confidence
@@ -158,17 +168,25 @@ func groupByType(suggestions []NormSuggestion) *NormSuggestionResult {
for _, s := range suggestions {
switch s.Norm.NormType {
case "A":
result.ANorms = append(result.ANorms, s)
if len(result.ANorms) < maxANorms {
result.ANorms = append(result.ANorms, s)
}
case "B1":
result.B1Norms = append(result.B1Norms, s)
if len(result.B1Norms) < maxB1Norms {
result.B1Norms = append(result.B1Norms, s)
}
case "B2":
result.B2Norms = append(result.B2Norms, s)
if len(result.B2Norms) < maxB2Norms {
result.B2Norms = append(result.B2Norms, s)
}
case "C":
result.CNorms = append(result.CNorms, s)
if len(result.CNorms) < maxCNorms {
result.CNorms = append(result.CNorms, s)
}
}
}
result.Total = len(suggestions)
result.Total = len(result.ANorms) + len(result.B1Norms) + len(result.B2Norms) + len(result.CNorms)
return result
}