From f11a43f6908af3a8f61c2557558e1d78b20a9003 Mon Sep 17 00:00:00 2001 From: Mikhail Chusavitin Date: Sun, 15 Mar 2026 23:29:44 +0300 Subject: [PATCH] export: merge inspur psu sensor groups --- internal/exporter/reanimator_converter.go | 9 ++++- .../exporter/reanimator_converter_test.go | 34 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/internal/exporter/reanimator_converter.go b/internal/exporter/reanimator_converter.go index 489e844..1003eb5 100644 --- a/internal/exporter/reanimator_converter.go +++ b/internal/exporter/reanimator_converter.go @@ -1071,11 +1071,18 @@ func convertSensors(sensors []models.SensorReading) *ReanimatorSensors { func groupedPowerSensorName(name string) string { trimmed := strings.TrimSpace(name) lower := strings.ToLower(trimmed) - for _, suffix := range []string{"_inputpower", "_inputvoltage", "_inputcurrent"} { + inputSuffixes := []string{"_inputpower", "_inputvoltage", "_inputcurrent", "_pin", "_vin", "_iin"} + for _, suffix := range inputSuffixes { if strings.HasSuffix(lower, suffix) { return strings.TrimSpace(trimmed[:len(trimmed)-len(suffix)]) } } + outputSuffixes := []string{"_outputpower", "_outputvoltage", "_outputcurrent", "_pout", "_vout", "_iout"} + for _, suffix := range outputSuffixes { + if strings.HasSuffix(lower, suffix) { + return strings.TrimSpace(trimmed[:len(trimmed)-len(suffix)]) + "_Output" + } + } return trimmed } diff --git a/internal/exporter/reanimator_converter_test.go b/internal/exporter/reanimator_converter_test.go index e23740f..6eeed11 100644 --- a/internal/exporter/reanimator_converter_test.go +++ b/internal/exporter/reanimator_converter_test.go @@ -1421,6 +1421,40 @@ func TestConvertToReanimator_MergesSiblingPowerSensors(t *testing.T) { } } +func TestConvertToReanimator_MergesInspurPSUInputAndOutputSensors(t *testing.T) { + input := &models.AnalysisResult{ + Hardware: &models.HardwareConfig{ + BoardInfo: models.BoardInfo{SerialNumber: "BOARD-123"}, + }, + Sensors: []models.SensorReading{ + {Name: "PSU0_VIN", Type: "voltage", Value: 224, Unit: "V", Status: "OK"}, + {Name: "PSU0_PIN", Type: "power", Value: 120, Unit: "W", Status: "OK"}, + {Name: "PSU0_VOUT", Type: "voltage", Value: 12, Unit: "V", Status: "OK"}, + {Name: "PSU0_POUT", Type: "power", Value: 88, Unit: "W", Status: "OK"}, + {Name: "PSU0_OutputPower", Type: "power", Value: 95, Unit: "W", Status: "OK"}, + }, + } + + out, err := ConvertToReanimator(input) + if err != nil { + t.Fatalf("ConvertToReanimator() failed: %v", err) + } + if out.Hardware.Sensors == nil || len(out.Hardware.Sensors.Power) != 2 { + t.Fatalf("expected 2 grouped PSU power sensors, got %#v", out.Hardware.Sensors) + } + + byName := map[string]ReanimatorPowerSensor{} + for _, item := range out.Hardware.Sensors.Power { + byName[item.Name] = item + } + if got, ok := byName["PSU0"]; !ok || got.VoltageV != 224 || got.PowerW != 120 { + t.Fatalf("expected PSU0 input group with VIN/PIN merged, got %#v", byName) + } + if got, ok := byName["PSU0_Output"]; !ok || got.VoltageV != 12 || got.PowerW != 95 { + t.Fatalf("expected PSU0 output group with VOUT/POUT merged, got %#v", byName) + } +} + func TestConvertToReanimator_PreservesCanonicalDedupWithoutDeviceVitals(t *testing.T) { input := &models.AnalysisResult{ Filename: "dedup-vitals.json",