Merge pull request 'Add "native" candump support' (#2) from feat/candump into master
Reviewed-on: #2
This commit was merged in pull request #2.
This commit is contained in:
@@ -117,10 +117,11 @@ 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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+72
-71
@@ -2,11 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChademoEvent interface {
|
type ChademoEvent interface {
|
||||||
// GetValue Return processed/calculated value and timestamp string
|
// GetValue Return processed/calculated value and timestamp string
|
||||||
GetValue() (interface{}, *string)
|
GetValue() (interface{}, *time.Time)
|
||||||
}
|
}
|
||||||
|
|
||||||
type frame struct {
|
type frame struct {
|
||||||
@@ -266,142 +267,142 @@ func getChargerStopControl(bytes *[]uint8) StopControl {
|
|||||||
return OPERATING
|
return OPERATING
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MaximumBatteryVoltage) GetValue() (interface{}, *string) {
|
func (m MaximumBatteryVoltage) GetValue() (interface{}, *time.Time) {
|
||||||
return bytesToUint16(m.payload[4:6]), &m.date
|
return bytesToUint16((*m.payload)[4:6]), m.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ConstChargingRateInd) GetValue() (interface{}, *string) {
|
func (c ConstChargingRateInd) GetValue() (interface{}, *time.Time) {
|
||||||
return c.payload[6], &c.date
|
return (*c.payload)[6], c.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BatteryCapacity) GetValue() (interface{}, *string) {
|
func (b BatteryCapacity) GetValue() (interface{}, *time.Time) {
|
||||||
return 0.1 * float32(bytesToUint16(b.payload[5:7])), &b.date
|
return 0.1 * float32(bytesToUint16((*b.payload)[5:7])), b.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MaxChargingTimeS) GetValue() (interface{}, *string) {
|
func (m MaxChargingTimeS) GetValue() (interface{}, *time.Time) {
|
||||||
return 10 * uint16(m.payload[1]), &m.date
|
return 10 * uint16((*m.payload)[1]), m.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MaxChargingTimeM) GetValue() (interface{}, *string) {
|
func (m MaxChargingTimeM) GetValue() (interface{}, *time.Time) {
|
||||||
return m.payload[2], &m.date
|
return (*m.payload)[2], m.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e EstChargingTimeM) GetValue() (interface{}, *string) {
|
func (e EstChargingTimeM) GetValue() (interface{}, *time.Time) {
|
||||||
return e.payload[3], &e.date
|
return (*e.payload)[3], e.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c EVControlProtocolNumber) GetValue() (interface{}, *string) {
|
func (c EVControlProtocolNumber) GetValue() (interface{}, *time.Time) {
|
||||||
return c.payload[0], &c.date
|
return (*c.payload)[0], c.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t TargetBatteryVoltage) GetValue() (interface{}, *string) {
|
func (t TargetBatteryVoltage) GetValue() (interface{}, *time.Time) {
|
||||||
return bytesToUint16(t.payload[1:3]), &t.date
|
return bytesToUint16((*t.payload)[1:3]), t.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ChargingCurrentReq) GetValue() (interface{}, *string) {
|
func (c ChargingCurrentReq) GetValue() (interface{}, *time.Time) {
|
||||||
return c.payload[3], &c.date
|
return (*c.payload)[3], c.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ChargingRate) GetValue() (interface{}, *string) {
|
func (c ChargingRate) GetValue() (interface{}, *time.Time) {
|
||||||
return c.payload[6], &c.date
|
return (*c.payload)[6], c.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s ShiftLever) GetValue() (interface{}, *string) {
|
func (s ShiftLever) GetValue() (interface{}, *time.Time) {
|
||||||
return getVehicleShiftLever(&s.payload), &s.date
|
return getVehicleShiftLever(s.payload), s.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v VehicleCharging) GetValue() (interface{}, *string) {
|
func (v VehicleCharging) GetValue() (interface{}, *time.Time) {
|
||||||
return getVehicleCharging(&v.payload), &v.date
|
return getVehicleCharging(v.payload), v.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ChargingSystemFault) GetValue() (interface{}, *string) {
|
func (c ChargingSystemFault) GetValue() (interface{}, *time.Time) {
|
||||||
return getFault(&c.payload, 5, 2), &c.date
|
return getFault(c.payload, 5, 2), c.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v VehicleStatus) GetValue() (interface{}, *string) {
|
func (v VehicleStatus) GetValue() (interface{}, *time.Time) {
|
||||||
return getVehicleStatus(&v.payload), &v.date
|
return getVehicleStatus(v.payload), v.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n NormalStopReq) GetValue() (interface{}, *string) {
|
func (n NormalStopReq) GetValue() (interface{}, *time.Time) {
|
||||||
return getNormalStopReq(&n.payload), &n.date
|
return getNormalStopReq(n.payload), n.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BattOvervoltage) GetValue() (interface{}, *string) {
|
func (b BattOvervoltage) GetValue() (interface{}, *time.Time) {
|
||||||
return getFault(&b.payload, 4, 0), &b.date
|
return getFault(b.payload, 4, 0), b.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BattUndervoltage) GetValue() (interface{}, *string) {
|
func (b BattUndervoltage) GetValue() (interface{}, *time.Time) {
|
||||||
return getFault(&b.payload, 4, 1), &b.date
|
return getFault(b.payload, 4, 1), b.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BattCurrentDeviationErr) GetValue() (interface{}, *string) {
|
func (b BattCurrentDeviationErr) GetValue() (interface{}, *time.Time) {
|
||||||
return getFault(&b.payload, 4, 2), &b.date
|
return getFault(b.payload, 4, 2), b.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h HighBattTemperature) GetValue() (interface{}, *string) {
|
func (h HighBattTemperature) GetValue() (interface{}, *time.Time) {
|
||||||
return getFault(&h.payload, 4, 3), &h.date
|
return getFault(h.payload, 4, 3), h.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BattVoltageDeviationErr) GetValue() (interface{}, *string) {
|
func (b BattVoltageDeviationErr) GetValue() (interface{}, *time.Time) {
|
||||||
return getFault(&b.payload, 4, 4), &b.date
|
return getFault(b.payload, 4, 4), b.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e EVcontWeldingDetectSupport) GetValue() (interface{}, *string) {
|
func (e EVcontWeldingDetectSupport) GetValue() (interface{}, *time.Time) {
|
||||||
return evWeldingDetectionSupport(&e.payload), &e.date
|
return evWeldingDetectionSupport(e.payload), e.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AvailableOutputVoltage) GetValue() (interface{}, *string) {
|
func (a AvailableOutputVoltage) GetValue() (interface{}, *time.Time) {
|
||||||
return bytesToUint16(a.payload[1:3]), &a.date
|
return bytesToUint16((*a.payload)[1:3]), a.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AvailableOutputCurrent) GetValue() (interface{}, *string) {
|
func (a AvailableOutputCurrent) GetValue() (interface{}, *time.Time) {
|
||||||
return a.payload[3], &a.date
|
return (*a.payload)[3], a.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t ThresholdVoltage) GetValue() (interface{}, *string) {
|
func (t ThresholdVoltage) GetValue() (interface{}, *time.Time) {
|
||||||
return bytesToUint16(t.payload[4:6]), &t.date
|
return bytesToUint16((*t.payload)[4:6]), t.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e EVSEControlProtocolNumber) GetValue() (interface{}, *string) {
|
func (e EVSEControlProtocolNumber) GetValue() (interface{}, *time.Time) {
|
||||||
return e.payload[0], &e.date
|
return (*e.payload)[0], e.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o OutputVoltage) GetValue() (interface{}, *string) {
|
func (o OutputVoltage) GetValue() (interface{}, *time.Time) {
|
||||||
return bytesToUint16(o.payload[1:3]), &o.date
|
return bytesToUint16((*o.payload)[1:3]), o.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o OutputCurrent) GetValue() (interface{}, *string) {
|
func (o OutputCurrent) GetValue() (interface{}, *time.Time) {
|
||||||
return o.payload[3], &o.date
|
return (*o.payload)[3], o.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r RemainingChargingTimeS) GetValue() (interface{}, *string) {
|
func (r RemainingChargingTimeS) GetValue() (interface{}, *time.Time) {
|
||||||
return r.payload[6] * 10, &r.date
|
return (*r.payload)[6] * 10, r.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r RemainingChargingTimeM) GetValue() (interface{}, *string) {
|
func (r RemainingChargingTimeM) GetValue() (interface{}, *time.Time) {
|
||||||
return r.payload[7], &r.date
|
return (*r.payload)[7], r.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StationStatus) GetValue() (interface{}, *string) {
|
func (s StationStatus) GetValue() (interface{}, *time.Time) {
|
||||||
return getStationState(&s.payload), &s.date
|
return getStationState(s.payload), s.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StationMalfunction) GetValue() (interface{}, *string) {
|
func (s StationMalfunction) GetValue() (interface{}, *time.Time) {
|
||||||
return getFault(&s.payload, 5, 1), &s.date
|
return getFault(s.payload, 5, 1), s.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v VehicleConnectorLock) GetValue() (interface{}, *string) {
|
func (v VehicleConnectorLock) GetValue() (interface{}, *time.Time) {
|
||||||
return getConnectorLock(&v.payload), &v.date
|
return getConnectorLock(v.payload), v.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BatteryIncompatibility) GetValue() (interface{}, *string) {
|
func (b BatteryIncompatibility) GetValue() (interface{}, *time.Time) {
|
||||||
return getBatteryCompatibility(&b.payload), &b.date
|
return getBatteryCompatibility(b.payload), b.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ChargingSystemMalfunction) GetValue() (interface{}, *string) {
|
func (c ChargingSystemMalfunction) GetValue() (interface{}, *time.Time) {
|
||||||
return getFault(&c.payload, 5, 4), &c.date
|
return getFault(c.payload, 5, 4), c.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ChargerStopControl) GetValue() (interface{}, *string) {
|
func (c ChargerStopControl) GetValue() (interface{}, *time.Time) {
|
||||||
return getChargerStopControl(&c.payload), &c.date
|
return getChargerStopControl(c.payload), c.date
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,18 @@ 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
|
||||||
const expr = "\\((.*)\\)\\s+can\\d+\\s+(\\d+)\\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 = "\\((\\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 length = 11
|
||||||
|
|
||||||
var pattern = regexp.MustCompile(expr)
|
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 {
|
func Readfile(filename *string) <-chan *CanFrame {
|
||||||
c := make(chan *CanFrame)
|
c := make(chan *CanFrame)
|
||||||
@@ -42,15 +47,35 @@ func Readfile(filename *string) <-chan *CanFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fromString(text *string) *CanFrame {
|
func fromString(text *string) *CanFrame {
|
||||||
submatch := pattern.FindStringSubmatch(*text)
|
var match []string
|
||||||
if len(submatch) == length {
|
var now time.Time
|
||||||
canid, err := strconv.ParseUint(submatch[2], 16, 0)
|
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 {
|
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)
|
||||||
@@ -61,9 +86,9 @@ func fromString(text *string) *CanFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &CanFrame{
|
return &CanFrame{
|
||||||
date: submatch[1],
|
date: &now,
|
||||||
canid: uint32(canid),
|
canid: uint32(canId),
|
||||||
payload: payload,
|
payload: &payload,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-3
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFromString(t *testing.T) {
|
func TestFromString(t *testing.T) {
|
||||||
@@ -11,6 +12,7 @@ func TestFromString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dump = "(2022-07-08 16:54:15.587099) can0 100 [8] 00 00 00 00 00 00 64 00"
|
var dump = "(2022-07-08 16:54:15.587099) can0 100 [8] 00 00 00 00 00 00 64 00"
|
||||||
|
var timestamp = time.Date(2022, 07, 8, 16, 54, 15, 587099, time.Local) //"2022-07-08 16:54:15.587099"
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -23,14 +25,20 @@ func TestFromString(t *testing.T) {
|
|||||||
args: args{text: &dump},
|
args: args{text: &dump},
|
||||||
want: &CanFrame{
|
want: &CanFrame{
|
||||||
canid: CAN_ID_100,
|
canid: CAN_ID_100,
|
||||||
date: "2022-07-08 16:54:15.587099",
|
date: ×tamp,
|
||||||
payload: []uint8{0, 0, 0, 0, 0, 0, 0x64, 0},
|
payload: &[]uint8{0, 0, 0, 0, 0, 0, 0x64, 0},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
if got := fromString(tt.args.text); !reflect.DeepEqual(got, tt.want) {
|
var got = fromString(tt.args.text)
|
||||||
|
|
||||||
|
var isDate = got.date.Compare(*tt.want.date) == 0
|
||||||
|
var isPayload = reflect.DeepEqual(*got.payload, *tt.want.payload)
|
||||||
|
var isId = got.canid == tt.want.canid
|
||||||
|
|
||||||
|
if isDate && isPayload && isId {
|
||||||
t.Errorf("fromString() = %v, want %v", got, tt.want)
|
t.Errorf("fromString() = %v, want %v", got, tt.want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CAN_ID_100 = 0x100
|
CAN_ID_100 = 0x100
|
||||||
CAN_ID_101 = 0x101
|
CAN_ID_101 = 0x101
|
||||||
@@ -60,8 +62,8 @@ type StopControl uint8
|
|||||||
|
|
||||||
type CanFrame struct {
|
type CanFrame struct {
|
||||||
canid uint32
|
canid uint32
|
||||||
payload []uint8
|
payload *[]uint8
|
||||||
date string
|
date *time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v VehicleChargingEnabled) String() string {
|
func (v VehicleChargingEnabled) String() string {
|
||||||
|
|||||||
Reference in New Issue
Block a user