Simple app to transform IEC 61851-24 CAN bus dump to human readable messages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
chademo-log/files.go

96 lines
2.1 KiB

package main
import (
"bufio"
"fmt"
"os"
"regexp"
"strconv"
"time"
)
// (2022-07-08 16:54:15.587099) can0 100 [8] 00 00 00 00 00 00 64 00
const EXPR_HR = "\\((.*)\\)\\s+can\\d+\\s+(\\S+)\\s+\\[\\d\\]\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)"
const EXPR_M = "\\((\\d+)\\.(\\d+)\\)\\s+can\\d+\\s+(\\S+)#([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})"
const length = 11
const time_hr_layout = "2006-01-02 15:04:05.000000"
var patternHr = regexp.MustCompile(EXPR_HR)
var patternM = regexp.MustCompile(EXPR_M)
func Readfile(filename *string) <-chan *CanFrame {
c := make(chan *CanFrame)
go func() {
defer close(c)
file, err := os.Open(*filename)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
text := scanner.Text()
c <- fromString(&text)
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
}()
return c
}
func fromString(text *string) *CanFrame {
var match []string
var now time.Time
var offset int
if match = patternHr.FindStringSubmatch(*text); match != nil {
now, _ = time.ParseInLocation(time_hr_layout, match[1], time.Local)
offset = 0
} else if match = patternM.FindStringSubmatch(*text); match != nil {
var seconds, _ = strconv.ParseInt(match[1], 10, 0)
var nanos, _ = strconv.ParseInt(match[2], 10, 0)
now = time.Unix(seconds, nanos*1000) //.In(time.Local)
// Correct time to local zone
var _, zoneoffset = now.Zone()
now = now.Add(-time.Duration(zoneoffset) * time.Second)
offset = 1
} else {
return nil
}
if len(match) == length+offset {
canId, err := strconv.ParseUint(match[2+offset], 16, 0)
if err != nil {
return nil
}
payload := make([]uint8, 8)
for idx, octet := range match[3+offset:] {
val, err := strconv.ParseUint(octet, 16, 0)
if err != nil {
fmt.Println(err)
continue
}
payload[idx] = uint8(val)
}
return &CanFrame{
date: &now,
canid: uint32(canId),
payload: &payload,
}
}
return nil
}