package inspur import ( "bufio" "regexp" "strconv" "strings" "git.mchus.pro/mchus/logpile/internal/models" ) // SDR sensor reading patterns var ( sdrLineRegex = regexp.MustCompile(`^(\S+)\s+\|\s+(.+?)\s+\|\s+(\w+)$`) valueRegex = regexp.MustCompile(`^([\d.]+)\s+(.+)$`) ) // ParseSDR parses BMC SDR (Sensor Data Record) output func ParseSDR(content []byte) []models.SensorReading { var readings []models.SensorReading scanner := bufio.NewScanner(strings.NewReader(string(content))) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if line == "" || strings.HasPrefix(line, "BMC sdr Info:") { continue } matches := sdrLineRegex.FindStringSubmatch(line) if matches == nil { continue } name := strings.TrimSpace(matches[1]) valueStr := strings.TrimSpace(matches[2]) status := strings.TrimSpace(matches[3]) reading := models.SensorReading{ Name: name, Status: status, } // Parse value and unit if valueStr != "disabled" && valueStr != "no reading" && !strings.HasPrefix(valueStr, "0x") { if vm := valueRegex.FindStringSubmatch(valueStr); vm != nil { if v, err := strconv.ParseFloat(vm[1], 64); err == nil { reading.Value = v reading.Unit = strings.TrimSpace(vm[2]) reading.RawValue = valueStr // Keep original string for reference } } } else if strings.HasPrefix(valueStr, "0x") { reading.RawValue = valueStr } // Determine sensor type reading.Type = determineSensorType(name) readings = append(readings, reading) } return readings } func determineSensorType(name string) string { nameLower := strings.ToLower(name) switch { case strings.Contains(nameLower, "temp"): return "temperature" case strings.Contains(nameLower, "fan") && strings.Contains(nameLower, "speed"): return "fan_speed" case strings.Contains(nameLower, "fan") && strings.Contains(nameLower, "status"): return "fan_status" case strings.HasSuffix(nameLower, "_vin") || strings.HasSuffix(nameLower, "_vout") || strings.HasSuffix(nameLower, "_v") || strings.Contains(nameLower, "volt"): return "voltage" case strings.Contains(nameLower, "power") || strings.HasSuffix(nameLower, "_pin") || strings.HasSuffix(nameLower, "_pout") || strings.HasSuffix(nameLower, "_pwr"): return "power" case strings.Contains(nameLower, "psu") && strings.Contains(nameLower, "status"): return "psu_status" case strings.Contains(nameLower, "cpu") && strings.Contains(nameLower, "status"): return "cpu_status" case strings.Contains(nameLower, "hdd") || strings.Contains(nameLower, "nvme"): return "storage_status" default: return "other" } }