Refactoring and optimization

pull/1/head
Terekhin Alexandr 3 years ago
parent 3c46e309e0
commit f00c743160
Signed by: didinst
GPG Key ID: D2EF94423C23BF12
  1. 28
      cli-mon.go
  2. 113
      ui/ui.go
  3. 238
      yabl/init.go
  4. 271
      yabl/protocol.go
  5. 93
      yabl/types.go

@ -3,11 +3,10 @@ package main
import (
"cli-mon/can"
"cli-mon/ui"
"cli-mon/yabl"
yabl "cli-mon/yabl"
"flag"
"fmt"
"os"
"reflect"
)
func main() {
@ -40,20 +39,25 @@ func main() {
os.Exit(0)
}
var messages = yabl.StartProtocolParsing(frames)
converter := yabl.NewProtocolConverter()
var display ui.UI
if *gui {
ui.InitCliApp(messages)
display = ui.NewUI()
} else {
for msg := range messages {
// val := getField(msg.Object, msg.Field)
fmt.Printf("%v %v.%v [%d] %v\n", msg.Updated.Format("Jan _2 15:04:05.000"), msg.ActionName, msg.Field, msg.UnitId, msg.Value)
display = ui.NewLog()
}
display.Start()
for frame := range frames {
if events, ok := converter.EventsFromFrame(frame); ok {
for _, event := range events {
display.Consume(event)
}
}
}
}
func getField(v yabl.Action, field yabl.FName) interface{} {
r := reflect.ValueOf(v)
f := reflect.Indirect(r).FieldByName(string(field))
return f.Interface()
display.Stop()
}

@ -2,9 +2,10 @@ package ui
import (
"cli-mon/yabl"
"fmt"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"os"
"reflect"
)
const (
@ -17,70 +18,122 @@ type page struct {
primitive tview.Primitive
}
func InitCliApp(events <-chan *yabl.Event) {
var app = tview.NewApplication()
pages := tview.NewPages()
type UI interface {
Consume(event *yabl.Event)
Start()
Stop()
}
type gui struct {
app *tview.Application
pages *tview.Pages
connPage *cTable
page2 tview.Primitive
}
type log struct {
}
func (g *gui) Consume(event *yabl.Event) {
switch obj := event.Object.(type) {
case *yabl.PuPresentEnergy:
g.connPage.updatePU(event.GetUnitId(), event.Field, event.Value)
case *yabl.PuPeriphery:
g.connPage.updatePU(event.GetUnitId(), event.Field, event.Value)
case *yabl.PuDebug:
g.connPage.updatePU(event.GetUnitId(), event.Field, event.Value)
case *yabl.PuErrors:
g.connPage.updatePuErrors(obj)
}
g.app.Draw()
}
func NewUI() UI {
g := &gui{}
g.app = tview.NewApplication()
g.pages = tview.NewPages()
var active page
var layout map[string]page
connectors := newConnectorsGrid()
page2 := tview.NewBox().SetBorder(true).SetTitle("Bbbbbb")
g.connPage = newConnectorsGrid()
g.page2 = tview.NewBox().SetBorder(true).SetTitle("Bbbbbb")
layout = map[string]page{
connectors_page: {
left: "Page2",
right: "Page2",
primitive: connectors,
primitive: g.connPage,
},
"Page2": {
left: connectors_page,
right: connectors_page,
primitive: page2,
primitive: g.page2,
},
}
for k, p := range layout {
pages.AddPage(k, p.primitive, true, true)
g.pages.AddPage(k, p.primitive, true, true)
}
active = layout["Page1"]
pages.SwitchToPage("Page1")
active = layout[connectors_page]
g.pages.SwitchToPage(connectors_page)
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
g.app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
switch event.Key() {
case tcell.KeyRight:
pages.SwitchToPage(active.right)
g.pages.SwitchToPage(active.right)
active = layout[active.right]
return nil
case tcell.KeyLeft:
pages.SwitchToPage(active.left)
g.pages.SwitchToPage(active.left)
active = layout[active.left]
return nil
case tcell.KeyCtrlC:
app.Stop()
g.app.Stop()
}
return event
})
return g
}
func (g *gui) Start() {
go func() {
if err := app.SetRoot(pages, true).EnableMouse(true).Run(); err != nil {
if err := g.app.SetRoot(g.pages, true).EnableMouse(true).Run(); err != nil {
panic(err)
}
os.Exit(0)
}()
}
for event := range events {
switch obj := event.Object.(type) {
case *yabl.PuPresentEnergy:
connectors.updatePU(event.UnitId, event.Field, event.Value)
case *yabl.PuPeriphery:
connectors.updatePU(event.UnitId, event.Field, event.Value)
case *yabl.PuDebug:
connectors.updatePU(event.UnitId, event.Field, event.Value)
case *yabl.PuErrors:
connectors.updatePuErrors(obj)
}
app.Draw()
}
func (g *gui) Stop() {
g.app.Stop()
}
func NewLog() UI {
return &log{}
}
func (l log) Consume(event *yabl.Event) {
fmt.Printf(
"%v %v.%v [%d] %v\n",
event.Updated.Format("Jan _2 15:04:05.000"),
event.ActionName,
event.Field,
event.GetUnitId(),
event.Value)
}
func (l log) Start() {
}
func (l log) Stop() {
}
func getField(v yabl.Action, field yabl.FName) interface{} {
r := reflect.ValueOf(v)
f := reflect.Indirect(r).FieldByName(string(field))
return f.Interface()
}

@ -2,36 +2,38 @@ package yabl
import "cli-mon/can"
func initialize() {
func (c *converter) initialize() {
c.protocolMap = make(map[key]action)
for i := uint(1); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_011, i}
cpe := &CpuPresentEnergy{UnitId: 1}
cpuPresentEnergyArray[i] = cpe
cpe := &CpuPresentEnergy{unit: 1}
c.cpuPresentEnergyArray[i] = cpe
fields := []*field{
{length: 2, setter: cpe.setPowerDirectionMode, name: FPowerDirectionMode},
{length: 10, setter: cpe.setPresentCurrent, name: FPresentCurrent},
{length: 11, setter: cpe.setPresentVoltage, name: FPresentVoltage},
}
protocolMap[key] = action{fields: fields, interval: 50, name: PCpuPresentEnergy, object: cpe}
c.protocolMap[key] = action{fields: fields, interval: 50, name: PCpuPresentEnergy, object: cpe}
}
cpuPeripheryInstance = &CpuPeriphery{UnitId: 0}
c.cpuPeripheryInstance = &CpuPeriphery{unit: 0}
fields := []*field{
{length: 2, setter: cpuPeripheryInstance.setContactorInput, name: FContactorInput},
{length: 2, setter: cpuPeripheryInstance.setCircuitBreakerInput, name: FCircuitBreakerInput},
{length: 2, setter: cpuPeripheryInstance.setCircuitBreakerPowerCBInput, name: FCircuitBreakerPowerCBInput},
{length: 2, setter: c.cpuPeripheryInstance.setContactorInput, name: FContactorInput},
{length: 2, setter: c.cpuPeripheryInstance.setCircuitBreakerInput, name: FCircuitBreakerInput},
{length: 2, setter: c.cpuPeripheryInstance.setCircuitBreakerPowerCBInput, name: FCircuitBreakerPowerCBInput},
}
protocolMap[key{can.CAN_ID_014, 0}] = action{
c.protocolMap[key{can.CAN_ID_014, 0}] = action{
fields: fields,
interval: 1000,
name: PCpuPeriphery,
object: cpuPeripheryInstance,
object: c.cpuPeripheryInstance,
}
for i := uint(0); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_015, i}
ces := &CpuEnergySettings{UnitId: i}
cpuEnergySettingsArray[i] = ces
ces := &CpuEnergySettings{unit: unit(i)}
c.cpuEnergySettingsArray[i] = ces
fields := []*field{
{length: 10, setter: ces.setCurrentMax, name: FCurrentMax},
{length: 11, setter: ces.setVoltageMax, name: FVoltageMax},
@ -39,68 +41,68 @@ func initialize() {
{length: 11, setter: ces.setTargetBatteryVoltage, name: FTargetBatteryVoltage},
{length: 11, setter: ces.setTargetGoalVoltage, name: FTargetGoalVoltage},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PCpuEnergySettings, object: ces}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PCpuEnergySettings, object: ces}
}
cpuErrorsInstance = &CpuErrors{UnitId: 0}
c.cpuErrorsInstance = &CpuErrors{unit: 0}
fields = []*field{
{length: 3, setter: cpuErrorsInstance.setBoardReady, name: FBoardReady},
{length: 4, setter: cpuErrorsInstance.setOtherError, name: FOtherError},
{length: 2, setter: cpuErrorsInstance.setRedButtonHard, name: FRedButtonHard},
{length: 2, setter: cpuErrorsInstance.setRedButtonSoft, name: FRedButtonSoft},
{length: 2, setter: cpuErrorsInstance.setModulesGone, name: FModulesGone},
{length: 2, setter: cpuErrorsInstance.setGridVoltageHighErr, name: FGridVoltageHighErr},
{length: 2, setter: cpuErrorsInstance.setGridVoltageHighWarn, name: FGridVoltageHighWarn},
{length: 2, setter: cpuErrorsInstance.setGridVoltageLowWarn, name: FGridVoltageLowWarn},
{length: 2, setter: cpuErrorsInstance.setGridVoltageLowErr, name: FGridVoltageLowErr},
{length: 11, setter: cpuErrorsInstance.setGridVoltageLow, name: FGridVoltageLow},
{length: 11, setter: cpuErrorsInstance.setGridVoltageHigh, name: FGridVoltageHigh},
{length: 2, setter: cpuErrorsInstance.setGridVoltageEmpty, name: FGridVoltageEmpty},
{length: 2, setter: cpuErrorsInstance.setNotReadySecc, name: FNotReadySecc},
{length: 2, setter: cpuErrorsInstance.setNotReadyPu, name: FNotReadyPu},
{length: 2, setter: cpuErrorsInstance.setNotReadyContactors, name: FNotReadyContactors},
{length: 2, setter: cpuErrorsInstance.setDebugConvertersEnabled, name: FDebugConvertersEnabled},
{length: 2, setter: cpuErrorsInstance.setContactorInputError, name: FContactorInputError},
{length: 2, setter: cpuErrorsInstance.setNotReadyPeriphery, name: FNotReadyPeriphery},
}
protocolMap[key{can.CAN_ID_016, 0}] = action{
{length: 3, setter: c.cpuErrorsInstance.setBoardReady, name: FBoardReady},
{length: 4, setter: c.cpuErrorsInstance.setOtherError, name: FOtherError},
{length: 2, setter: c.cpuErrorsInstance.setRedButtonHard, name: FRedButtonHard},
{length: 2, setter: c.cpuErrorsInstance.setRedButtonSoft, name: FRedButtonSoft},
{length: 2, setter: c.cpuErrorsInstance.setModulesGone, name: FModulesGone},
{length: 2, setter: c.cpuErrorsInstance.setGridVoltageHighErr, name: FGridVoltageHighErr},
{length: 2, setter: c.cpuErrorsInstance.setGridVoltageHighWarn, name: FGridVoltageHighWarn},
{length: 2, setter: c.cpuErrorsInstance.setGridVoltageLowWarn, name: FGridVoltageLowWarn},
{length: 2, setter: c.cpuErrorsInstance.setGridVoltageLowErr, name: FGridVoltageLowErr},
{length: 11, setter: c.cpuErrorsInstance.setGridVoltageLow, name: FGridVoltageLow},
{length: 11, setter: c.cpuErrorsInstance.setGridVoltageHigh, name: FGridVoltageHigh},
{length: 2, setter: c.cpuErrorsInstance.setGridVoltageEmpty, name: FGridVoltageEmpty},
{length: 2, setter: c.cpuErrorsInstance.setNotReadySecc, name: FNotReadySecc},
{length: 2, setter: c.cpuErrorsInstance.setNotReadyPu, name: FNotReadyPu},
{length: 2, setter: c.cpuErrorsInstance.setNotReadyContactors, name: FNotReadyContactors},
{length: 2, setter: c.cpuErrorsInstance.setDebugConvertersEnabled, name: FDebugConvertersEnabled},
{length: 2, setter: c.cpuErrorsInstance.setContactorInputError, name: FContactorInputError},
{length: 2, setter: c.cpuErrorsInstance.setNotReadyPeriphery, name: FNotReadyPeriphery},
}
c.protocolMap[key{can.CAN_ID_016, 0}] = action{
fields: fields,
interval: 1000,
name: PCpuErrors,
object: cpuErrorsInstance,
object: c.cpuErrorsInstance,
}
cpuDebugInstance = &CpuDebug{UnitId: 0}
c.cpuDebugInstance = &CpuDebug{unit: 0}
fields = []*field{
{length: 2, setter: cpuDebugInstance.setDebugModeOn, name: FDebugModeOn},
{length: 3, setter: cpuDebugInstance.setDebugContactorInputOn, name: FDebugContactorInputOn},
{length: 3, setter: cpuDebugInstance.setDebugCircuitBreakerOn, name: FDebugCircuitBreakerOn},
{length: 3, setter: cpuDebugInstance.setDebugRedButtonSoftware, name: FDebugRedButtonSoftware},
{length: 2, setter: c.cpuDebugInstance.setDebugModeOn, name: FDebugModeOn},
{length: 3, setter: c.cpuDebugInstance.setDebugContactorInputOn, name: FDebugContactorInputOn},
{length: 3, setter: c.cpuDebugInstance.setDebugCircuitBreakerOn, name: FDebugCircuitBreakerOn},
{length: 3, setter: c.cpuDebugInstance.setDebugRedButtonSoftware, name: FDebugRedButtonSoftware},
}
protocolMap[key{can.CAN_ID_01A, 0}] = action{
c.protocolMap[key{can.CAN_ID_01A, 0}] = action{
fields: fields,
interval: 1000,
name: PCpuDebug,
object: cpuDebugInstance,
object: c.cpuDebugInstance,
}
for i := uint(1); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_021, i}
ppe := &PuPresentEnergy{UnitId: i}
puPresentEnergyArray[i] = ppe
ppe := &PuPresentEnergy{unit: unit(i)}
c.puPresentEnergyArray[i] = ppe
fields := []*field{
{length: 2, setter: ppe.setV2GMode, name: FV2GMode},
{length: 11, setter: ppe.setVoltageBefore, name: FVoltageBefore},
{length: 11, setter: ppe.setVoltageAfter, name: FVoltageAfter},
{length: 10, setter: ppe.setPresentCurrent, name: FPresentCurrent},
}
protocolMap[key] = action{fields: fields, interval: 50, name: PPuPresentEnergy, object: ppe}
c.protocolMap[key] = action{fields: fields, interval: 50, name: PPuPresentEnergy, object: ppe}
}
for i := uint(1); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_022, i}
pp := &PuPeriphery{UnitId: i}
puPeripheryArray[i] = pp
pp := &PuPeriphery{unit: unit(i)}
c.puPeripheryArray[i] = pp
fields := []*field{
{length: 2, setter: pp.setConnectorInsert, name: FConnectorInsert},
{length: 2, setter: pp.setContactorOn, name: FContactorOn},
@ -111,13 +113,13 @@ func initialize() {
{length: 2, setter: pp.setPwmEnabled, name: FPwmEnabled},
{length: 9, setter: pp.setCpLineVoltage, name: FCpLineVoltage},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PPuPeriphery, object: pp}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PPuPeriphery, object: pp}
}
for i := uint(1); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_023, i}
pe := &PuErrors{UnitId: 1}
puErrorsArray[i] = pe
pe := &PuErrors{unit: 1}
c.puErrorsArray[i] = pe
fields := []*field{
{length: 3, setter: pe.setBoardReady, name: FBoardReady},
{length: 4, setter: pe.setOtherError, name: FOtherError},
@ -136,96 +138,96 @@ func initialize() {
{length: 2, setter: pe.setOutputCircuitBreakerEnabled, name: FOutputCircuitBreakerEnabled},
{length: 12, setter: pe.setOutputCircuitBreakerEnabledValue, name: FOutputCircuitBreakerEnabledValue},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PPuErrors, object: pe}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PPuErrors, object: pe}
}
for i := uint(0); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_02A, i}
pd := &PuDebug{UnitId: i}
puDebugArray[i] = pd
pd := &PuDebug{unit: unit(i)}
c.puDebugArray[i] = pd
fields = []*field{
{length: 2, setter: pd.setDebugModeOn, name: FDebugModeOn},
{length: 3, setter: pd.setDebugContactorOutputOn, name: FDebugContactorOutputOn},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PPuDebug, object: pd}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PPuDebug, object: pd}
}
for i := uint(1); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_041, i}
ste := &SeccTargetEnergy{UnitId: i}
seccTargetEnergyArray[i] = ste
ste := &SeccTargetEnergy{unit: unit(i)}
c.seccTargetEnergyArray[i] = ste
fields = []*field{
{length: 2, setter: ste.setTargetChargingAllow, name: FTargetChargingAllow},
{length: 11, setter: ste.setTargetBatteryVoltage, name: FTargetBatteryVoltage},
{length: 11, setter: ste.setTargetGoalVoltage, name: FTargetGoalVoltage},
{length: 10, setter: ste.setTargetCurrent, name: FTargetCurrent},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PSeccTargetEnergy, object: ste}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PSeccTargetEnergy, object: ste}
}
for i := uint(1); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_042, i}
se := &SeccErrors{UnitId: i}
seccErrorsArray[i] = se
se := &SeccErrors{unit: unit(i)}
c.seccErrorsArray[i] = se
fields = []*field{
{length: 3, setter: se.setBoardReady, name: FBoardReady},
{length: 2, setter: se.setNotReadyLogic, name: FNotReadyLogic},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PSeccErrors, object: se}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PSeccErrors, object: se}
}
for i := uint(0); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_046, i}
la := &LogicAuth{UnitId: i}
logicAuthArray[i] = la
la := &LogicAuth{unit: unit(i)}
c.logicAuthArray[i] = la
fields = []*field{
{length: 2, setter: la.setAuthMode, name: FAuthMode},
{length: 3, setter: la.setAuthState, name: FAuthState},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PLogicAuth, object: la}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PLogicAuth, object: la}
}
for i := uint(0); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_047, i}
lem := &LogicEnergyMode{UnitId: i}
logicEnergyMode[i] = lem
lem := &LogicEnergyMode{unit: unit(i)}
c.logicEnergyMode[i] = lem
fields = []*field{
{length: 2, setter: lem.setV2gMode, name: FV2gMode},
{length: 10, setter: lem.setCurrentMax, name: FCurrentMax},
{length: 11, setter: lem.setVoltageMax, name: FVoltageMax},
{length: 14, setter: lem.setPowerMax, name: FPowerMax},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PLogicEnergyMode, object: lem}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PLogicEnergyMode, object: lem}
}
logicErrorsInstance = &LogicErrors{UnitId: 0}
c.logicErrorsInstance = &LogicErrors{unit: 0}
fields = []*field{
{length: 3, setter: logicErrorsInstance.setBoardReady, name: FBoardReady},
{length: 2, setter: logicErrorsInstance.setNotReadySettings, name: FNotReadySettings},
{length: 3, setter: c.logicErrorsInstance.setBoardReady, name: FBoardReady},
{length: 2, setter: c.logicErrorsInstance.setNotReadySettings, name: FNotReadySettings},
}
protocolMap[key{can.CAN_ID_048, 0}] = action{
c.protocolMap[key{can.CAN_ID_048, 0}] = action{
fields: fields,
interval: 1000,
name: PLogicErrors,
object: logicErrorsInstance,
object: c.logicErrorsInstance,
}
logicWorkingMode = &LogicWorkingMode{UnitId: 0}
c.logicWorkingMode = &LogicWorkingMode{unit: 0}
fields = []*field{
{length: 5, setter: logicWorkingMode.setTargetContactorMode, name: FTargetContactorMode},
{length: 2, setter: logicWorkingMode.setAvailability, name: FAvailability},
{length: 5, setter: c.logicWorkingMode.setTargetContactorMode, name: FTargetContactorMode},
{length: 2, setter: c.logicWorkingMode.setAvailability, name: FAvailability},
}
protocolMap[key{can.CAN_ID_049, 0}] = action{
c.protocolMap[key{can.CAN_ID_049, 0}] = action{
fields: fields,
interval: 1000,
name: PLogicWorkingMode,
object: logicWorkingMode,
object: c.logicWorkingMode,
}
for i := uint(0); i < CONTACTOR_MAX; i++ {
key := key{can.CAN_ID_071, i}
cis := &ContactorInternalState{UnitId: i}
contactorInternalStateArray[i] = cis
cis := &ContactorInternalState{unit: unit(i)}
c.contactorInternalStateArray[i] = cis
fields = []*field{
{length: 3, setter: cis.setContactorReady, name: FContactorReady},
{length: 2, setter: cis.setContactorOn, name: FContactorOn},
@ -233,54 +235,54 @@ func initialize() {
{length: 2, setter: cis.setIsolated, name: FIsolated},
{length: 2, setter: cis.setDebugEnabled, name: FDebugEnabled},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PContactorInternalState, object: cis}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PContactorInternalState, object: cis}
}
contactorInternalErrorsInstance = &ContactorInternalErrors{UnitId: 0}
c.contactorInternalErrorsInstance = &ContactorInternalErrors{unit: 0}
fields = []*field{
{length: 3, setter: contactorInternalErrorsInstance.setBoardReady, name: FBoardReady},
{length: 4, setter: contactorInternalErrorsInstance.setOtherError, name: FOtherError},
{length: 3, setter: contactorInternalErrorsInstance.setContactorGroupChanged, name: FContactorGroupChanged},
{length: 4, setter: contactorInternalErrorsInstance.setUnexpectedFormation, name: FUnexpectedFormation},
{length: 2, setter: contactorInternalErrorsInstance.setCpuNotReady, name: FCpuNotReady},
{length: 2, setter: contactorInternalErrorsInstance.setPuNotReady, name: FPuNotReady},
{length: 2, setter: contactorInternalErrorsInstance.setDebug, name: FDebug},
{length: 5, setter: contactorInternalErrorsInstance.setPresentContactorMode, name: FPresentContactorMode},
}
protocolMap[key{can.CAN_ID_073, 0}] = action{
{length: 3, setter: c.contactorInternalErrorsInstance.setBoardReady, name: FBoardReady},
{length: 4, setter: c.contactorInternalErrorsInstance.setOtherError, name: FOtherError},
{length: 3, setter: c.contactorInternalErrorsInstance.setContactorGroupChanged, name: FContactorGroupChanged},
{length: 4, setter: c.contactorInternalErrorsInstance.setUnexpectedFormation, name: FUnexpectedFormation},
{length: 2, setter: c.contactorInternalErrorsInstance.setCpuNotReady, name: FCpuNotReady},
{length: 2, setter: c.contactorInternalErrorsInstance.setPuNotReady, name: FPuNotReady},
{length: 2, setter: c.contactorInternalErrorsInstance.setDebug, name: FDebug},
{length: 5, setter: c.contactorInternalErrorsInstance.setPresentContactorMode, name: FPresentContactorMode},
}
c.protocolMap[key{can.CAN_ID_073, 0}] = action{
fields: fields,
interval: 1000,
name: PContactorInternalErrors,
object: contactorInternalErrorsInstance,
object: c.contactorInternalErrorsInstance,
}
contactorsInternalForce = &ContactorsInternalForce{UnitId: 0}
c.contactorsInternalForce = &ContactorsInternalForce{unit: 0}
fields = []*field{
{length: 2, setter: contactorsInternalForce.setForceModeEnabled, name: FForceModeEnabled},
{length: 4, setter: contactorsInternalForce.setForceModeValue, name: FForceModeValue},
{length: 2, setter: c.contactorsInternalForce.setForceModeEnabled, name: FForceModeEnabled},
{length: 4, setter: c.contactorsInternalForce.setForceModeValue, name: FForceModeValue},
}
protocolMap[key{can.CAN_ID_074, 0}] = action{
c.protocolMap[key{can.CAN_ID_074, 0}] = action{
fields: fields,
interval: 1000,
name: PContactorsInternalForce,
object: contactorsInternalForce,
object: c.contactorsInternalForce,
}
for i := uint(0); i < CONTACTOR_MAX; i++ {
key := key{can.CAN_ID_075, i}
cid := &ContactorInternalDebug{UnitId: i}
contactorInternalDebugArray[i] = cid
cid := &ContactorInternalDebug{unit: unit(i)}
c.contactorInternalDebugArray[i] = cid
fields = []*field{
{length: 2, setter: cid.setDebugModeOn, name: FDebugModeOn},
{length: 3, setter: cid.setDebugContactorOn, name: FDebugContactorOn},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PContactorInternalDebug, object: cid}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PContactorInternalDebug, object: cid}
}
for i := uint(0); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_067, i}
ps := &PeripheryState{UnitId: i}
peripheryStateArray[i] = ps
ps := &PeripheryState{unit: unit(i)}
c.peripheryStateArray[i] = ps
fields = []*field{
{length: 3, setter: ps.setOtherErrorSeverity, name: FOtherErrorSeverity},
{length: 4, setter: ps.setOtherError, name: FOtherError},
@ -305,13 +307,13 @@ func initialize() {
{length: 2, setter: ps.setErrorContactorsInternalCircuitBreaker, name: FErrorContactorsInternalCircuitBreaker},
{length: 2, setter: ps.setErrorPlcCircuitBreaker, name: FErrorPlcCircuitBreaker},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PPeripheryState, object: ps}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PPeripheryState, object: ps}
}
for i := uint(0); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_068, i}
pi := &PeripheryInfo{UnitId: i}
peripheryInfoArray[i] = pi
pi := &PeripheryInfo{unit: unit(i)}
c.peripheryInfoArray[i] = pi
fields = []*field{
{length: 2, setter: pi.setInfoDoorOpen, name: FInfoDoorOpen},
{length: 8, setter: pi.setTempAirIn, name: FTempAirIn},
@ -319,39 +321,39 @@ func initialize() {
{length: 2, setter: pi.setStateShsnFan, name: FStateShsnFan},
{length: 2, setter: pi.setStateShptFan, name: FStateShptFan},
}
protocolMap[key] = action{fields: fields, interval: 5000, name: PPeripheryInfo, object: pi}
c.protocolMap[key] = action{fields: fields, interval: 5000, name: PPeripheryInfo, object: pi}
}
for i := uint(0); i <= CONNECTOR_COUNT; i++ {
key := key{can.CAN_ID_06C, i}
pd := &PeripheryDebug{UnitId: i}
peripheryDebugArray[i] = pd
pd := &PeripheryDebug{unit: unit(i)}
c.peripheryDebugArray[i] = pd
fields = []*field{
{length: 2, setter: pd.setDebugModeOn, name: FDebugModeOn},
{length: 3, setter: pd.setDebugShsnFan, name: FDebugShsnFan},
{length: 3, setter: pd.setDebugShptFan, name: FDebugShptFan},
{length: 3, setter: pd.setDebugIoBoardTestLamp, name: FDebugIoBoardTestLamp},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PPeripheryDebug, object: pd}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PPeripheryDebug, object: pd}
}
for i := uint(1); i < CONVERTERS_MAX; i++ {
key := key{can.CAN_ID_061, i}
cpe := &ConverterPresentEnergy{UnitId: i}
converterPresentEnergyArray[i] = cpe
cpe := &ConverterPresentEnergy{unit: unit(i)}
c.converterPresentEnergyArray[i] = cpe
fields = []*field{
{length: 2, setter: cpe.setV2gMode, name: FV2gMode},
{length: 11, setter: cpe.setPresentVoltage, name: FPresentVoltage},
{length: 10, setter: cpe.setPresentCurrent, name: FPresentCurrent},
{length: 8, setter: cpe.setConnectedOut, name: FConnectedOut},
}
protocolMap[key] = action{fields: fields, interval: 500, name: PConverterPresentEnergy, object: cpe}
c.protocolMap[key] = action{fields: fields, interval: 500, name: PConverterPresentEnergy, object: cpe}
}
for i := uint(1); i < CONVERTERS_MAX; i++ {
key := key{can.CAN_ID_062, i}
ce := &ConverterErrors{UnitId: i}
converterErrorsArray[i] = ce
ce := &ConverterErrors{unit: unit(i)}
c.converterErrorsArray[i] = ce
fields = []*field{
{length: 3, setter: ce.setBoardReady, name: FBoardReady},
{length: 4, setter: ce.setOtherError, name: FOtherError},
@ -371,24 +373,24 @@ func initialize() {
{length: 2, setter: ce.setDebugConvEnabled, name: FDebugConvEnabled},
{length: 2, setter: ce.setDebugConvDisabled, name: FDebugConvDisabled},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PConverterErrors, object: ce}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PConverterErrors, object: ce}
}
for i := uint(0); i < CONVERTERS_MAX; i++ {
key := key{can.CAN_ID_065, i}
cd := &ConverterDebug{UnitId: i}
converterDebugArray[i] = cd
cd := &ConverterDebug{unit: unit(i)}
c.converterDebugArray[i] = cd
fields = []*field{
{length: 2, setter: cd.setDebugModeOn, name: FDebugModeOn},
{length: 3, setter: cd.setDebugEnergyOn, name: FDebugEnergyOn},
{length: 11, setter: cd.setDebugTargetVoltage, name: FDebugTargetVoltage},
{length: 10, setter: cd.setDebugTargetCurrent, name: FDebugTargetCurrent},
}
protocolMap[key] = action{fields: fields, interval: 1000, name: PConverterDebug, object: cd}
c.protocolMap[key] = action{fields: fields, interval: 1000, name: PConverterDebug, object: cd}
}
// set "null" values
for _, element := range protocolMap {
for _, element := range c.protocolMap {
var from uint8 = 0
for _, f := range element.fields {
var mask uint64 = ^(ALL_BITS << f.length)

@ -6,44 +6,6 @@ import (
time "time"
)
type Action 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 AName string
type FName string
type Event struct {
UnitId uint
ActionName AName
Field FName
Object Action
Updated *time.Time
Value any
}
type action struct {
object Action
fields []*field
@ -64,75 +26,78 @@ type key struct {
unitId uint
}
var protocolMap map[key]action = make(map[key]action)
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 [CONTACTOR_MAX]*ContactorInternalState
var contactorInternalErrorsInstance *ContactorInternalErrors
var contactorsInternalForce *ContactorsInternalForce
var contactorInternalDebugArray [CONTACTOR_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 *Event {
result := make(chan *Event)
initialize()
go func() {
defer close(result)
for frame := range frames {
if frames == nil {
continue
}
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}
param := protocolMap[k]
var start uint8 = 0
for _, f := range param.fields {
if val, found := get(start, f.length, frame.Payload); found {
f.last = frame.Date
if f.value != val {
f.value = val
obj := f.setter(val)
result <- &Event{
Field: f.name,
ActionName: param.name,
Object: param.object,
UnitId: unitId,
Updated: frame.Date,
Value: obj,
}
type converter struct {
protocolMap map[key]action
cpuPresentEnergyArray [CONNECTOR_MAX]*CpuPresentEnergy
cpuPeripheryInstance *CpuPeriphery
cpuEnergySettingsArray [CONNECTOR_MAX]*CpuEnergySettings
cpuErrorsInstance *CpuErrors
cpuDebugInstance *CpuDebug
puPresentEnergyArray [CONNECTOR_MAX]*PuPresentEnergy
puPeripheryArray [CONNECTOR_MAX]*PuPeriphery
puErrorsArray [CONNECTOR_MAX]*PuErrors
puDebugArray [CONNECTOR_MAX]*PuDebug
seccTargetEnergyArray [CONNECTOR_MAX]*SeccTargetEnergy
seccErrorsArray [CONNECTOR_MAX]*SeccErrors
logicAuthArray [CONNECTOR_MAX]*LogicAuth
logicEnergyMode [CONNECTOR_MAX]*LogicEnergyMode
logicErrorsInstance *LogicErrors
logicWorkingMode *LogicWorkingMode
contactorInternalStateArray [CONTACTOR_MAX]*ContactorInternalState
contactorInternalErrorsInstance *ContactorInternalErrors
contactorsInternalForce *ContactorsInternalForce
contactorInternalDebugArray [CONTACTOR_MAX]*ContactorInternalDebug
peripheryStateArray [CONNECTOR_MAX]*PeripheryState
peripheryInfoArray [CONNECTOR_MAX]*PeripheryInfo
peripheryDebugArray [CONNECTOR_MAX]*PeripheryDebug
converterPresentEnergyArray [CONVERTERS_MAX]*ConverterPresentEnergy
converterErrorsArray [CONVERTERS_MAX]*ConverterErrors
converterDebugArray [CONVERTERS_MAX]*ConverterDebug
}
type Converter interface {
EventsFromFrame(*can.CanFrame) ([]*Event, bool)
}
func NewProtocolConverter() Converter {
c := &converter{}
c.initialize()
return c
}
func (c *converter) EventsFromFrame(frame *can.CanFrame) ([]*Event, bool) {
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}
if param, ok := c.protocolMap[k]; ok {
result := make([]*Event, 0, len(param.fields))
var start uint8 = 0
for _, f := range param.fields {
if val, found := get(start, f.length, frame.Payload); found {
f.last = frame.Date
if f.value != val { // value changed
f.value = val
obj := f.setter(val)
event := &Event{
Field: f.name,
ActionName: param.name,
Object: param.object,
unit: unit(unitId),
Updated: frame.Date,
Value: obj,
}
result = append(result, event)
}
start += f.length
}
start += f.length // next field
}
}()
return result
return result, len(result) > 0
}
return nil, false
}
func get(from uint8, size uint8, buffer []byte) (uint64, bool) {
@ -149,102 +114,6 @@ func get(from uint8, size uint8, buffer []byte) (uint64, bool) {
}
}
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
func (u unit) GetUnitId() uint {
return uint(u)
}

@ -1,7 +1,50 @@
package yabl
import "time"
type AName string
type FName string
type unit uint
type Action interface {
GetUnitId() uint
}
type Event struct {
unit
ActionName AName
Field FName
Object Action
Updated *time.Time
Value any
}
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 ContactorInternalState struct {
UnitId uint
unit
//UnitId uint
ContactorReady *BoardReadyType
ContactorOn *BooleanType
UnexpectedState *ErrorType
@ -10,7 +53,7 @@ type ContactorInternalState struct {
}
type ContactorInternalErrors struct {
UnitId uint
unit
BoardReady *BoardReadyType
OtherError *ContactorInternalOtherErrorType
ContactorGroupChanged *ContactorGroupChangedType
@ -22,19 +65,19 @@ type ContactorInternalErrors struct {
}
type ContactorsInternalForce struct {
UnitId uint
unit
ForceModeEnabled *BooleanType
ForceModeValue *ForceModeType
}
type ContactorInternalDebug struct {
UnitId uint
unit
DebugModeOn *BooleanType
DebugContactorOn *DebugSwitchModeType
}
type PuPresentEnergy struct {
UnitId uint
unit
V2GMode *V2GModeType
VoltageBefore *Voltage11BitType
VoltageAfter *Voltage11BitType
@ -42,7 +85,7 @@ type PuPresentEnergy struct {
}
type PuPeriphery struct {
UnitId uint
unit
ConnectorInsert *BooleanType
ContactorOn *BooleanType
ConnectorLocked *BooleanType
@ -54,13 +97,13 @@ type PuPeriphery struct {
}
type LogicAuth struct {
UnitId uint
unit
AuthMode *AuthModeType
AuthState *AuthStateType
}
type LogicEnergyMode struct {
UnitId uint
unit
V2gMode *V2GModeType
CurrentMax *Current10BitType
VoltageMax *Voltage11BitType
@ -68,33 +111,33 @@ type LogicEnergyMode struct {
}
type LogicErrors struct {
UnitId uint
unit
BoardReady *BoardReadyType
NotReadySettings *ErrorType
}
type LogicWorkingMode struct {
UnitId uint
unit
TargetContactorMode *ContactorModeType
Availability *BooleanType
}
type CpuPresentEnergy struct {
UnitId uint
unit
PowerDirectionMode *V2GModeType
PresentCurrent *Current10BitType
PresentVoltage *Voltage11BitType
}
type CpuPeriphery struct {
UnitId uint
unit
ContactorInput *BooleanType
CircuitBreakerInput *BooleanType
CircuitBreakerPowerCBInput *BooleanType
}
type CpuEnergySettings struct {
UnitId uint
unit
CurrentMax *Current10BitType
VoltageMax *Voltage11BitType
PowerMax *Power14BitType
@ -103,7 +146,7 @@ type CpuEnergySettings struct {
}
type CpuErrors struct {
UnitId uint
unit
BoardReady *BoardReadyType
OtherError *OtherError4BitType
RedButtonHard *ErrorType
@ -125,7 +168,7 @@ type CpuErrors struct {
}
type CpuDebug struct {
UnitId uint
unit
DebugModeOn *BooleanType
DebugContactorInputOn *DebugSwitchModeType
DebugCircuitBreakerOn *DebugSwitchModeType
@ -133,7 +176,7 @@ type CpuDebug struct {
}
type PuErrors struct {
UnitId uint
unit
BoardReady *BoardReadyType
OtherError *OtherError4BitType
IncorrectVoltage *ErrorType
@ -153,13 +196,13 @@ type PuErrors struct {
}
type PuDebug struct {
UnitId uint
unit
DebugModeOn *BooleanType
DebugContactorOutputOn *DebugSwitchModeType
}
type SeccTargetEnergy struct {
UnitId uint
unit
TargetChargingAllow *BooleanType
TargetBatteryVoltage *Voltage11BitType
TargetGoalVoltage *Voltage11BitType
@ -167,13 +210,13 @@ type SeccTargetEnergy struct {
}
type SeccErrors struct {
UnitId uint
unit
BoardReady *BoardReadyType
NotReadyLogic *ErrorType
}
type PeripheryState struct {
UnitId uint
unit
OtherErrorSeverity *BoardReadyType
OtherError *OtherError4BitType
ErrorShakeSensor *ErrorType
@ -199,7 +242,7 @@ type PeripheryState struct {
}
type PeripheryInfo struct {
UnitId uint
unit
InfoDoorOpen *BooleanType
TempAirIn *SignedAirTemp8BitType
TempAirOut *SignedAirTemp8BitType
@ -208,7 +251,7 @@ type PeripheryInfo struct {
}
type PeripheryDebug struct {
UnitId uint
unit
DebugModeOn *BooleanType
DebugShsnFan *DebugSwitchModeType
DebugShptFan *DebugSwitchModeType
@ -216,7 +259,7 @@ type PeripheryDebug struct {
}
type ConverterPresentEnergy struct {
UnitId uint
unit
V2gMode *V2GModeType
PresentVoltage *Voltage11BitType
PresentCurrent *Current10BitType
@ -224,7 +267,7 @@ type ConverterPresentEnergy struct {
}
type ConverterErrors struct {
UnitId uint
unit
BoardReady *BoardReadyType
OtherError *OtherError4BitType
NotConnectedOut *ErrorType
@ -245,7 +288,7 @@ type ConverterErrors struct {
}
type ConverterDebug struct {
UnitId uint
unit
DebugModeOn *BooleanType
DebugEnergyOn *DebugSwitchModeType
DebugTargetVoltage *Voltage11BitType

Loading…
Cancel
Save