Merge pull request 'EVSE to EV, refactor' (#1) from feature/refactor into master
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -1,61 +1,20 @@
|
|||||||
|
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||||
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CanFrame struct {
|
// NewCan New returns a new CAN bus socket.
|
||||||
canid uint32
|
|
||||||
payload []uint8
|
|
||||||
date string
|
|
||||||
}
|
|
||||||
|
|
||||||
// (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 length = 11
|
|
||||||
|
|
||||||
var pattern = regexp.MustCompile(expr)
|
|
||||||
|
|
||||||
func FromString(text *string) *CanFrame {
|
|
||||||
submatch := pattern.FindStringSubmatch(*text)
|
|
||||||
if len(submatch) == length {
|
|
||||||
canid, err := strconv.ParseUint(submatch[2], 16, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
payload := make([]uint8, 8)
|
|
||||||
for idx, octet := range submatch[3:] {
|
|
||||||
val, err := strconv.ParseUint(octet, 16, 0)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
payload[idx] = uint8(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &CanFrame{
|
|
||||||
date: submatch[1],
|
|
||||||
canid: uint32(canid),
|
|
||||||
payload: payload,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a new CAN bus socket.
|
|
||||||
func NewCan() (*Socket, error) {
|
func NewCan() (*Socket, error) {
|
||||||
fd, err := unix.Socket(unix.AF_CAN, unix.SOCK_RAW, unix.CAN_RAW)
|
fd, err := unix.Socket(unix.AF_CAN, unix.SOCK_RAW, unix.CAN_RAW)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -142,6 +101,8 @@ func StartCan(canbus string) (<-chan *CanFrame, error) {
|
|||||||
{Id: CAN_ID_100, Mask: 0xFFF},
|
{Id: CAN_ID_100, Mask: 0xFFF},
|
||||||
{Id: CAN_ID_101, Mask: 0xFFF},
|
{Id: CAN_ID_101, Mask: 0xFFF},
|
||||||
{Id: CAN_ID_102, Mask: 0xFFF},
|
{Id: CAN_ID_102, Mask: 0xFFF},
|
||||||
|
{Id: CAN_ID_108, Mask: 0xFFF},
|
||||||
|
{Id: CAN_ID_109, Mask: 0xFFF},
|
||||||
}
|
}
|
||||||
|
|
||||||
if socket, err := NewCan(); err == nil {
|
if socket, err := NewCan(); err == nil {
|
||||||
@@ -156,8 +117,6 @@ 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 {
|
||||||
//log.Println("debug: data", data)
|
|
||||||
|
|
||||||
canevents <- &CanFrame{
|
canevents <- &CanFrame{
|
||||||
date: time.Now().String(),
|
date: time.Now().String(),
|
||||||
canid: id,
|
canid: id,
|
||||||
|
|||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func StartCan(canbus string) (<-chan *CanFrame, error) {
|
||||||
|
return nil, &NotImplError{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type NotImplError struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *NotImplError) Error() string {
|
||||||
|
return "Not implemented for windows platform"
|
||||||
|
}
|
||||||
+1
-29
@@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@@ -20,7 +19,7 @@ func main() {
|
|||||||
switch {
|
switch {
|
||||||
case len(*filename) > 0:
|
case len(*filename) > 0:
|
||||||
fmt.Printf("Open file %v\n", *filename)
|
fmt.Printf("Open file %v\n", *filename)
|
||||||
frames = readfile(filename)
|
frames = Readfile(filename)
|
||||||
case len(*canbus) > 0:
|
case len(*canbus) > 0:
|
||||||
fmt.Printf("Open device %v\n", canbus)
|
fmt.Printf("Open device %v\n", canbus)
|
||||||
var err error
|
var err error
|
||||||
@@ -58,30 +57,3 @@ func main() {
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|||||||
+153
-80
@@ -4,37 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
CAN_ID_100 = 256
|
|
||||||
CAN_ID_101 = 257
|
|
||||||
CAN_ID_102 = 258
|
|
||||||
|
|
||||||
DISABLED VehicleChargingEnabled = iota
|
|
||||||
ENABLED
|
|
||||||
|
|
||||||
PARKING ShiftLeverPosition = iota
|
|
||||||
OTHER
|
|
||||||
|
|
||||||
NORMAL SystemFault = iota
|
|
||||||
FAULT
|
|
||||||
|
|
||||||
CONTACTOR_CLOSED ContactorVehicleStatus = iota
|
|
||||||
CONTACTOR_OPEN
|
|
||||||
|
|
||||||
NO_REQUEST StopRequest = iota
|
|
||||||
STOP_REQUEST
|
|
||||||
)
|
|
||||||
|
|
||||||
type VehicleChargingEnabled uint8
|
|
||||||
|
|
||||||
type ShiftLeverPosition uint8
|
|
||||||
|
|
||||||
type SystemFault uint8
|
|
||||||
|
|
||||||
type ContactorVehicleStatus uint8
|
|
||||||
|
|
||||||
type StopRequest uint8
|
|
||||||
|
|
||||||
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{}, *string)
|
||||||
@@ -62,8 +31,8 @@ type MaxChargingTimeM frame
|
|||||||
// EstChargingTimeM Estimated remaining time before the end of charging calculated by EV
|
// EstChargingTimeM Estimated remaining time before the end of charging calculated by EV
|
||||||
type EstChargingTimeM frame
|
type EstChargingTimeM frame
|
||||||
|
|
||||||
// ControlProtocolNumber Software version of control protocol to which EV corresponds
|
// EVControlProtocolNumber Software version of control protocol to which EV corresponds
|
||||||
type ControlProtocolNumber frame
|
type EVControlProtocolNumber frame
|
||||||
|
|
||||||
// TargetBatteryVoltage Target battery voltage ed charging voltage at the vehicle inlet terminals
|
// TargetBatteryVoltage Target battery voltage ed charging voltage at the vehicle inlet terminals
|
||||||
type TargetBatteryVoltage frame
|
type TargetBatteryVoltage frame
|
||||||
@@ -104,6 +73,53 @@ type HighBattTemperature frame
|
|||||||
// BattVoltageDeviationErr Status flag indicating whether or not the vehicle battery voltage deviates from the output voltage measured by the station
|
// BattVoltageDeviationErr Status flag indicating whether or not the vehicle battery voltage deviates from the output voltage measured by the station
|
||||||
type BattVoltageDeviationErr frame
|
type BattVoltageDeviationErr frame
|
||||||
|
|
||||||
|
// EVSE entity from here
|
||||||
|
|
||||||
|
// EVcontWeldingDetectSupport Identifier indicating whether or not the station deals with EV contactor welding detection
|
||||||
|
type EVcontWeldingDetectSupport frame
|
||||||
|
|
||||||
|
// AvailableOutputVoltage Maximum output voltage value at the vehicle connector terminals
|
||||||
|
type AvailableOutputVoltage frame
|
||||||
|
|
||||||
|
// AvailableOutputCurrent Maximum output current value of the station
|
||||||
|
type AvailableOutputCurrent frame
|
||||||
|
|
||||||
|
// ThresholdVoltage Threshold voltage to stop the charging process in order to protect vehicle battery
|
||||||
|
type ThresholdVoltage frame
|
||||||
|
|
||||||
|
// EVSEControlProtocolNumber Software version number of control protocol or charging sequences that the station deals with
|
||||||
|
type EVSEControlProtocolNumber frame
|
||||||
|
|
||||||
|
// OutputVoltage Supply voltage value of the output circuit in the station
|
||||||
|
type OutputVoltage frame
|
||||||
|
|
||||||
|
// OutputCurrent Supply current value of the output circuit in the station
|
||||||
|
type OutputCurrent frame
|
||||||
|
|
||||||
|
// RemainingChargingTimeS Remaining time before the end of charging (counted by 10 s)
|
||||||
|
type RemainingChargingTimeS frame
|
||||||
|
|
||||||
|
// RemainingChargingTimeM Remaining time before the end of charging (counted by min)
|
||||||
|
type RemainingChargingTimeM frame
|
||||||
|
|
||||||
|
// StationStatus Status flag indicating the energy transfer from the station
|
||||||
|
type StationStatus frame
|
||||||
|
|
||||||
|
// StationMalfunction Status flag indicating whether or not there is a malfunction caused by the station
|
||||||
|
type StationMalfunction frame
|
||||||
|
|
||||||
|
// VehicleConnectorLock Status flag indicating Vehicle connector lock the electromagnetic lock status of vehicle connector
|
||||||
|
type VehicleConnectorLock frame
|
||||||
|
|
||||||
|
// BatteryIncompatibility Status flag indicating the compatibility of vehicle battery with the output voltage of station
|
||||||
|
type BatteryIncompatibility frame
|
||||||
|
|
||||||
|
// ChargingSystemMalfunction Status flag indicating whether or not there is a problem with EV, such as improper connection
|
||||||
|
type ChargingSystemMalfunction frame
|
||||||
|
|
||||||
|
// ChargerStopControl Status flag indicating whether or not the station proceeds with shutdown process
|
||||||
|
type ChargerStopControl frame
|
||||||
|
|
||||||
func FromCanFrames(frames <-chan *CanFrame) <-chan ChademoEvent {
|
func FromCanFrames(frames <-chan *CanFrame) <-chan ChademoEvent {
|
||||||
events := make(chan ChademoEvent)
|
events := make(chan ChademoEvent)
|
||||||
|
|
||||||
@@ -121,7 +137,7 @@ func FromCanFrames(frames <-chan *CanFrame) <-chan ChademoEvent {
|
|||||||
events <- &MaxChargingTimeM{frame}
|
events <- &MaxChargingTimeM{frame}
|
||||||
events <- &EstChargingTimeM{frame}
|
events <- &EstChargingTimeM{frame}
|
||||||
case CAN_ID_102:
|
case CAN_ID_102:
|
||||||
events <- &ControlProtocolNumber{frame}
|
events <- &EVControlProtocolNumber{frame}
|
||||||
events <- &TargetBatteryVoltage{frame}
|
events <- &TargetBatteryVoltage{frame}
|
||||||
events <- &ChargingCurrentReq{frame}
|
events <- &ChargingCurrentReq{frame}
|
||||||
events <- &ChargingRate{frame}
|
events <- &ChargingRate{frame}
|
||||||
@@ -135,6 +151,23 @@ func FromCanFrames(frames <-chan *CanFrame) <-chan ChademoEvent {
|
|||||||
events <- &BattCurrentDeviationErr{frame}
|
events <- &BattCurrentDeviationErr{frame}
|
||||||
events <- &HighBattTemperature{frame}
|
events <- &HighBattTemperature{frame}
|
||||||
events <- &BattVoltageDeviationErr{frame}
|
events <- &BattVoltageDeviationErr{frame}
|
||||||
|
case CAN_ID_108:
|
||||||
|
events <- &EVcontWeldingDetectSupport{frame}
|
||||||
|
events <- &AvailableOutputVoltage{frame}
|
||||||
|
events <- &AvailableOutputCurrent{frame}
|
||||||
|
events <- &ThresholdVoltage{frame}
|
||||||
|
case CAN_ID_109:
|
||||||
|
events <- &EVSEControlProtocolNumber{frame}
|
||||||
|
events <- &OutputVoltage{frame}
|
||||||
|
events <- &OutputCurrent{frame}
|
||||||
|
events <- &RemainingChargingTimeS{frame}
|
||||||
|
events <- &RemainingChargingTimeM{frame}
|
||||||
|
events <- &StationStatus{frame}
|
||||||
|
events <- &StationMalfunction{frame}
|
||||||
|
events <- &VehicleConnectorLock{frame}
|
||||||
|
events <- &BatteryIncompatibility{frame}
|
||||||
|
events <- &ChargingSystemMalfunction{frame}
|
||||||
|
events <- &ChargerStopControl{frame}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -198,6 +231,41 @@ func bytesToUint16(bytes []uint8) uint16 {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func evWeldingDetectionSupport(bytes *[]uint8) SuppVehicleWeldingDetection {
|
||||||
|
if (*bytes)[0] == 0 {
|
||||||
|
return VEHICLE_WELDING_DETECTION_NOT_SUPPORTED
|
||||||
|
}
|
||||||
|
return VEHICLE_WELDING_DETECTION_SUPPORTED
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStationState(bytes *[]uint8) StationState {
|
||||||
|
if isBitSet((*bytes)[5], 0) {
|
||||||
|
return CHARGING
|
||||||
|
}
|
||||||
|
return STANDBY
|
||||||
|
}
|
||||||
|
|
||||||
|
func getConnectorLock(bytes *[]byte) ConnectorLock {
|
||||||
|
if isBitSet((*bytes)[5], 2) {
|
||||||
|
return CONNECTOR_LOCKED
|
||||||
|
}
|
||||||
|
return CONNECTOR_UNLOCKED
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBatteryCompatibility(bytes *[]uint8) BatteryCompatible {
|
||||||
|
if isBitSet((*bytes)[5], 3) {
|
||||||
|
return BATTERY_INCOMPATIBLE
|
||||||
|
}
|
||||||
|
return BATTERY_COMPATIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
func getChargerStopControl(bytes *[]uint8) StopControl {
|
||||||
|
if isBitSet((*bytes)[5], 5) {
|
||||||
|
return SHUTDOWN_STOP
|
||||||
|
}
|
||||||
|
return OPERATING
|
||||||
|
}
|
||||||
|
|
||||||
func (m MaximumBatteryVoltage) GetValue() (interface{}, *string) {
|
func (m MaximumBatteryVoltage) GetValue() (interface{}, *string) {
|
||||||
return bytesToUint16(m.payload[4:6]), &m.date
|
return bytesToUint16(m.payload[4:6]), &m.date
|
||||||
}
|
}
|
||||||
@@ -222,7 +290,7 @@ func (e EstChargingTimeM) GetValue() (interface{}, *string) {
|
|||||||
return e.payload[3], &e.date
|
return e.payload[3], &e.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ControlProtocolNumber) GetValue() (interface{}, *string) {
|
func (c EVControlProtocolNumber) GetValue() (interface{}, *string) {
|
||||||
return c.payload[0], &c.date
|
return c.payload[0], &c.date
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,57 +346,62 @@ func (b BattVoltageDeviationErr) GetValue() (interface{}, *string) {
|
|||||||
return getFault(&b.payload, 4, 4), &b.date
|
return getFault(&b.payload, 4, 4), &b.date
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v VehicleChargingEnabled) String() string {
|
func (e EVcontWeldingDetectSupport) GetValue() (interface{}, *string) {
|
||||||
switch v {
|
return evWeldingDetectionSupport(&e.payload), &e.date
|
||||||
case DISABLED:
|
|
||||||
return "disabled"
|
|
||||||
case ENABLED:
|
|
||||||
return "enabled"
|
|
||||||
default:
|
|
||||||
panic("VehicleChargingEnabled not implemented")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s ShiftLeverPosition) String() string {
|
func (a AvailableOutputVoltage) GetValue() (interface{}, *string) {
|
||||||
switch s {
|
return bytesToUint16(a.payload[1:3]), &a.date
|
||||||
case PARKING:
|
|
||||||
return "parking"
|
|
||||||
case OTHER:
|
|
||||||
return "other"
|
|
||||||
default:
|
|
||||||
panic("ShiftLeverPosition not implemented")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SystemFault) String() string {
|
func (a AvailableOutputCurrent) GetValue() (interface{}, *string) {
|
||||||
switch s {
|
return a.payload[3], &a.date
|
||||||
case NORMAL:
|
|
||||||
return "normal"
|
|
||||||
case FAULT:
|
|
||||||
return "fault"
|
|
||||||
default:
|
|
||||||
panic("SystemFault not implemented")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ContactorVehicleStatus) String() string {
|
func (t ThresholdVoltage) GetValue() (interface{}, *string) {
|
||||||
switch c {
|
return bytesToUint16(t.payload[4:6]), &t.date
|
||||||
case CONTACTOR_CLOSED:
|
|
||||||
return "contactor closed"
|
|
||||||
case CONTACTOR_OPEN:
|
|
||||||
return "contactor open"
|
|
||||||
default:
|
|
||||||
panic("ContactorVehicleStatus not implemented")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StopRequest) String() string {
|
func (e EVSEControlProtocolNumber) GetValue() (interface{}, *string) {
|
||||||
switch s {
|
return e.payload[0], &e.date
|
||||||
case NO_REQUEST:
|
}
|
||||||
return "no request"
|
|
||||||
case STOP_REQUEST:
|
func (o OutputVoltage) GetValue() (interface{}, *string) {
|
||||||
return "stop request"
|
return bytesToUint16(o.payload[1:3]), &o.date
|
||||||
default:
|
}
|
||||||
panic("StopRequest not implemented")
|
|
||||||
}
|
func (o OutputCurrent) GetValue() (interface{}, *string) {
|
||||||
|
return o.payload[3], &o.date
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RemainingChargingTimeS) GetValue() (interface{}, *string) {
|
||||||
|
return r.payload[6] * 10, &r.date
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RemainingChargingTimeM) GetValue() (interface{}, *string) {
|
||||||
|
return r.payload[7], &r.date
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s StationStatus) GetValue() (interface{}, *string) {
|
||||||
|
return getStationState(&s.payload), &s.date
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s StationMalfunction) GetValue() (interface{}, *string) {
|
||||||
|
return getFault(&s.payload, 5, 1), &s.date
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v VehicleConnectorLock) GetValue() (interface{}, *string) {
|
||||||
|
return getConnectorLock(&v.payload), &v.date
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BatteryIncompatibility) GetValue() (interface{}, *string) {
|
||||||
|
return getBatteryCompatibility(&b.payload), &b.date
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c ChargingSystemMalfunction) GetValue() (interface{}, *string) {
|
||||||
|
return getFault(&c.payload, 5, 4), &c.date
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c ChargerStopControl) GetValue() (interface{}, *string) {
|
||||||
|
return getChargerStopControl(&c.payload), &c.date
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// (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 length = 11
|
||||||
|
|
||||||
|
var pattern = regexp.MustCompile(expr)
|
||||||
|
|
||||||
|
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 {
|
||||||
|
submatch := pattern.FindStringSubmatch(*text)
|
||||||
|
if len(submatch) == length {
|
||||||
|
canid, err := strconv.ParseUint(submatch[2], 16, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := make([]uint8, 8)
|
||||||
|
for idx, octet := range submatch[3:] {
|
||||||
|
val, err := strconv.ParseUint(octet, 16, 0)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
payload[idx] = uint8(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &CanFrame{
|
||||||
|
date: submatch[1],
|
||||||
|
canid: uint32(canid),
|
||||||
|
payload: payload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ func TestFromString(t *testing.T) {
|
|||||||
name: "Candump parsing test",
|
name: "Candump parsing test",
|
||||||
args: args{text: &dump},
|
args: args{text: &dump},
|
||||||
want: &CanFrame{
|
want: &CanFrame{
|
||||||
canid: 100,
|
canid: CAN_ID_100,
|
||||||
date: "2022-07-08 16:54:15.587099",
|
date: "2022-07-08 16:54:15.587099",
|
||||||
payload: []uint8{0, 0, 0, 0, 0, 0, 0x64, 0},
|
payload: []uint8{0, 0, 0, 0, 0, 0, 0x64, 0},
|
||||||
},
|
},
|
||||||
@@ -30,8 +30,8 @@ func TestFromString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
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) {
|
if got := fromString(tt.args.text); !reflect.DeepEqual(got, tt.want) {
|
||||||
t.Errorf("FromString() = %v, want %v", got, tt.want)
|
t.Errorf("fromString() = %v, want %v", got, tt.want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
const (
|
||||||
|
CAN_ID_100 = 0x100
|
||||||
|
CAN_ID_101 = 0x101
|
||||||
|
CAN_ID_102 = 0x102
|
||||||
|
CAN_ID_108 = 0x108
|
||||||
|
CAN_ID_109 = 0x109
|
||||||
|
|
||||||
|
DISABLED VehicleChargingEnabled = iota
|
||||||
|
ENABLED
|
||||||
|
|
||||||
|
PARKING ShiftLeverPosition = iota
|
||||||
|
OTHER
|
||||||
|
|
||||||
|
NORMAL SystemFault = iota
|
||||||
|
FAULT
|
||||||
|
|
||||||
|
CONTACTOR_CLOSED ContactorVehicleStatus = iota
|
||||||
|
CONTACTOR_OPEN
|
||||||
|
|
||||||
|
NO_REQUEST StopRequest = iota
|
||||||
|
STOP_REQUEST
|
||||||
|
|
||||||
|
VEHICLE_WELDING_DETECTION_SUPPORTED SuppVehicleWeldingDetection = iota
|
||||||
|
VEHICLE_WELDING_DETECTION_NOT_SUPPORTED
|
||||||
|
|
||||||
|
STANDBY StationState = iota
|
||||||
|
CHARGING
|
||||||
|
|
||||||
|
CONNECTOR_LOCKED ConnectorLock = iota
|
||||||
|
CONNECTOR_UNLOCKED
|
||||||
|
|
||||||
|
BATTERY_COMPATIBLE BatteryCompatible = iota
|
||||||
|
BATTERY_INCOMPATIBLE
|
||||||
|
|
||||||
|
OPERATING StopControl = iota
|
||||||
|
SHUTDOWN_STOP
|
||||||
|
)
|
||||||
|
|
||||||
|
type VehicleChargingEnabled uint8
|
||||||
|
|
||||||
|
type ShiftLeverPosition uint8
|
||||||
|
|
||||||
|
type SystemFault uint8
|
||||||
|
|
||||||
|
type ContactorVehicleStatus uint8
|
||||||
|
|
||||||
|
type StopRequest uint8
|
||||||
|
|
||||||
|
type SuppVehicleWeldingDetection uint8
|
||||||
|
|
||||||
|
type StationState uint8
|
||||||
|
|
||||||
|
type ConnectorLock uint8
|
||||||
|
|
||||||
|
type BatteryCompatible uint8
|
||||||
|
|
||||||
|
type StopControl uint8
|
||||||
|
|
||||||
|
type CanFrame struct {
|
||||||
|
canid uint32
|
||||||
|
payload []uint8
|
||||||
|
date string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v VehicleChargingEnabled) String() string {
|
||||||
|
switch v {
|
||||||
|
case DISABLED:
|
||||||
|
return "disabled"
|
||||||
|
case ENABLED:
|
||||||
|
return "enabled"
|
||||||
|
default:
|
||||||
|
panic("VehicleChargingEnabled not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s ShiftLeverPosition) String() string {
|
||||||
|
switch s {
|
||||||
|
case PARKING:
|
||||||
|
return "parking"
|
||||||
|
case OTHER:
|
||||||
|
return "other"
|
||||||
|
default:
|
||||||
|
panic("ShiftLeverPosition not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SystemFault) String() string {
|
||||||
|
switch s {
|
||||||
|
case NORMAL:
|
||||||
|
return "normal"
|
||||||
|
case FAULT:
|
||||||
|
return "fault"
|
||||||
|
default:
|
||||||
|
panic("SystemFault not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c ContactorVehicleStatus) String() string {
|
||||||
|
switch c {
|
||||||
|
case CONTACTOR_CLOSED:
|
||||||
|
return "contactor closed"
|
||||||
|
case CONTACTOR_OPEN:
|
||||||
|
return "contactor open"
|
||||||
|
default:
|
||||||
|
panic("ContactorVehicleStatus not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s StopRequest) String() string {
|
||||||
|
switch s {
|
||||||
|
case NO_REQUEST:
|
||||||
|
return "no request"
|
||||||
|
case STOP_REQUEST:
|
||||||
|
return "stop request"
|
||||||
|
default:
|
||||||
|
panic("StopRequest not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SuppVehicleWeldingDetection) String() string {
|
||||||
|
switch s {
|
||||||
|
case VEHICLE_WELDING_DETECTION_NOT_SUPPORTED:
|
||||||
|
return "not supported"
|
||||||
|
case VEHICLE_WELDING_DETECTION_SUPPORTED:
|
||||||
|
return "supported"
|
||||||
|
default:
|
||||||
|
panic("SuppVehicleWeldingDetection not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s StationState) String() string {
|
||||||
|
switch s {
|
||||||
|
case CHARGING:
|
||||||
|
return "charging"
|
||||||
|
case STANDBY:
|
||||||
|
return "standby"
|
||||||
|
default:
|
||||||
|
panic("StationState not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c ConnectorLock) String() string {
|
||||||
|
switch c {
|
||||||
|
case CONNECTOR_LOCKED:
|
||||||
|
return "locked"
|
||||||
|
case CONNECTOR_UNLOCKED:
|
||||||
|
return "unlocked"
|
||||||
|
default:
|
||||||
|
panic("ConnectorLock not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BatteryCompatible) String() string {
|
||||||
|
switch b {
|
||||||
|
case BATTERY_COMPATIBLE:
|
||||||
|
return "compatible"
|
||||||
|
case BATTERY_INCOMPATIBLE:
|
||||||
|
return "incompatible"
|
||||||
|
default:
|
||||||
|
panic("BatteryCompatible not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s StopControl) String() string {
|
||||||
|
switch s {
|
||||||
|
case OPERATING:
|
||||||
|
return "operating"
|
||||||
|
case SHUTDOWN_STOP:
|
||||||
|
return "shutdown or stop charging"
|
||||||
|
default:
|
||||||
|
panic("StopControl not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user