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.
345 lines
9.4 KiB
345 lines
9.4 KiB
package yabl
|
|
|
|
import (
|
|
"cli-mon/can"
|
|
"encoding/binary"
|
|
"time"
|
|
)
|
|
|
|
type Packet interface {
|
|
GetUnitId() uint
|
|
}
|
|
|
|
type SignedAirTemp8BitType int
|
|
type ConnectedOut8bitType uint
|
|
type ForceModeType uint
|
|
type SignedVoltage12bitType int
|
|
type DebugSwitchModeType uint
|
|
type OtherError4BitType uint
|
|
type ContactorModeType uint
|
|
type Power14BitType uint
|
|
type AuthStateType uint
|
|
type AuthModeType uint
|
|
type BoardReadyType uint
|
|
type BooleanType uint
|
|
type ErrorType uint
|
|
type ContactorInternalOtherErrorType uint
|
|
type ContactorGroupChangedType uint
|
|
type V2GModeType uint
|
|
type Voltage11BitType uint
|
|
type Current10BitType uint
|
|
type CpLineLevelType uint
|
|
type IsolationStateType uint
|
|
type Voltage9BitType float32
|
|
|
|
type PName string
|
|
type FName string
|
|
|
|
type parameters struct {
|
|
fields []field
|
|
interval uint
|
|
name PName
|
|
}
|
|
|
|
type field struct {
|
|
length uint8
|
|
setter func(uint64 uint64)
|
|
value uint64
|
|
last time.Time
|
|
name FName
|
|
}
|
|
|
|
type key struct {
|
|
canId, unitId uint
|
|
}
|
|
|
|
var protocolMap map[key]parameters
|
|
var cpuPresentEnergyArray [CONNECTOR_MAX]*CpuPresentEnergy
|
|
var cpuPeripheryInstance *CpuPeriphery
|
|
var cpuEnergySettingsArray [CONNECTOR_MAX]*CpuEnergySettings
|
|
var cpuErrorsInstance *CpuErrors
|
|
var cpuDebugInstance *CpuDebug
|
|
var puPresentEnergyArray [CONNECTOR_MAX]*PuPresentEnergy
|
|
var puPeripheryArray [CONNECTOR_MAX]*PuPeriphery
|
|
var puErrorsArray [CONNECTOR_MAX]*PuErrors
|
|
var puDebugArray [CONNECTOR_MAX]*PuDebug
|
|
var seccTargetEnergyArray [CONNECTOR_MAX]*SeccTargetEnergy
|
|
var seccErrorsArray [CONNECTOR_MAX]*SeccErrors
|
|
var logicAuthArray [CONNECTOR_MAX]*LogicAuth
|
|
var logicEnergyMode [CONNECTOR_MAX]*LogicEnergyMode
|
|
var logicErrorsInstance *LogicErrors
|
|
var logicWorkingMode *LogicWorkingMode
|
|
var contactorInternalStateArray [CONNECTOR_MAX]*ContactorInternalState
|
|
var contactorInternalErrorsInstance *ContactorInternalErrors
|
|
var contactorsInternalForce *ContactorsInternalForce
|
|
var contactorInternalDebugArray [CONNECTOR_MAX]*ContactorInternalDebug
|
|
var peripheryStateArray [CONNECTOR_MAX]*PeripheryState
|
|
var peripheryInfoArray [CONNECTOR_MAX]*PeripheryInfo
|
|
var peripheryDebugArray [CONNECTOR_MAX]*PeripheryDebug
|
|
var converterPresentEnergyArray [CONVERTERS_MAX]*ConverterPresentEnergy
|
|
var converterErrorsArray [CONVERTERS_MAX]*ConverterErrors
|
|
var converterDebugArray [CONVERTERS_MAX]*ConverterDebug
|
|
|
|
func StartProtocolParsing(frames <-chan *can.CanFrame) <-chan Packet {
|
|
result := make(chan Packet)
|
|
|
|
go func() {
|
|
defer close(result)
|
|
var contactorsFirstState [CONTACTOR_MAX]bool
|
|
var contactorsFirstErr [CONTACTOR_MAX]bool
|
|
var puFirst [CONNECTOR_MAX]bool
|
|
var puPeripheryFirst [CONNECTOR_MAX]bool
|
|
|
|
for frame := range frames {
|
|
if frames == nil {
|
|
continue
|
|
}
|
|
|
|
var unitId = uint((frame.CanId & UNIT_ID_MASK) >> UNIT_ID_OFFSET)
|
|
|
|
switch {
|
|
case frame.CanId&ACTION_ID_MASK == can.CAN_ID_071:
|
|
changed := false
|
|
var model = ContactorInternalState{UnitId: unitId}
|
|
if val, ok := get(0, 3, frame.Payload); ok && model.ContactorReady != BoardReadyType(val) {
|
|
model.ContactorReady = BoardReadyType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(3, 2, frame.Payload); ok && model.ContactorOn != BooleanType(val) {
|
|
model.ContactorOn = BooleanType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(5, 2, frame.Payload); ok && model.UnexpectedState != ErrorType(val) {
|
|
model.UnexpectedState = ErrorType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(7, 2, frame.Payload); ok && model.Isolated != ErrorType(val) {
|
|
model.Isolated = ErrorType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(9, 2, frame.Payload); ok && model.DebugEnabled != BooleanType(val) {
|
|
model.DebugEnabled = BooleanType(val)
|
|
changed = true
|
|
}
|
|
if changed || !contactorsFirstState[unitId] {
|
|
contactorsFirstState[unitId] = true
|
|
result <- &model
|
|
}
|
|
case frame.CanId&ACTION_ID_MASK == can.CAN_ID_073:
|
|
changed := false
|
|
model := ContactorInternalErrors{UnitId: unitId}
|
|
if val, ok := get(0, 3, frame.Payload); ok && model.BoardReady != BoardReadyType(val) {
|
|
model.BoardReady = BoardReadyType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(3, 4, frame.Payload); ok && model.OtherError != ContactorInternalOtherErrorType(val) {
|
|
model.OtherError = ContactorInternalOtherErrorType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(7, 3, frame.Payload); ok && model.ContactorGroupChanged != ContactorGroupChangedType(val) {
|
|
model.ContactorGroupChanged = ContactorGroupChangedType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(10, 4, frame.Payload); ok && model.UnexpectedFormation != ContactorInternalOtherErrorType(val) {
|
|
model.UnexpectedFormation = ContactorInternalOtherErrorType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(14, 2, frame.Payload); ok && model.CpuNotReady != ErrorType(val) {
|
|
model.CpuNotReady = ErrorType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(16, 2, frame.Payload); ok && model.PuNotReady != ErrorType(val) {
|
|
model.PuNotReady = ErrorType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(18, 2, frame.Payload); ok && model.Debug != BooleanType(val) {
|
|
model.Debug = BooleanType(val)
|
|
changed = true
|
|
}
|
|
if changed || !contactorsFirstErr[unitId] {
|
|
contactorsFirstErr[unitId] = true
|
|
result <- &model
|
|
}
|
|
case frame.CanId&ACTION_ID_MASK == can.CAN_ID_021:
|
|
changed := false
|
|
model := PuPresentEnergy{UnitId: unitId}
|
|
if val, ok := get(0, 2, frame.Payload); ok && model.V2GMode != V2GModeType(val) {
|
|
model.V2GMode = V2GModeType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(2, 11, frame.Payload); ok && model.VoltageBefore != Voltage11BitType(val) {
|
|
model.VoltageBefore = Voltage11BitType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(13, 11, frame.Payload); ok && model.VoltageAfter != Voltage11BitType(val) {
|
|
model.VoltageAfter = Voltage11BitType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(24, 10, frame.Payload); ok && model.PresentCurrent != Current10BitType(val) {
|
|
model.PresentCurrent = Current10BitType(val)
|
|
changed = true
|
|
}
|
|
if changed || !puFirst[unitId] {
|
|
puFirst[unitId] = true
|
|
result <- &model
|
|
}
|
|
case frame.CanId&ACTION_ID_MASK == can.CAN_ID_022:
|
|
changed := false
|
|
model := PuPeriphery{UnitId: unitId}
|
|
if val, ok := get(0, 2, frame.Payload); ok && model.ConnectorInsert != BooleanType(val) {
|
|
model.ConnectorInsert = BooleanType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(2, 2, frame.Payload); ok && model.ContactorOn != BooleanType(val) {
|
|
model.ContactorOn = BooleanType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(4, 2, frame.Payload); ok && model.ConnectorLocked != BooleanType(val) {
|
|
model.ConnectorLocked = BooleanType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(6, 3, frame.Payload); ok && model.CpLineLevel != CpLineLevelType(val) {
|
|
model.CpLineLevel = CpLineLevelType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(9, 3, frame.Payload); ok && model.IsolationState != IsolationStateType(val) {
|
|
model.IsolationState = IsolationStateType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(12, 2, frame.Payload); ok && model.ChargingAllowed != BooleanType(val) {
|
|
model.ChargingAllowed = BooleanType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(14, 2, frame.Payload); ok && model.PwmEnabled != BooleanType(val) {
|
|
model.PwmEnabled = BooleanType(val)
|
|
changed = true
|
|
}
|
|
if val, ok := get(16, 9, frame.Payload); ok && model.CpLineVoltage != (Voltage9BitType(val)*0.1-15) {
|
|
model.CpLineVoltage = Voltage9BitType(val)*0.1 - 15
|
|
changed = true
|
|
}
|
|
if changed || !puPeripheryFirst[unitId] {
|
|
puPeripheryFirst[unitId] = true
|
|
result <- &model
|
|
}
|
|
|
|
}
|
|
}
|
|
}()
|
|
|
|
return result
|
|
}
|
|
|
|
func get(from uint, size uint, buffer []byte) (uint64, bool) {
|
|
value := binary.LittleEndian.Uint64(buffer)
|
|
|
|
var mask uint64 = ^(ALL_BITS << size)
|
|
mask = mask << from
|
|
selected := mask & value
|
|
|
|
if selected == mask {
|
|
return 0, false
|
|
} else {
|
|
return selected >> from, true
|
|
}
|
|
}
|
|
|
|
func (t *ContactorInternalState) GetUnitId() uint {
|
|
return t.UnitId
|
|
}
|
|
|
|
func (t *ContactorInternalErrors) GetUnitId() uint {
|
|
return t.UnitId
|
|
}
|
|
|
|
func (t *PuPresentEnergy) GetUnitId() uint {
|
|
return t.UnitId
|
|
}
|
|
|
|
func (t *PuPeriphery) GetUnitId() uint {
|
|
return t.UnitId
|
|
}
|
|
|
|
func (a *LogicAuth) GetUnitId() uint {
|
|
return a.UnitId
|
|
}
|
|
|
|
func (l *LogicEnergyMode) GetUnitId() uint {
|
|
return l.UnitId
|
|
}
|
|
|
|
func (l *LogicErrors) GetUnitId() uint {
|
|
return l.UnitId
|
|
}
|
|
|
|
func (l *LogicWorkingMode) GetUnitId() uint {
|
|
return l.UnitId
|
|
}
|
|
|
|
func (c *CpuPresentEnergy) GetUnitId() uint {
|
|
return c.UnitId
|
|
}
|
|
|
|
func (c *CpuPeriphery) GetUnitId() uint {
|
|
return c.UnitId
|
|
}
|
|
|
|
func (c *CpuEnergySettings) GetUnitId() uint {
|
|
return c.UnitId
|
|
}
|
|
|
|
func (c *CpuErrors) GetUnitId() uint {
|
|
return c.UnitId
|
|
}
|
|
|
|
func (d *CpuDebug) GetUnitId() uint {
|
|
return d.UnitId
|
|
}
|
|
|
|
func (p *PuErrors) GetUnitId() uint {
|
|
return p.UnitId
|
|
}
|
|
|
|
func (d *PuDebug) GetUnitId() uint {
|
|
return d.UnitId
|
|
}
|
|
|
|
func (s *SeccTargetEnergy) GetUnitId() uint {
|
|
return s.UnitId
|
|
}
|
|
|
|
func (e *SeccErrors) GetUnitId() uint {
|
|
return e.UnitId
|
|
}
|
|
|
|
func (c *ContactorsInternalForce) GetUnitId() uint {
|
|
return c.UnitId
|
|
}
|
|
|
|
func (c *ContactorInternalDebug) GetUnitId() uint {
|
|
return c.UnitId
|
|
}
|
|
|
|
func (p *PeripheryState) GetUnitId() uint {
|
|
return p.UnitId
|
|
}
|
|
|
|
func (p *PeripheryInfo) GetUnitId() uint {
|
|
return p.UnitId
|
|
}
|
|
|
|
func (p *PeripheryDebug) GetUnitId() uint {
|
|
return p.UnitId
|
|
}
|
|
|
|
func (c *ConverterPresentEnergy) GetUnitId() uint {
|
|
return c.UnitId
|
|
}
|
|
|
|
func (c *ConverterErrors) GetUnitId() uint {
|
|
return c.UnitId
|
|
}
|
|
|
|
func (c *ConverterDebug) GetUnitId() uint {
|
|
return c.UnitId
|
|
}
|
|
|