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

@ -6,13 +6,15 @@ import (
"os"
"regexp"
"strconv"
"time"
)
// (2022-07-08 16:54:15.587099) can0 100 [8] 00 00 00 00 00 00 64 00
// (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_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 length = 11
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 time_hr_layout = "2006-01-02 15:04:05.000000"
const base_length = 11
var patternHr = regexp.MustCompile(EXPR_HR)
var patternM = regexp.MustCompile(EXPR_M)
@ -40,7 +42,7 @@ func Readfile(filename *string) <-chan *CanFrame {
func process(scanner *bufio.Scanner, ch chan<- *CanFrame) {
for scanner.Scan() {
text := scanner.Text()
if frame := fromString(&text); frame != nil {
if frame := fromString(text); frame != nil {
ch <- frame
}
}
@ -60,22 +62,36 @@ func ReadStdin() <-chan *CanFrame {
return c
}
func fromString(text *string) *CanFrame {
var submatch []string
if submatch = patternHr.FindStringSubmatch(*text); submatch == nil {
if submatch = patternM.FindStringSubmatch(*text); submatch == nil {
return nil
}
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(submatch) == length {
canid, err := strconv.ParseUint(submatch[2], 16, 0)
if len(match) == base_length+offset {
canId, err := strconv.ParseUint(match[2+offset], 16, 0)
if err != nil {
return nil
}
payload := make([]uint8, 8)
for idx, octet := range submatch[3:] {
for idx, octet := range match[3+offset:] {
val, err := strconv.ParseUint(octet, 16, 0)
if err != nil {
fmt.Println(err)
@ -86,8 +102,8 @@ func fromString(text *string) *CanFrame {
}
return &CanFrame{
Date: submatch[1],
CanId: uint32(canid),
Date: &now,
CanId: uint32(canId),
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
import (
"cli-mon/can"
can "cli-mon/can"
"encoding/binary"
time "time"
)
@ -40,7 +40,7 @@ type Event struct {
ActionName AName
Field FName
Object Action
Updated time.Time
Updated *time.Time
Value any
}
@ -55,7 +55,7 @@ type field struct {
length uint8
setter func(uint64 uint64) any
value uint64
last time.Time
last *time.Time
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 canId = frame.CanId & ACTION_ID_MASK
var k = key{canId: canId, unitId: unitId}
var now = time.Now()
param := protocolMap[k]
var start uint8 = 0
for _, f := range param.fields {
if val, found := get(start, f.length, frame.Payload); found {
f.last = now
f.last = frame.Date
if f.value != val {
f.value = val
obj := f.setter(val)
@ -122,7 +121,7 @@ func StartProtocolParsing(frames <-chan *can.CanFrame) <-chan *Event {
ActionName: param.name,
Object: param.object,
UnitId: unitId,
Updated: now,
Updated: frame.Date,
Value: obj,
}
}

Loading…
Cancel
Save