← back to kevin-buckham__MMCd-Go

Function bodies 80 total

All specs Real LLM only Function bodies
main.NewApp function · go · L39-L45 (7 LOC)
app.go
func NewApp() *App {
	return &App{
		defs:    sensor.DefaultDefinitions(),
		units:   sensor.UnitMetric,
		commLog: newCommLog(),
	}
}
main.App.Connect method · go · L67-L95 (29 LOC)
app.go
func (a *App) Connect(port string, baud int) error {
	a.mu.Lock()
	defer a.mu.Unlock()

	if a.connected {
		return fmt.Errorf("already connected")
	}

	if baud <= 0 {
		baud = protocol.DefaultBaudRate
	}

	a.conn = protocol.NewSerialConn(port, baud)
	if err := a.conn.Open(); err != nil {
		return err
	}

	a.ecu = protocol.NewECU(a.conn, a.defs)
	a.connected = true

	runtime.EventsEmit(a.ctx, "connection:status", map[string]interface{}{
		"connected": true,
		"port":      port,
		"baud":      baud,
	})

	a.log("info", "Connected to ECU", fmt.Sprintf("port=%s baud=%d", port, baud))
	return nil
}
main.App.ConnectDemo method · go · L98-L119 (22 LOC)
app.go
func (a *App) ConnectDemo() error {
	a.mu.Lock()
	defer a.mu.Unlock()

	if a.connected {
		return fmt.Errorf("already connected")
	}

	a.sim = protocol.NewSimulator(a.defs)
	a.connected = true
	a.demoMode = true

	runtime.EventsEmit(a.ctx, "connection:status", map[string]interface{}{
		"connected": true,
		"port":      "DEMO",
		"baud":      0,
		"demo":      true,
	})

	a.log("info", "Connected in DEMO mode", "simulated ECU")
	return nil
}
main.App.Disconnect method · go · L129-L160 (32 LOC)
app.go
func (a *App) Disconnect() error {
	a.mu.Lock()
	defer a.mu.Unlock()

	if a.lg != nil && a.lg.IsRunning() {
		a.lg.Stop()
	}

	if a.csvWriter != nil {
		a.csvWriter.Close()
		a.csvWriter = nil
	}

	if a.conn != nil {
		a.conn.Close()
	}

	a.connected = false
	a.demoMode = false
	a.ecu = nil
	a.sim = nil
	a.conn = nil
	a.lg = nil

	if a.ctx != nil {
		runtime.EventsEmit(a.ctx, "connection:status", map[string]interface{}{
			"connected": false,
		})
	}

	return nil
}
main.App.SetActiveSensors method · go · L175-L212 (38 LOC)
app.go
func (a *App) SetActiveSensors(slugs []string) error {
	a.mu.Lock()
	defer a.mu.Unlock()

	upperSlugs := make([]string, len(slugs))
	for i, s := range slugs {
		upperSlugs[i] = strings.ToUpper(s)
	}

	indices, notFound := sensor.SlugsToIndices(a.defs, upperSlugs)
	if len(notFound) > 0 {
		slog.Warn("unknown sensors", "slugs", notFound)
	}

	// Add INJD if RPM and INJP are both selected
	hasRPM, hasINJP := false, false
	for _, idx := range indices {
		if a.defs[idx].Slug == "RPM" {
			hasRPM = true
		}
		if a.defs[idx].Slug == "INJP" {
			hasINJP = true
		}
	}
	if hasRPM && hasINJP {
		if injdIdx, _ := sensor.FindBySlug(a.defs, "INJD"); injdIdx >= 0 {
			indices = append(indices, injdIdx)
		}
	}

	a.activeIndices = indices

	if a.lg != nil {
		a.lg.SetIndices(indices)
	}

	return nil
}
main.App.StartMonitoring method · go · L215-L289 (75 LOC)
app.go
func (a *App) StartMonitoring() error {
	a.mu.Lock()
	defer a.mu.Unlock()

	if !a.connected {
		return fmt.Errorf("not connected")
	}

	if a.lg != nil && a.lg.IsRunning() {
		return nil // already running
	}

	indices := a.activeIndices
	if len(indices) == 0 {
		indices = sensor.AllPollableIndices(a.defs)
		a.activeIndices = indices
	}

	var poller logger.SamplePoller
	var pollRate time.Duration
	if a.demoMode {
		poller = a.sim
		pollRate = 50 * time.Millisecond // 20Hz for smooth UI updates
	} else {
		poller = a.ecu
		pollRate = 1 * time.Millisecond // as fast as possible for real ECU
	}
	a.lg = logger.NewWithRate(poller, a.defs, indices, a.units, pollRate)

	a.lg.OnError(func(err error) {
		a.log("warn", "Poll error", err.Error())
	})

	a.lg.OnDisconnect(func() {
		a.log("error", "ECU communication lost", "Too many consecutive errors — check cable")
		if a.ctx != nil {
			runtime.EventsEmit(a.ctx, "connection:status", map[string]interface{}{
				"connected": false,
				"reason":   
main.App.StopMonitoring method · go · L292-L300 (9 LOC)
app.go
func (a *App) StopMonitoring() {
	a.mu.Lock()
	defer a.mu.Unlock()

	if a.lg != nil {
		a.lg.Stop()
		a.log("info", "Monitoring stopped", "")
	}
}
Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
main.App.StartLogging method · go · L303-L336 (34 LOC)
app.go
func (a *App) StartLogging(filename string) error {
	a.mu.Lock()
	defer a.mu.Unlock()

	if a.csvWriter != nil {
		return fmt.Errorf("already logging")
	}

	indices := a.activeIndices
	if len(indices) == 0 {
		indices = sensor.AllPollableIndices(a.defs)
	}

	var err error
	a.csvWriter, err = logger.NewCSVWriter(filename, a.defs, indices, a.units)
	if err != nil {
		return err
	}

	if a.lg != nil {
		a.lg.OnSample(func(sample sensor.Sample) {
			if a.csvWriter != nil {
				a.csvWriter.WriteSample(sample)
			}
		})
	}

	runtime.EventsEmit(a.ctx, "logging:status", map[string]interface{}{
		"logging":  true,
		"filename": filename,
	})

	return nil
}
main.App.StopLogging method · go · L339-L357 (19 LOC)
app.go
func (a *App) StopLogging() error {
	a.mu.Lock()
	defer a.mu.Unlock()

	if a.csvWriter == nil {
		return nil
	}

	count := a.csvWriter.Count()
	err := a.csvWriter.Close()
	a.csvWriter = nil

	runtime.EventsEmit(a.ctx, "logging:status", map[string]interface{}{
		"logging": false,
		"count":   count,
	})

	return err
}
main.App.ReadDTCs method · go · L360-L405 (46 LOC)
app.go
func (a *App) ReadDTCs() (*protocol.DTCResult, error) {
	a.mu.Lock()
	defer a.mu.Unlock()

	if !a.connected {
		return nil, fmt.Errorf("not connected")
	}
	if a.demoMode {
		a.log("info", "Reading DTCs (DEMO)", "")
		result := &protocol.DTCResult{
			ActiveRaw: 0x0022, // bits 1 + 5
			StoredRaw: 0x0406, // bits 1, 2, 10
			Active: []protocol.DTCCode{
				{Bit: 1, Code: "12", Description: "Intake air flow sensor"},
				{Bit: 5, Code: "21", Description: "Engine coolant temperature sensor"},
			},
			Stored: []protocol.DTCCode{
				{Bit: 1, Code: "12", Description: "Intake air flow sensor"},
				{Bit: 2, Code: "13", Description: "Intake air temperature sensor"},
				{Bit: 10, Code: "31", Description: "Knock sensor"},
			},
		}
		a.log("info", "DTCs read (DEMO)", fmt.Sprintf("active=%d stored=%d", len(result.Active), len(result.Stored)))
		return result, nil
	}

	// Pause monitoring if running to avoid serial bus contention
	wasRunning := a.lg != nil && a.lg.IsRunning()
	if wasRunning {
	
main.App.EraseDTCs method · go · L408-L441 (34 LOC)
app.go
func (a *App) EraseDTCs() error {
	a.mu.Lock()
	defer a.mu.Unlock()

	if !a.connected {
		return fmt.Errorf("not connected")
	}
	if a.demoMode {
		a.log("info", "Erasing DTCs (DEMO)", "")
		time.Sleep(500 * time.Millisecond)
		a.log("info", "DTCs erased (DEMO)", "OK")
		return nil
	}

	// Pause monitoring if running to avoid serial bus contention
	wasRunning := a.lg != nil && a.lg.IsRunning()
	if wasRunning {
		a.lg.Stop()
	}

	a.log("info", "Erasing DTCs", "")
	err := a.ecu.EraseDTCs()

	if wasRunning {
		a.lg.Start()
	}

	if err != nil {
		a.log("error", "DTC erase failed", err.Error())
	} else {
		a.log("info", "DTCs erased", "OK")
	}
	return err
}
main.App.RunActuatorTest method · go · L444-L502 (59 LOC)
app.go
func (a *App) RunActuatorTest(command string) (string, error) {
	a.mu.Lock()
	defer a.mu.Unlock()

	if !a.connected {
		return "", fmt.Errorf("not connected")
	}
	commands := map[string]byte{
		"fuel-pump": 0xF6,
		"purge":     0xF5,
		"pressure":  0xF4,
		"egr":       0xF3,
		"mvic":      0xF2,
		"boost":     0xF1,
		"inj1":      0xFC,
		"inj2":      0xFB,
		"inj3":      0xFA,
		"inj4":      0xF9,
		"inj5":      0xF8,
		"inj6":      0xF7,
	}

	addr, ok := commands[strings.ToLower(command)]
	if !ok {
		return "", fmt.Errorf("unknown command: %s", command)
	}

	if a.demoMode {
		a.log("info", "Running actuator test (DEMO)", fmt.Sprintf("%s (0x%02X)", command, addr))
		time.Sleep(6 * time.Second)
		a.log("info", "Actuator test complete (DEMO)", fmt.Sprintf("%s → OK", command))
		return "OK (DEMO)", nil
	}

	// Pause monitoring if running to avoid serial bus contention
	wasRunning := a.lg != nil && a.lg.IsRunning()
	if wasRunning {
		a.lg.Stop()
	}

	a.log("info", "Running actuator test",
main.App.GetAboutInfo method · go · L517-L528 (12 LOC)
app.go
func (a *App) GetAboutInfo() *AboutInfo {
	return &AboutInfo{
		Name:        version.Name,
		Version:     version.Version,
		Description: version.Description,
		Developers:  version.Developers,
		Copyright:   version.Copyright,
		License:     version.License,
		Attribution: version.Attribution,
		URL:         version.URL,
	}
}
main.App.LoadLogFile method · go · L548-L579 (32 LOC)
app.go
func (a *App) LoadLogFile() (*LogData, error) {
	selection, err := runtime.OpenFileDialog(a.ctx, runtime.OpenDialogOptions{
		Title: "Open Log File",
		Filters: []runtime.FileFilter{
			{DisplayName: "Log Files (*.csv, *.mmcd, *.pdb)", Pattern: "*.csv;*.mmcd;*.pdb;*.PDB"},
			{DisplayName: "CSV Files (*.csv)", Pattern: "*.csv"},
			{DisplayName: "MMCD Binary (*.mmcd)", Pattern: "*.mmcd"},
			{DisplayName: "PalmOS PDB (*.pdb)", Pattern: "*.pdb;*.PDB"},
			{DisplayName: "All Files (*.*)", Pattern: "*.*"},
		},
	})
	if err != nil {
		return nil, err
	}
	if selection == "" {
		return nil, fmt.Errorf("cancelled")
	}

	slog.Info("loading log file", "path", selection)

	lower := strings.ToLower(selection)
	switch {
	case strings.HasSuffix(lower, ".csv"):
		return a.loadCSVLog(selection)
	case strings.HasSuffix(lower, ".mmcd"):
		return a.loadBinaryLog(selection)
	case strings.HasSuffix(lower, ".pdb"):
		return a.loadPDBLog(selection)
	default:
		return nil, fmt.Errorf("unsupported file type: 
main.App.loadCSVLog method · go · L581-L602 (22 LOC)
app.go
func (a *App) loadCSVLog(path string) (*LogData, error) {
	csvLog, err := logger.ReadCSVLog(path)
	if err != nil {
		return nil, err
	}
	// Generate elapsed times: assume ~50ms per sample if no real timestamps
	elapsed := make([]float64, csvLog.Count)
	for i := range elapsed {
		elapsed[i] = float64(i) * 50.0
	}
	// Use Elapsed_ms from CSV if available
	if csvLog.ElapsedMs != nil && len(csvLog.ElapsedMs) == csvLog.Count {
		elapsed = csvLog.ElapsedMs
	}
	return &LogData{
		Slugs:     csvLog.Slugs,
		Data:      csvLog.Data,
		ElapsedMs: elapsed,
		Count:     csvLog.Count,
		Name:      path,
	}, nil
}
All rows scored by the Repobility analyzer (https://repobility.com)
main.App.loadBinaryLog method · go · L604-L649 (46 LOC)
app.go
func (a *App) loadBinaryLog(path string) (*LogData, error) {
	binLog, err := logger.ReadBinaryLog(path)
	if err != nil {
		return nil, err
	}

	// Convert samples to float data keyed by slug
	data := make(map[string][]float64)
	var slugs []string

	for _, idx := range binLog.Indices {
		if idx >= 0 && idx < len(a.defs) && a.defs[idx].Exists {
			slug := a.defs[idx].Slug
			slugs = append(slugs, slug)
			data[slug] = make([]float64, 0, len(binLog.Samples))
		}
	}

	elapsed := make([]float64, 0, len(binLog.Samples))
	var startTime time.Time
	for i, sample := range binLog.Samples {
		if i == 0 {
			startTime = sample.Time
		}
		elapsed = append(elapsed, float64(sample.Time.Sub(startTime).Milliseconds()))
		sample.ComputeDerivatives(a.defs)
		for _, idx := range binLog.Indices {
			if idx >= 0 && idx < len(a.defs) && a.defs[idx].Exists {
				slug := a.defs[idx].Slug
				if sample.HasData(idx) {
					data[slug] = append(data[slug], a.defs[idx].Convert(sample.RawData[idx], binLog.Units))
			
main.App.loadPDBLog method · go · L651-L700 (50 LOC)
app.go
func (a *App) loadPDBLog(path string) (*LogData, error) {
	pdbLog, err := logger.ParsePDB(path)
	if err != nil {
		return nil, err
	}

	// Determine which sensors are present across all samples
	var presentMask uint32
	for _, s := range pdbLog.Samples {
		presentMask |= s.DataPresent
	}

	data := make(map[string][]float64)
	var slugs []string
	var indices []int

	for i, def := range a.defs {
		if def.Exists && presentMask&(1<<uint(i)) != 0 {
			slugs = append(slugs, def.Slug)
			indices = append(indices, i)
			data[def.Slug] = make([]float64, 0, len(pdbLog.Samples))
		}
	}

	elapsed := make([]float64, 0, len(pdbLog.Samples))
	var startTime time.Time
	for i, sample := range pdbLog.Samples {
		if i == 0 {
			startTime = sample.Time
		}
		elapsed = append(elapsed, float64(sample.Time.Sub(startTime).Milliseconds()))
		sample.ComputeDerivatives(a.defs)
		for _, idx := range indices {
			slug := a.defs[idx].Slug
			if sample.HasData(idx) {
				data[slug] = append(data[slug], a.defs[idx].Conv
main.CommLog.add method · go · L43-L50 (8 LOC)
commlog.go
func (cl *CommLog) add(entry LogEntry) {
	cl.mu.Lock()
	defer cl.mu.Unlock()
	cl.entries = append(cl.entries, entry)
	if len(cl.entries) > maxLogEntries {
		cl.entries = cl.entries[len(cl.entries)-maxLogEntries:]
	}
}
main.CommLog.getAll method · go · L52-L58 (7 LOC)
commlog.go
func (cl *CommLog) getAll() []LogEntry {
	cl.mu.Lock()
	defer cl.mu.Unlock()
	out := make([]LogEntry, len(cl.entries))
	copy(out, cl.entries)
	return out
}
main.App.log method · go · L61-L88 (28 LOC)
commlog.go
func (a *App) log(level, message, detail string) {
	entry := LogEntry{
		Time:    time.Now().Format("15:04:05.000"),
		Level:   level,
		Message: message,
		Detail:  detail,
	}

	if a.commLog == nil {
		a.commLog = newCommLog()
	}
	a.commLog.add(entry)

	// Emit to frontend
	if a.ctx != nil {
		runtime.EventsEmit(a.ctx, "comm:log", entry)
	}

	// Also log via slog
	switch level {
	case "error":
		slog.Error(message, "detail", detail)
	case "warn":
		slog.Warn(message, "detail", detail)
	default:
		slog.Info(message, "detail", detail)
	}
}
main.App.GetCommLog method · go · L91-L96 (6 LOC)
commlog.go
func (a *App) GetCommLog() []LogEntry {
	if a.commLog == nil {
		return nil
	}
	return a.commLog.getAll()
}
main.App.GetCommStats method · go · L99-L112 (14 LOC)
commlog.go
func (a *App) GetCommStats() *CommStats {
	a.mu.Lock()
	defer a.mu.Unlock()

	stats := &CommStats{}
	if a.lg != nil {
		ls := a.lg.Stats()
		stats.SamplesTotal = ls.SampleCount
		stats.ErrorsTotal = ls.ErrorCount
		stats.CurrentHz = ls.CurrentHz
		stats.UptimeSeconds = ls.UptimeSeconds
	}
	return stats
}
main.App.emitStats method · go · L115-L137 (23 LOC)
commlog.go
func (a *App) emitStats() {
	ticker := time.NewTicker(2 * time.Second)
	defer ticker.Stop()
	for {
		<-ticker.C
		a.mu.Lock()
		if a.lg == nil || !a.lg.IsRunning() {
			a.mu.Unlock()
			return
		}
		ls := a.lg.Stats()
		a.mu.Unlock()

		if a.ctx != nil {
			runtime.EventsEmit(a.ctx, "comm:stats", CommStats{
				SamplesTotal:  ls.SampleCount,
				ErrorsTotal:   ls.ErrorCount,
				CurrentHz:     ls.CurrentHz,
				UptimeSeconds: ls.UptimeSeconds,
			})
		}
	}
}
Repobility · MCP-ready · https://repobility.com
cli.init function · go · L111-L116 (6 LOC)
internal/cli/import.go
func init() {
	importCmd.Flags().StringVarP(&importFile, "file", "f", "", "PDB file to import")
	importCmd.Flags().StringVarP(&importOutput, "output", "o", "", "Output file (auto-generated if empty)")
	importCmd.Flags().StringVar(&importFormat, "format", "csv", "Output format: csv or mmcd")
	rootCmd.AddCommand(importCmd)
}
cli.init function · go · L175-L180 (6 LOC)
internal/cli/log.go
func init() {
	logCmd.Flags().StringVarP(&logSensors, "sensors", "s", "", "Sensor slugs to poll (comma-separated, or 'all')")
	logCmd.Flags().StringVarP(&logOutput, "output", "o", "", "Output CSV file path")
	logCmd.Flags().BoolVarP(&logDisplay, "display", "d", true, "Show live values in terminal")
	rootCmd.AddCommand(logCmd)
}
cli.init function · go · L59-L69 (11 LOC)
internal/cli/root.go
func init() {
	rootCmd.PersistentFlags().StringVarP(&cfgPort, "port", "p", "", "Serial port (e.g. /dev/ttyUSB0, COM3)")
	rootCmd.PersistentFlags().IntVarP(&cfgBaud, "baud", "b", 1953, "Serial baud rate")
	rootCmd.PersistentFlags().StringVarP(&cfgUnits, "units", "u", "metric", "Unit system: metric, imperial, raw")
	rootCmd.PersistentFlags().BoolVarP(&cfgVerbose, "verbose", "v", false, "Enable debug logging")
	rootCmd.PersistentFlags().StringVar(&cfgLogFile, "log-file", "", "Write log output to file")
	rootCmd.PersistentFlags().BoolVar(&cfgYes, "yes", false, "Skip confirmation prompts")
	rootCmd.AddCommand(aboutCmd)

	cobra.OnInitialize(initLogging)
}
cli.initLogging function · go · L71-L89 (19 LOC)
internal/cli/root.go
func initLogging() {
	level := slog.LevelInfo
	if cfgVerbose {
		level = slog.LevelDebug
	}

	var w io.Writer = os.Stderr
	if cfgLogFile != "" {
		f, err := os.OpenFile(cfgLogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Warning: could not open log file %s: %v\n", cfgLogFile, err)
		} else {
			w = io.MultiWriter(os.Stderr, f)
		}
	}

	handler := slog.NewTextHandler(w, &slog.HandlerOptions{Level: level})
	slog.SetDefault(slog.New(handler))
}
cli.confirmPrompt function · go · L93-L102 (10 LOC)
internal/cli/root.go
func confirmPrompt(msg string) bool {
	if cfgYes {
		return true
	}
	fmt.Printf("%s (y/N): ", msg)
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')
	line = strings.TrimSpace(strings.ToLower(line))
	return line == "y" || line == "yes"
}
cli.Execute function · go · L105-L110 (6 LOC)
internal/cli/root.go
func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
logger.NewCSVWriter function · go · L26-L55 (30 LOC)
internal/logger/csv.go
func NewCSVWriter(filename string, defs []sensor.Definition, indices []int, units sensor.UnitSystem) (*CSVWriter, error) {
	f, err := os.Create(filename)
	if err != nil {
		return nil, fmt.Errorf("failed to create CSV file %s: %w", filename, err)
	}

	w := csv.NewWriter(f)

	// Write header row
	header := []string{"Timestamp", "Elapsed_ms"}
	for _, idx := range indices {
		if idx >= 0 && idx < len(defs) && defs[idx].Exists {
			header = append(header, defs[idx].Slug)
			header = append(header, defs[idx].Slug+"_raw")
		}
	}
	if err := w.Write(header); err != nil {
		f.Close()
		return nil, fmt.Errorf("failed to write CSV header: %w", err)
	}
	w.Flush()

	return &CSVWriter{
		file:    f,
		writer:  w,
		defs:    defs,
		indices: indices,
		units:   units,
	}, nil
}
logger.CSVWriter.WriteSample method · go · L58-L98 (41 LOC)
internal/logger/csv.go
func (cw *CSVWriter) WriteSample(sample sensor.Sample) error {
	cw.mu.Lock()
	defer cw.mu.Unlock()

	if cw.count == 0 {
		cw.startTime = sample.Time
	}

	elapsed := sample.Time.Sub(cw.startTime).Milliseconds()

	row := []string{
		sample.Time.Format("2006-01-02T15:04:05.000"),
		fmt.Sprintf("%d", elapsed),
	}

	for _, idx := range cw.indices {
		if idx >= 0 && idx < len(cw.defs) && cw.defs[idx].Exists {
			if sample.HasData(idx) {
				row = append(row, cw.defs[idx].Format(sample.RawData[idx], cw.units))
				row = append(row, fmt.Sprintf("%d", sample.RawData[idx]))
			} else {
				row = append(row, "")
				row = append(row, "")
			}
		}
	}

	if err := cw.writer.Write(row); err != nil {
		return fmt.Errorf("failed to write CSV row: %w", err)
	}

	cw.count++

	// Flush every write for crash safety
	cw.writer.Flush()
	if err := cw.writer.Error(); err != nil {
		return fmt.Errorf("CSV flush error: %w", err)
	}

	return nil
}
Source: Repobility analyzer · https://repobility.com
logger.CSVWriter.Close method · go · L101-L111 (11 LOC)
internal/logger/csv.go
func (cw *CSVWriter) Close() error {
	cw.mu.Lock()
	defer cw.mu.Unlock()

	cw.writer.Flush()
	if err := cw.writer.Error(); err != nil {
		cw.file.Close()
		return fmt.Errorf("CSV flush error: %w", err)
	}
	return cw.file.Close()
}
logger.ReadCSVLog function · go · L21-L106 (86 LOC)
internal/logger/csv_reader.go
func ReadCSVLog(filename string) (*CSVLog, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, fmt.Errorf("failed to open CSV: %w", err)
	}
	defer f.Close()

	reader := csv.NewReader(f)
	records, err := reader.ReadAll()
	if err != nil {
		return nil, fmt.Errorf("failed to parse CSV: %w", err)
	}

	if len(records) < 2 {
		return nil, fmt.Errorf("CSV has no data rows")
	}

	header := records[0]

	// Identify converted value columns (not Timestamp, Elapsed_ms, or *_raw)
	type colInfo struct {
		slug string
		col  int
	}
	var cols []colInfo
	elapsedCol := -1
	for i, h := range header {
		if h == "Elapsed_ms" {
			elapsedCol = i
			continue
		}
		if h == "Timestamp" || h == "" {
			continue
		}
		if strings.HasSuffix(h, "_raw") {
			continue
		}
		cols = append(cols, colInfo{slug: h, col: i})
	}

	if len(cols) == 0 {
		return nil, fmt.Errorf("no sensor columns found in CSV header")
	}

	slugs := make([]string, len(cols))
	data := make(map[string][]float64, len(cols))
	for i
logger.New function · go · L57-L65 (9 LOC)
internal/logger/logger.go
func New(poller SamplePoller, defs []sensor.Definition, indices []int, units sensor.UnitSystem) *Logger {
	return &Logger{
		poller:   poller,
		defs:     defs,
		indices:  indices,
		units:    units,
		pollRate: 1 * time.Millisecond, // as fast as possible for real ECU
	}
}
logger.Logger.Stats method · go · L96-L112 (17 LOC)
internal/logger/logger.go
func (l *Logger) Stats() LoggerStats {
	l.mu.Lock()
	defer l.mu.Unlock()
	var hz float64
	if !l.startTime.IsZero() {
		elapsed := time.Since(l.startTime).Seconds()
		if elapsed > 0 {
			hz = float64(l.sampleCount) / elapsed
		}
	}
	return LoggerStats{
		SampleCount:   l.sampleCount,
		ErrorCount:    l.errorCount,
		CurrentHz:     hz,
		UptimeSeconds: time.Since(l.startTime).Seconds(),
	}
}
logger.Logger.Start method · go · L115-L130 (16 LOC)
internal/logger/logger.go
func (l *Logger) Start() error {
	l.mu.Lock()
	if l.running {
		l.mu.Unlock()
		return nil
	}

	ctx, cancel := context.WithCancel(context.Background())
	l.cancel = cancel
	l.running = true
	l.mu.Unlock()

	go l.pollLoop(ctx)
	slog.Info("logger started", "sensors", len(l.indices))
	return nil
}
logger.Logger.Stop method · go · L133-L144 (12 LOC)
internal/logger/logger.go
func (l *Logger) Stop() {
	l.mu.Lock()
	defer l.mu.Unlock()

	if !l.running {
		return
	}

	l.cancel()
	l.running = false
	slog.Info("logger stopped")
}
logger.Logger.pollLoop method · go · L170-L237 (68 LOC)
internal/logger/logger.go
func (l *Logger) pollLoop(ctx context.Context) {
	ticker := time.NewTicker(l.pollRate)
	defer ticker.Stop()

	l.mu.Lock()
	l.startTime = time.Now()
	l.sampleCount = 0
	l.errorCount = 0
	l.consecutiveErrs = 0
	l.mu.Unlock()

	for {
		select {
		case <-ctx.Done():
			return
		case <-ticker.C:
			l.mu.Lock()
			indices := make([]int, len(l.indices))
			copy(indices, l.indices)
			l.mu.Unlock()

			if len(indices) == 0 {
				time.Sleep(100 * time.Millisecond)
				continue
			}

			sample, err := l.poller.PollSensors(indices)
			if err != nil {
				l.mu.Lock()
				l.errorCount++
				l.consecutiveErrs++
				consecErrs := l.consecutiveErrs
				errCbs := make([]ErrorCallback, len(l.errCbs))
				copy(errCbs, l.errCbs)
				disconnCb := l.disconnCb
				l.mu.Unlock()

				slog.Debug("poll error", "error", err, "consecutive", consecErrs)

				for _, cb := range errCbs {
					cb(err)
				}

				// Watchdog: if too many consecutive errors, assume disconnect
				if consecErrs >= watchdogThreshold {
		
logger.ParsePDB function · go · L66-L196 (131 LOC)
internal/logger/pdb.go
func ParsePDB(filename string) (*PDBLog, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, fmt.Errorf("failed to open PDB file: %w", err)
	}
	defer f.Close()

	// Read header
	var hdr pdbHeader
	if err := binary.Read(f, binary.BigEndian, &hdr); err != nil {
		return nil, fmt.Errorf("failed to read PDB header: %w", err)
	}

	// Validate type and creator
	typeStr := string(hdr.Type[:])
	creatorStr := string(hdr.Creator[:])
	if typeStr != "strm" || creatorStr != "MMCd" {
		return nil, fmt.Errorf("not an MMCd log file: type=%q creator=%q", typeStr, creatorStr)
	}

	// Extract null-terminated name
	nameBytes := hdr.Name[:]
	nameEnd := 0
	for i, b := range nameBytes {
		if b == 0 {
			nameEnd = i
			break
		}
	}
	if nameEnd == 0 {
		nameEnd = len(nameBytes)
	}

	log := &PDBLog{
		Name: string(nameBytes[:nameEnd]),
	}

	// Read record index entries
	records := make([]pdbRecordEntry, hdr.NumRecords)
	for i := 0; i < int(hdr.NumRecords); i++ {
		if err := binary.Read(f, binar
Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
logger.PDBToCSV function · go · L199-L239 (41 LOC)
internal/logger/pdb.go
func PDBToCSV(pdbLog *PDBLog, outputFile string, defs []sensor.Definition, units sensor.UnitSystem) error {
	if len(pdbLog.Samples) == 0 {
		return fmt.Errorf("no samples in PDB log")
	}

	// Determine which sensor indices have any data across all samples
	var presentMask uint32
	for _, s := range pdbLog.Samples {
		presentMask |= s.DataPresent
	}

	var indices []int
	for i := 0; i < sensor.MaxSensors; i++ {
		if presentMask&(1<<uint(i)) != 0 {
			indices = append(indices, i)
		}
	}

	// Also add INJD if RPM and INJP are present
	hasRPM := presentMask&(1<<17) != 0
	hasINJP := presentMask&(1<<19) != 0
	if hasRPM && hasINJP {
		indices = append(indices, 20) // INJD
	}

	writer, err := NewCSVWriter(outputFile, defs, indices, units)
	if err != nil {
		return err
	}
	defer writer.Close()

	for i := range pdbLog.Samples {
		// Compute derivatives (INJD) for each sample
		pdbLog.Samples[i].ComputeDerivatives(defs)
		if err := writer.WriteSample(pdbLog.Samples[i]); err != nil {
			return fmt.E
logger.NewBinaryWriter function · go · L53-L84 (32 LOC)
internal/logger/store.go
func NewBinaryWriter(filename string, indices []int, units sensor.UnitSystem) (*BinaryWriter, error) {
	f, err := os.Create(filename)
	if err != nil {
		return nil, fmt.Errorf("failed to create binary log %s: %w", filename, err)
	}

	// Write header
	header := make([]byte, mmcdHeaderSize)
	copy(header[0:4], mmcdMagic)
	header[4] = mmcdVersion
	header[5] = byte(units)
	binary.LittleEndian.PutUint16(header[6:8], uint16(len(indices)))
	binary.LittleEndian.PutUint32(header[8:12], 0) // sample count placeholder
	// header[12:16] reserved

	if _, err := f.Write(header); err != nil {
		f.Close()
		return nil, fmt.Errorf("failed to write header: %w", err)
	}

	// Write sensor index table
	indexTable := make([]byte, len(indices))
	for i, idx := range indices {
		indexTable[i] = byte(idx)
	}
	if _, err := f.Write(indexTable); err != nil {
		f.Close()
		return nil, fmt.Errorf("failed to write index table: %w", err)
	}

	return &BinaryWriter{file: f}, nil
}
logger.BinaryWriter.WriteSample method · go · L87-L99 (13 LOC)
internal/logger/store.go
func (bw *BinaryWriter) WriteSample(sample sensor.Sample) error {
	buf := make([]byte, mmcdSampleSize)
	binary.LittleEndian.PutUint64(buf[0:8], uint64(sample.Time.UnixNano()))
	binary.LittleEndian.PutUint32(buf[8:12], sample.DataPresent)
	// buf[12:16] padding
	copy(buf[16:48], sample.RawData[:])

	if _, err := bw.file.Write(buf); err != nil {
		return fmt.Errorf("failed to write sample: %w", err)
	}
	bw.sampleCount++
	return nil
}
logger.BinaryWriter.Close method · go · L102-L110 (9 LOC)
internal/logger/store.go
func (bw *BinaryWriter) Close() error {
	// Update sample count in header
	if _, err := bw.file.Seek(8, io.SeekStart); err == nil {
		countBuf := make([]byte, 4)
		binary.LittleEndian.PutUint32(countBuf, bw.sampleCount)
		bw.file.Write(countBuf)
	}
	return bw.file.Close()
}
logger.ReadBinaryLog function · go · L127-L184 (58 LOC)
internal/logger/store.go
func ReadBinaryLog(filename string) (*BinaryLog, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, fmt.Errorf("failed to open binary log: %w", err)
	}
	defer f.Close()

	// Read header
	header := make([]byte, mmcdHeaderSize)
	if _, err := io.ReadFull(f, header); err != nil {
		return nil, fmt.Errorf("failed to read header: %w", err)
	}

	if string(header[0:4]) != mmcdMagic {
		return nil, fmt.Errorf("not an MMCD binary log (bad magic)")
	}

	log := &BinaryLog{
		Version:     header[4],
		Units:       sensor.UnitSystem(header[5]),
		SampleCount: binary.LittleEndian.Uint32(header[8:12]),
	}

	sensorCount := binary.LittleEndian.Uint16(header[6:8])

	// Read sensor index table
	indexTable := make([]byte, sensorCount)
	if _, err := io.ReadFull(f, indexTable); err != nil {
		return nil, fmt.Errorf("failed to read index table: %w", err)
	}
	log.Indices = make([]int, sensorCount)
	for i, b := range indexTable {
		log.Indices[i] = int(b)
	}

	// Read samples
	log.Samples = ma
protocol.decodeDTCs function · go · L54-L62 (9 LOC)
internal/protocol/dtc.go
func decodeDTCs(bitmap uint16) []DTCCode {
	var codes []DTCCode
	for i := 0; i < 16; i++ {
		if bitmap&(1<<uint(i)) != 0 {
			codes = append(codes, dtcTable[i])
		}
	}
	return codes
}
protocol.ECU.ReadDTCs method · go · L65-L109 (45 LOC)
internal/protocol/dtc.go
func (e *ECU) ReadDTCs() (*DTCResult, error) {
	if !e.conn.IsOpen() {
		if err := e.conn.Open(); err != nil {
			return nil, err
		}
		defer e.conn.Close()
	}

	// Flush stale bytes before reading DTCs
	e.conn.Flush()

	result := &DTCResult{}

	// Read active DTCs (low byte)
	activeLow, err := e.QuerySensor(AddrActiveDTCLow)
	if err != nil {
		return nil, fmt.Errorf("failed to read active DTC low byte: %w", err)
	}

	// Read active DTCs (high byte)
	activeHigh, err := e.QuerySensor(AddrActiveDTCHigh)
	if err != nil {
		return nil, fmt.Errorf("failed to read active DTC high byte: %w", err)
	}

	result.ActiveRaw = uint16(activeLow) | (uint16(activeHigh) << 8)
	result.Active = decodeDTCs(result.ActiveRaw)

	// Read stored DTCs (low byte)
	storedLow, err := e.QuerySensor(AddrStoredDTCLow)
	if err != nil {
		return nil, fmt.Errorf("failed to read stored DTC low byte: %w", err)
	}

	// Read stored DTCs (high byte)
	storedHigh, err := e.QuerySensor(AddrStoredDTCHigh)
	if err != nil {
		return
protocol.ECU.EraseDTCs method · go · L112-L130 (19 LOC)
internal/protocol/dtc.go
func (e *ECU) EraseDTCs() error {
	if !e.conn.IsOpen() {
		if err := e.conn.Open(); err != nil {
			return err
		}
		defer e.conn.Close()
	}

	result, err := e.SendCommand(AddrEraseDTC, 2*time.Second)
	if err != nil {
		return fmt.Errorf("failed to erase DTCs: %w", err)
	}

	if result != 0x00 {
		return fmt.Errorf("unexpected erase DTC response: 0x%02X", result)
	}

	return nil
}
All rows scored by the Repobility analyzer (https://repobility.com)
protocol.NewECU function · go · L28-L33 (6 LOC)
internal/protocol/ecu.go
func NewECU(conn *SerialConn, defs []sensor.Definition) *ECU {
	return &ECU{
		conn: conn,
		defs: defs,
	}
}
protocol.ECU.QuerySensor method · go · L39-L80 (42 LOC)
internal/protocol/ecu.go
func (e *ECU) QuerySensor(addr byte) (byte, error) {
	if addr >= 0xC0 {
		return 0, fmt.Errorf("address 0x%02X is in command range (>=0xC0), refusing to poll", addr)
	}

	e.busMu.Lock()
	defer e.busMu.Unlock()

	// Send the address byte
	_, err := e.conn.Send([]byte{addr})
	if err != nil {
		return 0, fmt.Errorf("failed to send sensor address 0x%02X: %w", addr, err)
	}

	// Read 2 bytes: echo + data
	buf := make([]byte, 2)
	totalRead := 0
	deadline := time.Now().Add(500 * time.Millisecond)

	for totalRead < 2 && time.Now().Before(deadline) {
		n, err := e.conn.Receive(buf[totalRead:])
		if err != nil {
			e.conn.Flush()
			return 0, fmt.Errorf("failed to read response for 0x%02X: %w", addr, err)
		}
		totalRead += n
	}

	if totalRead < 2 {
		e.conn.Flush()
		return 0, fmt.Errorf("timeout reading response for 0x%02X: got %d bytes", addr, totalRead)
	}

	// Verify echo — discard sample on mismatch
	if buf[0] != addr {
		slog.Warn("ECU echo mismatch", "expected", fmt.Sprintf("0x%02X", add
protocol.ECU.PollSensors method · go · L83-L109 (27 LOC)
internal/protocol/ecu.go
func (e *ECU) PollSensors(indices []int) (sensor.Sample, error) {
	var sample sensor.Sample
	sample.Time = time.Now()

	for _, idx := range indices {
		if idx < 0 || idx >= len(e.defs) {
			continue
		}
		def := e.defs[idx]
		if !def.Exists || def.Computed || def.Addr == 0xFF {
			continue
		}

		data, err := e.QuerySensor(def.Addr)
		if err != nil {
			slog.Debug("sensor query failed", "slug", def.Slug, "addr", fmt.Sprintf("0x%02X", def.Addr), "error", err)
			continue
		}

		sample.SetData(idx, data)
	}

	// Compute derived values (e.g., injector duty cycle)
	sample.ComputeDerivatives(e.defs)

	return sample, nil
}
page 1 / 2next ›