Correct timestamp when reading from stdin or file

refactor
Terekhin Alexandr 2 years ago
parent e42d3b5722
commit 6521b707dd
Signed by: didinst
GPG Key ID: D2EF94423C23BF12
  1. 5
      can/can.go
  2. 44
      can/input.go
  3. 59
      can/input_test.go
  4. 11
      yabl/protocol.go

@ -40,7 +40,7 @@ const CAN_ID_065 = 0x065
type CanFrame struct { type CanFrame struct {
CanId uint32 CanId uint32
Payload []uint8 Payload []uint8
Date string Date *time.Time
} }
// NewCan New returns a new CAN bus socket. // NewCan New returns a new CAN bus socket.
@ -167,8 +167,9 @@ func StartCan(canbus string) (<-chan *CanFrame, error) {
for { //TODO implement stop for { //TODO implement stop
if id, data, serr := socket.Recv(); serr == nil { if id, data, serr := socket.Recv(); serr == nil {
var now = time.Now()
canevents <- &CanFrame{ canevents <- &CanFrame{
Date: time.Now().String(), Date: &now,
CanId: id, CanId: id,
Payload: data, Payload: data,
} }

@ -6,13 +6,15 @@ import (
"os" "os"
"regexp" "regexp"
"strconv" "strconv"
"time"
) )
// (2022-07-08 16:54:15.587099) can0 100 [8] 00 00 00 00 00 00 64 00 // (2022-07-08 16:54:15.587099) can0 100 [8] 00 00 00 00 00 00 64 00
// (1670578900.771868) can0 00004021#00000000FCFFFFFF // (1670578900.771868) can0 00004021#00000000FCFFFFFF
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_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 = "\\((.*)\\)\\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 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"
const base_length = 11
var patternHr = regexp.MustCompile(EXPR_HR) var patternHr = regexp.MustCompile(EXPR_HR)
var patternM = regexp.MustCompile(EXPR_M) var patternM = regexp.MustCompile(EXPR_M)
@ -40,7 +42,7 @@ func Readfile(filename *string) <-chan *CanFrame {
func process(scanner *bufio.Scanner, ch chan<- *CanFrame) { func process(scanner *bufio.Scanner, ch chan<- *CanFrame) {
for scanner.Scan() { for scanner.Scan() {
text := scanner.Text() text := scanner.Text()
if frame := fromString(&text); frame != nil { if frame := fromString(text); frame != nil {
ch <- frame ch <- frame
} }
} }
@ -60,22 +62,36 @@ func ReadStdin() <-chan *CanFrame {
return c return c
} }
func fromString(text *string) *CanFrame { func fromString(text string) *CanFrame {
var submatch []string var match []string
if submatch = patternHr.FindStringSubmatch(*text); submatch == nil { var now time.Time
if submatch = patternM.FindStringSubmatch(*text); submatch == nil { var offset int
return nil
} 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(submatch) == length { if len(match) == base_length+offset {
canid, err := strconv.ParseUint(submatch[2], 16, 0) canId, err := strconv.ParseUint(match[2+offset], 16, 0)
if err != nil { if err != nil {
return nil return nil
} }
payload := make([]uint8, 8) payload := make([]uint8, 8)
for idx, octet := range submatch[3:] { for idx, octet := range match[3+offset:] {
val, err := strconv.ParseUint(octet, 16, 0) val, err := strconv.ParseUint(octet, 16, 0)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@ -86,8 +102,8 @@ func fromString(text *string) *CanFrame {
} }
return &CanFrame{ return &CanFrame{
Date: submatch[1], Date: &now,
CanId: uint32(canid), CanId: uint32(canId),
Payload: payload, Payload: payload,
} }
} }

@ -0,0 +1,59 @@
package can
import (
"reflect"
"testing"
"time"
)
const (
frame_hr = "(2022-07-08 16:54:15.587099) can0 100 [8] 00 00 00 00 00 00 64 00"
frame_m = "(1670578900.771868) can0 00004021#00000000FCFFFFFF"
)
func Test_fromString(t *testing.T) {
var time_m, err1 = time.ParseInLocation("2006-01-02T15:04:05.000000", "2022-12-09T09:41:40.771868", time.Local)
var time_p, err2 = time.ParseInLocation("2006-01-02 15:04:05.000000", "2022-07-08 16:54:15.587099", time.Local)
if err1 != nil || err2 != nil {
t.Error()
}
//time_m = time_m.In(time.Local)
//time_p = time_p.In(time.Local)
type args struct {
text string
}
tests := []struct {
name string
args args
want *CanFrame
}{
{
name: "Machine readable time",
args: args{text: frame_m},
want: &CanFrame{
Date: &time_m,
CanId: 0x4021,
Payload: []uint8{00, 00, 00, 00, 0xFC, 0xFF, 0xFF, 0xFF},
},
},
{
name: "Human readable time",
args: args{text: frame_hr},
want: &CanFrame{
Date: &time_p,
CanId: 0x100,
Payload: []uint8{00, 00, 00, 00, 00, 00, 0x64, 00},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := fromString(tt.args.text); !reflect.DeepEqual(got, tt.want) {
t.Errorf("fromString() = %v, want %v", got, tt.want)
}
})
}
}

@ -1,7 +1,7 @@
package yabl package yabl
import ( import (
"cli-mon/can" can "cli-mon/can"
"encoding/binary" "encoding/binary"
time "time" time "time"
) )
@ -40,7 +40,7 @@ type Event struct {
ActionName AName ActionName AName
Field FName Field FName
Object Action Object Action
Updated time.Time Updated *time.Time
Value any Value any
} }
@ -55,7 +55,7 @@ type field struct {
length uint8 length uint8
setter func(uint64 uint64) any setter func(uint64 uint64) any
value uint64 value uint64
last time.Time last *time.Time
name FName name FName
} }
@ -106,14 +106,13 @@ func StartProtocolParsing(frames <-chan *can.CanFrame) <-chan *Event {
var unitId = uint((frame.CanId & UNIT_ID_MASK) >> UNIT_ID_OFFSET) var unitId = uint((frame.CanId & UNIT_ID_MASK) >> UNIT_ID_OFFSET)
var canId = frame.CanId & ACTION_ID_MASK var canId = frame.CanId & ACTION_ID_MASK
var k = key{canId: canId, unitId: unitId} var k = key{canId: canId, unitId: unitId}
var now = time.Now()
param := protocolMap[k] param := protocolMap[k]
var start uint8 = 0 var start uint8 = 0
for _, f := range param.fields { for _, f := range param.fields {
if val, found := get(start, f.length, frame.Payload); found { if val, found := get(start, f.length, frame.Payload); found {
f.last = now f.last = frame.Date
if f.value != val { if f.value != val {
f.value = val f.value = val
obj := f.setter(val) obj := f.setter(val)
@ -122,7 +121,7 @@ func StartProtocolParsing(frames <-chan *can.CanFrame) <-chan *Event {
ActionName: param.name, ActionName: param.name,
Object: param.object, Object: param.object,
UnitId: unitId, UnitId: unitId,
Updated: now, Updated: frame.Date,
Value: obj, Value: obj,
} }
} }

Loading…
Cancel
Save