From d5d0d903f0fbb3cbe5fc3e4bbc9669e0c5dc4c4c Mon Sep 17 00:00:00 2001 From: Terekhin Alexandr Date: Fri, 1 Sep 2023 11:17:23 +0300 Subject: [PATCH 1/7] Fix target energy settings --- ui/parameters.go | 34 +++++++++++++++--------------- ui/ui.go | 55 +++++++++++++++++++++++++----------------------- 2 files changed, 46 insertions(+), 43 deletions(-) diff --git a/ui/parameters.go b/ui/parameters.go index 119590f..924a050 100644 --- a/ui/parameters.go +++ b/ui/parameters.go @@ -8,23 +8,22 @@ var pu = []key{ {yabl.PCpuPresentEnergy, yabl.FPresentVoltage, 3}, {yabl.PPuPresentEnergy, yabl.FPresentCurrent, 4}, {yabl.PCpuPresentEnergy, yabl.FPresentCurrent, 5}, - {yabl.PPuPeriphery, yabl.FConnectorInsert, 6}, - {yabl.PPuPeriphery, yabl.FContactorOn, 7}, - {yabl.PPuPeriphery, yabl.FConnectorLocked, 8}, - {yabl.PPuPeriphery, yabl.FCpLineLevel, 9}, - {yabl.PPuPeriphery, yabl.FIsolationState, 10}, - {yabl.PPuPeriphery, yabl.FChargingAllowed, 11}, - {yabl.PPuPeriphery, yabl.FPwmEnabled, 12}, - {yabl.PPuPeriphery, yabl.FCpLineVoltage, 13}, - {yabl.PCpuEnergySettings, yabl.FTargetBatteryVoltage, 14}, - {yabl.PCpuEnergySettings, yabl.FTargetGoalVoltage, 15}, - {yabl.PCpuEnergySettings, yabl.FPowerMax, 16}, - {yabl.PCpuEnergySettings, yabl.FCurrentMax, 17}, - {yabl.PCpuEnergySettings, yabl.FVoltageMax, 18}, - {yabl.PPuDebug, yabl.FDebugModeOn, 19}, - {yabl.PPuDebug, yabl.FDebugContactorOutputOn, 20}, - {yabl.PPuPeriphery, yabl.FDebugContactorOn, 21}, - {yabl.PPuErrors, yabl.FBoardReady, 22}, + {yabl.PSeccTargetEnergy, yabl.FTargetCurrent, 6}, + {yabl.PPuPeriphery, yabl.FConnectorInsert, 7}, + {yabl.PPuPeriphery, yabl.FContactorOn, 8}, + {yabl.PPuPeriphery, yabl.FConnectorLocked, 9}, + {yabl.PPuPeriphery, yabl.FCpLineLevel, 10}, + {yabl.PPuPeriphery, yabl.FIsolationState, 11}, + {yabl.PPuPeriphery, yabl.FChargingAllowed, 12}, + {yabl.PPuPeriphery, yabl.FPwmEnabled, 13}, + {yabl.PPuPeriphery, yabl.FCpLineVoltage, 14}, + {yabl.PSeccTargetEnergy, yabl.FTargetBatteryVoltage, 15}, + {yabl.PSeccTargetEnergy, yabl.FTargetGoalVoltage, 16}, + {yabl.PCpuEnergySettings, yabl.FPowerMax, 17}, + {yabl.PCpuEnergySettings, yabl.FCurrentMax, 18}, + {yabl.PCpuEnergySettings, yabl.FVoltageMax, 19}, + {yabl.PPuDebug, yabl.FDebugModeOn, 20}, + {yabl.PPuErrors, yabl.FBoardReady, 21}, } var pu_errors = []key{ @@ -45,6 +44,7 @@ var pu_errors = []key{ {yabl.PPuErrors, yabl.FOutputCircuitBreakerEnabled, 15}, {yabl.PPuDebug, yabl.FDebugModeOn, 16}, {yabl.PPuDebug, yabl.FDebugContactorOutputOn, 17}, + {yabl.PPuPeriphery, yabl.FDebugContactorOn, 18}, } var contactors_errors = []key{ diff --git a/ui/ui.go b/ui/ui.go index 8da2e93..c0909d7 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -57,52 +57,55 @@ type log struct { } func (g *gui) Consume(event *yabl.Event) { + g.pu.update(event) + g.puErrors.update(event) + g.contactorsErrors.update(event) + g.contactorsState.update(event) + g.peripheryState.update(event) + g.peripheryStationState.update(event) + g.converters.update(event) + g.convertersErrors.update(event) + g.cpu.update(event) + switch event.Object.(type) { case *yabl.PuPresentEnergy: - g.pu.update(event) + break case *yabl.PuPeriphery: - g.pu.update(event) + break case *yabl.PuDebug: - g.pu.update(event) - g.puErrors.update(event) + break case *yabl.PuErrors: - g.pu.update(event) - g.puErrors.update(event) + break case *yabl.ContactorInternalErrors: - g.contactorsErrors.update(event) + break case *yabl.ContactorInternalDebug: - g.contactorsErrors.update(event) - g.contactorsState.update(event) + break case *yabl.ContactorInternalState: - g.contactorsState.update(event) + break case *yabl.ContactorsInternalForce: - g.contactorsErrors.update(event) + break case *yabl.PeripheryState: - g.peripheryState.update(event) - g.peripheryStationState.update(event) + break case *yabl.PeripheryInfo: - g.peripheryState.update(event) - g.peripheryStationState.update(event) + break case *yabl.PeripheryDebug: - g.peripheryState.update(event) - g.peripheryStationState.update(event) + break case *yabl.ConverterPresentEnergy: - g.converters.update(event) + break case *yabl.ConverterErrors: - g.converters.update(event) - g.convertersErrors.update(event) + break case *yabl.ConverterDebug: - g.converters.update(event) + break case *yabl.CpuPresentEnergy: - g.pu.update(event) + break case *yabl.CpuEnergySettings: - g.pu.update(event) + break case *yabl.CpuErrors: - g.cpu.update(event) + break case *yabl.CpuPeriphery: - g.cpu.update(event) + break case *yabl.CpuDebug: - g.cpu.update(event) + break default: return } -- 2.36.3 From 46b1f6dbb99c170a06ac924e0112f9e9a790524d Mon Sep 17 00:00:00 2001 From: Terekhin Alexandr Date: Tue, 10 Oct 2023 14:00:38 +0300 Subject: [PATCH 2/7] Fix offline timeouts --- cli-mon.go | 4 +++- yabl/protocol.go | 26 +++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/cli-mon.go b/cli-mon.go index 1801a31..a442827 100644 --- a/cli-mon.go +++ b/cli-mon.go @@ -54,9 +54,11 @@ func main() { updates := make(chan *yabl.Event, 1000) + isOffline := len(*filename) > 0 || *stdin + var f func() f = func() { - if events, ok := converter.CheckTimeouts(); ok { + if events, ok := converter.CheckTimeouts(isOffline); ok { for _, event := range events { updates <- event } diff --git a/yabl/protocol.go b/yabl/protocol.go index 47bfbfd..9a0cbdc 100644 --- a/yabl/protocol.go +++ b/yabl/protocol.go @@ -57,7 +57,7 @@ type converter struct { type Converter interface { EventsFromFrame(*can.CanFrame) ([]*Event, bool) - CheckTimeouts() ([]*Event, bool) + CheckTimeouts(isOffline bool) ([]*Event, bool) } func NewProtocolConverter() Converter { @@ -122,12 +122,19 @@ func (u unit) GetUnitId() uint { return uint(u) } -func (c *converter) CheckTimeouts() ([]*Event, bool) { +func (c *converter) CheckTimeouts(isOffline bool) ([]*Event, bool) { var multipler uint = 2 var events []*Event for k, param := range c.protocolMap { - now := time.Now() + + var now time.Time + if isOffline { + now = getMaxTime(&c.protocolMap) + } else { + now = time.Now() + } + deadline := now.Add(-time.Duration(param.interval*multipler) * time.Millisecond) var from uint8 = 0 @@ -161,3 +168,16 @@ func (c *converter) CheckTimeouts() ([]*Event, bool) { } return events, events != nil } + +func getMaxTime(protocolMap *map[key]action) time.Time { + now := time.Unix(0, 0) + + for _, param := range *protocolMap { + for _, fld := range param.fields { + if fld.last != nil && fld.last.After(now) { + now = *fld.last + } + } + } + return now +} -- 2.36.3 From 7679cc3ba9358d0d4362e8c2cc3c972e85d11711 Mon Sep 17 00:00:00 2001 From: Terekhin Alexandr Date: Fri, 13 Oct 2023 15:16:54 +0300 Subject: [PATCH 3/7] Stop on stdin close --- can/input.go | 1 + 1 file changed, 1 insertion(+) diff --git a/can/input.go b/can/input.go index 6ddca57..457b4a3 100644 --- a/can/input.go +++ b/can/input.go @@ -58,6 +58,7 @@ func ReadStdin() <-chan *CanFrame { go func() { scanner := bufio.NewScanner(os.Stdin) process(scanner, c) + close(c) }() return c } -- 2.36.3 From d709c2107dc5ce014a3c365068ede3c6e60ce641 Mon Sep 17 00:00:00 2001 From: Terekhin Alexandr Date: Fri, 13 Oct 2023 16:57:39 +0300 Subject: [PATCH 4/7] Minor refactor --- can/can.go | 69 ++++++------------------------------------------ can/input.go | 2 +- cli-mon.go | 31 +++++++++++++++++++++- yabl/const.go | 43 ++++++++++++++++++++++++------ yabl/init.go | 52 ++++++++++++++++++------------------ yabl/protocol.go | 4 +-- 6 files changed, 101 insertions(+), 100 deletions(-) diff --git a/can/can.go b/can/can.go index c812f61..379a37c 100644 --- a/can/can.go +++ b/can/can.go @@ -11,36 +11,11 @@ import ( "golang.org/x/sys/unix" ) -const CAN_ID_071 = 0x071 -const CAN_ID_073 = 0x073 -const CAN_ID_074 = 0x074 -const CAN_ID_075 = 0x075 -const CAN_ID_021 = 0x021 -const CAN_ID_022 = 0x022 -const CAN_ID_023 = 0x023 -const CAN_ID_011 = 0x011 -const CAN_ID_014 = 0x014 -const CAN_ID_015 = 0x015 -const CAN_ID_016 = 0x016 -const CAN_ID_01A = 0x01A -const CAN_ID_02A = 0x02A -const CAN_ID_041 = 0x041 -const CAN_ID_042 = 0x042 -const CAN_ID_046 = 0x046 -const CAN_ID_047 = 0x047 -const CAN_ID_048 = 0x048 -const CAN_ID_049 = 0x049 -const CAN_ID_067 = 0x067 -const CAN_ID_068 = 0x068 -const CAN_ID_06C = 0x06C -const CAN_ID_061 = 0x061 -const CAN_ID_062 = 0x062 -const CAN_ID_065 = 0x065 const bufferSize = 100 type CanFrame struct { CanId uint32 - Payload []uint8 + Payload *[]uint8 Date *time.Time } @@ -83,9 +58,9 @@ func (sck *Socket) Bind(addr string, filter []unix.CanFilter) error { return unix.Bind(sck.dev.fd, sck.addr) } -// Recv receives data from the CAN socket. +// Receive receives data from the CAN socket. // id is the CAN_frame id the data was originated from. -func (sck *Socket) Recv() (id uint32, data []byte, err error) { +func (sck *Socket) Receive() (id uint32, data *[]byte, err error) { var buf [frameSize]byte n, err := io.ReadFull(sck.dev, buf[:]) if err != nil { @@ -99,9 +74,9 @@ func (sck *Socket) Recv() (id uint32, data []byte, err error) { id = binary.LittleEndian.Uint32(buf[:4]) //TODO make correct switch betwin EFF and SFF id &= unix.CAN_EFF_MASK - data = make([]byte, buf[4]) - copy(data, buf[8:]) - return id, data, nil + payload := make([]byte, buf[4]) + copy(payload, buf[8:]) + return id, &payload, nil } type device struct { @@ -126,35 +101,7 @@ type canframe struct { Data [8]byte } -func StartCan(canbus string) (<-chan *CanFrame, error) { - - var filter []unix.CanFilter = []unix.CanFilter{ - {Id: CAN_ID_071, Mask: 0xFFF}, - {Id: CAN_ID_073, Mask: 0xFFF}, - {Id: CAN_ID_074, Mask: 0xFFF}, - {Id: CAN_ID_075, Mask: 0xFFF}, - {Id: CAN_ID_021, Mask: 0xFFF}, - {Id: CAN_ID_022, Mask: 0xFFF}, - {Id: CAN_ID_011, Mask: 0xFFF}, - {Id: CAN_ID_014, Mask: 0xFFF}, - {Id: CAN_ID_015, Mask: 0xFFF}, - {Id: CAN_ID_016, Mask: 0xFFF}, - {Id: CAN_ID_01A, Mask: 0xFFF}, - {Id: CAN_ID_023, Mask: 0xFFF}, - {Id: CAN_ID_02A, Mask: 0xFFF}, - {Id: CAN_ID_041, Mask: 0xFFF}, - {Id: CAN_ID_042, Mask: 0xFFF}, - {Id: CAN_ID_046, Mask: 0xFFF}, - {Id: CAN_ID_047, Mask: 0xFFF}, - {Id: CAN_ID_048, Mask: 0xFFF}, - {Id: CAN_ID_049, Mask: 0xFFF}, - {Id: CAN_ID_067, Mask: 0xFFF}, - {Id: CAN_ID_068, Mask: 0xFFF}, - {Id: CAN_ID_06C, Mask: 0xFFF}, - {Id: CAN_ID_061, Mask: 0xFFF}, - {Id: CAN_ID_062, Mask: 0xFFF}, - {Id: CAN_ID_065, Mask: 0xFFF}, - } +func StartCan(canbus string, filter []unix.CanFilter) (<-chan *CanFrame, error) { if socket, err := NewCan(); err == nil { @@ -167,7 +114,7 @@ func StartCan(canbus string) (<-chan *CanFrame, error) { defer socket.Close() for { //TODO implement stop - if id, data, serr := socket.Recv(); serr == nil { + if id, data, serr := socket.Receive(); serr == nil { var now = time.Now() canevents <- &CanFrame{ Date: &now, diff --git a/can/input.go b/can/input.go index 457b4a3..eeb9942 100644 --- a/can/input.go +++ b/can/input.go @@ -105,7 +105,7 @@ func fromString(text string) *CanFrame { return &CanFrame{ Date: &now, CanId: uint32(canId), - Payload: payload, + Payload: &payload, } } diff --git a/cli-mon.go b/cli-mon.go index a442827..964c48c 100644 --- a/cli-mon.go +++ b/cli-mon.go @@ -6,6 +6,7 @@ import ( "cli-mon/yabl" "flag" "fmt" + "golang.org/x/sys/unix" "os" "time" ) @@ -25,8 +26,36 @@ func main() { case len(*filename) > 0: frames = can.Readfile(filename) case len(*canbus) > 0: + filter := []unix.CanFilter{ + {Id: yabl.CanIdContIntState, Mask: 0xFFF}, + {Id: yabl.CanIdContIntErr, Mask: 0xFFF}, + {Id: yabl.CanIdContIntForce, Mask: 0xFFF}, + {Id: yabl.CanIdContIntDebug, Mask: 0xFFF}, + {Id: yabl.CanIdPuPresentEnergy, Mask: 0xFFF}, + {Id: yabl.CanIdPuPeriphery, Mask: 0xFFF}, + {Id: yabl.CanIdCpuPresentEnergy, Mask: 0xFFF}, + {Id: yabl.CanIdCpuPeriphery, Mask: 0xFFF}, + {Id: yabl.CanIdCpuEnergySettings, Mask: 0xFFF}, + {Id: yabl.CanIdCpuErrors, Mask: 0xFFF}, + {Id: yabl.CanIdCpuDebug, Mask: 0xFFF}, + {Id: yabl.CanIdPuErrors, Mask: 0xFFF}, + {Id: yabl.CanIdPuDebug, Mask: 0xFFF}, + {Id: yabl.CanIdSeccTargetEnergy, Mask: 0xFFF}, + {Id: yabl.CanIdSeccErrors, Mask: 0xFFF}, + {Id: yabl.CanIdLogicAuth, Mask: 0xFFF}, + {Id: yabl.CanIdLogicEnergyMode, Mask: 0xFFF}, + {Id: yabl.CanIdLogicErrors, Mask: 0xFFF}, + {Id: yabl.CanIdLogicWorkingMode, Mask: 0xFFF}, + {Id: yabl.CanIdPeripheryState, Mask: 0xFFF}, + {Id: yabl.CanIdPeripheryInfo, Mask: 0xFFF}, + {Id: yabl.CanIdPeripheryDebug, Mask: 0xFFF}, + {Id: yabl.CanIdConverterPresentEnergy, Mask: 0xFFF}, + {Id: yabl.CanIdConverterErrors, Mask: 0xFFF}, + {Id: yabl.CanIdConverterDebug, Mask: 0xFFF}, + } + var err error - frames, err = can.StartCan(*canbus) + frames, err = can.StartCan(*canbus, filter) if err != nil { fmt.Println(err) return diff --git a/yabl/const.go b/yabl/const.go index 2acd615..d08aa02 100644 --- a/yabl/const.go +++ b/yabl/const.go @@ -1,14 +1,41 @@ package yabl const ( - CONVERTERS_MAX = 18 + 1 - CONTACTOR_MAX = 18 + 1 - CONNECTOR_COUNT = 6 - CONNECTOR_MAX = CONNECTOR_COUNT + 1 - ALL_BITS = 0xFFFFFFFFFFFFFFFF - UNIT_ID_OFFSET = 12 - UNIT_ID_MASK = 0b111111111111 << UNIT_ID_OFFSET - ACTION_ID_MASK = 0b111111111111 + CONVERTERS_MAX = 18 + 1 + CONTACTOR_MAX = 18 + 1 + CONNECTOR_COUNT = 6 + CONNECTOR_MAX = CONNECTOR_COUNT + 1 + ALL_BITS = 0xFFFFFFFFFFFFFFFF + UNIT_ID_OFFSET = 12 + UNIT_ID_MASK = 0b111111111111 << UNIT_ID_OFFSET + ACTION_ID_MASK = 0b111111111111 + + CanIdContIntState = 0x071 + CanIdContIntErr = 0x073 + CanIdContIntForce = 0x074 + CanIdContIntDebug = 0x075 + CanIdPuPresentEnergy = 0x021 + CanIdPuPeriphery = 0x022 + CanIdPuErrors = 0x023 + CanIdCpuPresentEnergy = 0x011 + CanIdCpuPeriphery = 0x014 + CanIdCpuEnergySettings = 0x015 + CanIdCpuErrors = 0x016 + CanIdCpuDebug = 0x01A + CanIdPuDebug = 0x02A + CanIdSeccTargetEnergy = 0x041 + CanIdSeccErrors = 0x042 + CanIdLogicAuth = 0x046 + CanIdLogicEnergyMode = 0x047 + CanIdLogicErrors = 0x048 + CanIdLogicWorkingMode = 0x049 + CanIdPeripheryState = 0x067 + CanIdPeripheryInfo = 0x068 + CanIdPeripheryDebug = 0x06C + CanIdConverterPresentEnergy = 0x061 + CanIdConverterErrors = 0x062 + CanIdConverterDebug = 0x065 + BOARD_READY_OK BoardReadyType = 0 BOARD_READY_INFO BoardReadyType = 1 BOARD_READY_WARNING BoardReadyType = 2 diff --git a/yabl/init.go b/yabl/init.go index b910d9f..1c88a4d 100644 --- a/yabl/init.go +++ b/yabl/init.go @@ -1,12 +1,10 @@ package yabl -import "cli-mon/can" - 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} + key := key{CanIdCpuPresentEnergy, i} cpe := &CpuPresentEnergy{unit: 1} c.cpuPresentEnergyArray[i] = cpe fields := []*field{ @@ -23,7 +21,7 @@ func (c *converter) initialize() { {length: 2, setter: c.cpuPeripheryInstance.setCircuitBreakerInput, name: FCircuitBreakerInput}, {length: 2, setter: c.cpuPeripheryInstance.setCircuitBreakerPowerCBInput, name: FCircuitBreakerPowerCBInput}, } - c.protocolMap[key{can.CAN_ID_014, 0}] = action{ + c.protocolMap[key{CanIdCpuPeriphery, 0}] = action{ fields: fields, interval: 1000, name: PCpuPeriphery, @@ -31,7 +29,7 @@ func (c *converter) initialize() { } for i := uint(0); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_015, i} + key := key{CanIdCpuEnergySettings, i} ces := &CpuEnergySettings{unit: unit(i)} c.cpuEnergySettingsArray[i] = ces fields := []*field{ @@ -65,7 +63,7 @@ func (c *converter) initialize() { {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{ + c.protocolMap[key{CanIdCpuErrors, 0}] = action{ fields: fields, interval: 1000, name: PCpuErrors, @@ -79,7 +77,7 @@ func (c *converter) initialize() { {length: 3, setter: c.cpuDebugInstance.setDebugCircuitBreakerOn, name: FDebugCircuitBreakerOn}, {length: 3, setter: c.cpuDebugInstance.setDebugRedButtonSoftware, name: FDebugRedButtonSoftware}, } - c.protocolMap[key{can.CAN_ID_01A, 0}] = action{ + c.protocolMap[key{CanIdCpuDebug, 0}] = action{ fields: fields, interval: 1000, name: PCpuDebug, @@ -87,7 +85,7 @@ func (c *converter) initialize() { } for i := uint(1); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_021, i} + key := key{CanIdPuPresentEnergy, i} ppe := &PuPresentEnergy{unit: unit(i)} c.puPresentEnergyArray[i] = ppe fields := []*field{ @@ -100,7 +98,7 @@ func (c *converter) initialize() { } for i := uint(1); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_022, i} + key := key{CanIdPuPeriphery, i} pp := &PuPeriphery{unit: unit(i)} c.puPeripheryArray[i] = pp fields := []*field{ @@ -117,7 +115,7 @@ func (c *converter) initialize() { } for i := uint(1); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_023, i} + key := key{CanIdPuErrors, i} pe := &PuErrors{unit: 1} c.puErrorsArray[i] = pe fields := []*field{ @@ -142,7 +140,7 @@ func (c *converter) initialize() { } for i := uint(0); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_02A, i} + key := key{CanIdPuDebug, i} pd := &PuDebug{unit: unit(i)} c.puDebugArray[i] = pd fields = []*field{ @@ -153,7 +151,7 @@ func (c *converter) initialize() { } for i := uint(1); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_041, i} + key := key{CanIdSeccTargetEnergy, i} ste := &SeccTargetEnergy{unit: unit(i)} c.seccTargetEnergyArray[i] = ste fields = []*field{ @@ -166,7 +164,7 @@ func (c *converter) initialize() { } for i := uint(1); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_042, i} + key := key{CanIdSeccErrors, i} se := &SeccErrors{unit: unit(i)} c.seccErrorsArray[i] = se fields = []*field{ @@ -177,7 +175,7 @@ func (c *converter) initialize() { } for i := uint(0); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_046, i} + key := key{CanIdLogicAuth, i} la := &LogicAuth{unit: unit(i)} c.logicAuthArray[i] = la fields = []*field{ @@ -188,7 +186,7 @@ func (c *converter) initialize() { } for i := uint(0); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_047, i} + key := key{CanIdLogicEnergyMode, i} lem := &LogicEnergyMode{unit: unit(i)} c.logicEnergyMode[i] = lem fields = []*field{ @@ -205,7 +203,7 @@ func (c *converter) initialize() { {length: 3, setter: c.logicErrorsInstance.setBoardReady, name: FBoardReady}, {length: 2, setter: c.logicErrorsInstance.setNotReadySettings, name: FNotReadySettings}, } - c.protocolMap[key{can.CAN_ID_048, 0}] = action{ + c.protocolMap[key{CanIdLogicErrors, 0}] = action{ fields: fields, interval: 1000, name: PLogicErrors, @@ -213,7 +211,7 @@ func (c *converter) initialize() { } for i := uint(0); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_049, i} + key := key{CanIdLogicWorkingMode, i} lwm := &LogicWorkingMode{unit: unit(i)} c.logicWorkingMode[i] = lwm fields = []*field{ @@ -229,7 +227,7 @@ func (c *converter) initialize() { } for i := uint(0); i < CONTACTOR_MAX; i++ { - key := key{can.CAN_ID_071, i} + key := key{CanIdContIntState, i} cis := &ContactorInternalState{unit: unit(i)} c.contactorInternalStateArray[i] = cis fields = []*field{ @@ -253,7 +251,7 @@ func (c *converter) initialize() { {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{ + c.protocolMap[key{CanIdContIntErr, 0}] = action{ fields: fields, interval: 1000, name: PContactorInternalErrors, @@ -265,7 +263,7 @@ func (c *converter) initialize() { {length: 2, setter: c.contactorsInternalForce.setForceModeEnabled, name: FForceModeEnabled}, {length: 4, setter: c.contactorsInternalForce.setForceModeValue, name: FForceModeValue}, } - c.protocolMap[key{can.CAN_ID_074, 0}] = action{ + c.protocolMap[key{CanIdContIntForce, 0}] = action{ fields: fields, interval: 1000, name: PContactorsInternalForce, @@ -273,7 +271,7 @@ func (c *converter) initialize() { } for i := uint(0); i < CONTACTOR_MAX; i++ { - key := key{can.CAN_ID_075, i} + key := key{CanIdContIntDebug, i} cid := &ContactorInternalDebug{unit: unit(i)} c.contactorInternalDebugArray[i] = cid fields = []*field{ @@ -284,7 +282,7 @@ func (c *converter) initialize() { } for i := uint(0); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_067, i} + key := key{CanIdPeripheryState, i} ps := &PeripheryState{unit: unit(i)} c.peripheryStateArray[i] = ps fields = []*field{ @@ -315,7 +313,7 @@ func (c *converter) initialize() { } for i := uint(0); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_068, i} + key := key{CanIdPeripheryInfo, i} pi := &PeripheryInfo{unit: unit(i)} c.peripheryInfoArray[i] = pi fields = []*field{ @@ -329,7 +327,7 @@ func (c *converter) initialize() { } for i := uint(0); i <= CONNECTOR_COUNT; i++ { - key := key{can.CAN_ID_06C, i} + key := key{CanIdPeripheryDebug, i} pd := &PeripheryDebug{unit: unit(i)} c.peripheryDebugArray[i] = pd fields = []*field{ @@ -342,7 +340,7 @@ func (c *converter) initialize() { } for i := uint(1); i < CONVERTERS_MAX; i++ { - key := key{can.CAN_ID_061, i} + key := key{CanIdConverterPresentEnergy, i} cpe := &ConverterPresentEnergy{unit: unit(i)} c.converterPresentEnergyArray[i] = cpe fields = []*field{ @@ -355,7 +353,7 @@ func (c *converter) initialize() { } for i := uint(1); i < CONVERTERS_MAX; i++ { - key := key{can.CAN_ID_062, i} + key := key{CanIdConverterErrors, i} ce := &ConverterErrors{unit: unit(i)} c.converterErrorsArray[i] = ce fields = []*field{ @@ -381,7 +379,7 @@ func (c *converter) initialize() { } for i := uint(0); i < CONVERTERS_MAX; i++ { - key := key{can.CAN_ID_065, i} + key := key{CanIdConverterDebug, i} cd := &ConverterDebug{unit: unit(i)} c.converterDebugArray[i] = cd fields = []*field{ diff --git a/yabl/protocol.go b/yabl/protocol.go index 9a0cbdc..d8ba314 100644 --- a/yabl/protocol.go +++ b/yabl/protocol.go @@ -104,8 +104,8 @@ func (c *converter) EventsFromFrame(frame *can.CanFrame) ([]*Event, bool) { return nil, false } -func get(from uint8, size uint8, buffer []byte) (uint64, bool) { - value := binary.LittleEndian.Uint64(buffer) +func get(from uint8, size uint8, buffer *[]byte) (uint64, bool) { + value := binary.LittleEndian.Uint64(*buffer) var mask uint64 = ^(ALL_BITS << size) mask = mask << from -- 2.36.3 From 7b7c419f035e31e5b8284b68fc06fb6a0c41aa6b Mon Sep 17 00:00:00 2001 From: Terekhin Alexandr Date: Fri, 13 Oct 2023 17:17:41 +0300 Subject: [PATCH 5/7] Deadline as data los timestamp --- yabl/protocol.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yabl/protocol.go b/yabl/protocol.go index d8ba314..5979162 100644 --- a/yabl/protocol.go +++ b/yabl/protocol.go @@ -152,7 +152,7 @@ func (c *converter) CheckTimeouts(isOffline bool) ([]*Event, bool) { ActionName: param.name, Object: param.object, unit: unit(k.unitId), - Updated: &now, + Updated: &deadline, Value: nil, } -- 2.36.3 From 234a50adb2f234854dfa12e3cd9a6650c814b724 Mon Sep 17 00:00:00 2001 From: Terekhin Alexandr Date: Sat, 14 Oct 2023 19:37:39 +0300 Subject: [PATCH 6/7] Add amqp support --- can/input.go | 4 +-- can/input_test.go | 4 +-- cli-mon.go | 14 ++++++--- go.mod | 3 +- go.sum | 18 +++++++++++ ui/amqp.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++ ui/amqp_test.go | 35 +++++++++++++++++++++ yabl/strings.go | 22 ++++++++++++- 8 files changed, 168 insertions(+), 11 deletions(-) create mode 100644 ui/amqp.go create mode 100644 ui/amqp_test.go diff --git a/can/input.go b/can/input.go index eeb9942..32667c5 100644 --- a/can/input.go +++ b/can/input.go @@ -52,11 +52,11 @@ func process(scanner *bufio.Scanner, ch chan<- *CanFrame) { } } -func ReadStdin() <-chan *CanFrame { +func ReadStdin(file *os.File) <-chan *CanFrame { c := make(chan *CanFrame) go func() { - scanner := bufio.NewScanner(os.Stdin) + scanner := bufio.NewScanner(file) process(scanner, c) close(c) }() diff --git a/can/input_test.go b/can/input_test.go index 88071ad..ac28e43 100644 --- a/can/input_test.go +++ b/can/input_test.go @@ -36,7 +36,7 @@ func Test_fromString(t *testing.T) { want: &CanFrame{ Date: &time_m, CanId: 0x4021, - Payload: []uint8{00, 00, 00, 00, 0xFC, 0xFF, 0xFF, 0xFF}, + Payload: &[]uint8{00, 00, 00, 00, 0xFC, 0xFF, 0xFF, 0xFF}, }, }, { @@ -45,7 +45,7 @@ func Test_fromString(t *testing.T) { want: &CanFrame{ Date: &time_p, CanId: 0x100, - Payload: []uint8{00, 00, 00, 00, 00, 00, 0x64, 00}, + Payload: &[]uint8{00, 00, 00, 00, 00, 00, 0x64, 00}, }, }, } diff --git a/cli-mon.go b/cli-mon.go index 964c48c..8469bbc 100644 --- a/cli-mon.go +++ b/cli-mon.go @@ -4,7 +4,7 @@ import ( "cli-mon/can" "cli-mon/ui" "cli-mon/yabl" - "flag" + flag "flag" "fmt" "golang.org/x/sys/unix" "os" @@ -13,16 +13,18 @@ import ( func main() { filename := flag.String("f", "", "Candump filename") - canbus := flag.String("i", "", "CAN bus interface") + canbus := flag.String("i", "can0", "CAN bus interface") stdin := flag.Bool("s", false, "Read from stdin") - gui := flag.Bool("gui", false, "Text mode gui") + gui := flag.Bool("gui", false, "Pseudo-GUI CLI interface") + amqp := flag.String("amqp", "", "Run output to AMQP broker url") + interval := time.Duration(*flag.Uint("t", 50, "Override data loss check interval, ms")) flag.Parse() var frames <-chan *can.CanFrame switch { case *stdin: - frames = can.ReadStdin() + frames = can.ReadStdin(os.Stdin) case len(*filename) > 0: frames = can.Readfile(filename) case len(*canbus) > 0: @@ -75,6 +77,8 @@ func main() { if *gui { display = ui.NewUI() + } else if len(*amqp) > 0 { + display = ui.NewAmqp(*amqp) } else { display = ui.NewLog() } @@ -92,7 +96,7 @@ func main() { updates <- event } } - time.AfterFunc(50*time.Millisecond, f) + time.AfterFunc(interval*time.Millisecond, f) } time.AfterFunc(5*time.Second, f) diff --git a/go.mod b/go.mod index 1a86a66..e26b183 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,14 @@ module cli-mon go 1.19 require ( + github.com/gdamore/tcell/v2 v2.6.0 + github.com/rabbitmq/amqp091-go v1.9.0 github.com/rivo/tview v0.0.0-20230621164836-6cc0565babaf golang.org/x/sys v0.5.0 ) require ( github.com/gdamore/encoding v1.0.0 // indirect - github.com/gdamore/tcell/v2 v2.6.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/rivo/uniseg v0.4.3 // indirect diff --git a/go.sum b/go.sum index 949c504..0a5ac24 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,31 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell/v2 v2.6.0 h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCySg= github.com/gdamore/tcell/v2 v2.6.0/go.mod h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rabbitmq/amqp091-go v1.9.0 h1:qrQtyzB4H8BQgEuJwhmVQqVHB9O4+MNDJCCAcpc3Aoo= +github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= github.com/rivo/tview v0.0.0-20230621164836-6cc0565babaf h1:IchpMMtnfvzg7T3je672bP1nKWz1M4tW3kMZT6CbgoM= github.com/rivo/tview v0.0.0-20230621164836-6cc0565babaf/go.mod h1:nVwGv4MP47T0jvlk7KuTTjjuSmrGO4JF0iaiNt4bufE= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -40,3 +54,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/ui/amqp.go b/ui/amqp.go new file mode 100644 index 0000000..d2020e4 --- /dev/null +++ b/ui/amqp.go @@ -0,0 +1,79 @@ +package ui + +import ( + "cli-mon/yabl" + "context" + json "encoding/json" + "fmt" + amqp "github.com/rabbitmq/amqp091-go" + "os" + "time" +) + +const exchange = "yabl-newproto-in" + +var hostname, _ = os.Hostname() + +type broker struct { + uri string + conn *amqp.Connection + ch *amqp.Channel +} + +func NewAmqp(uri string) UI { + return &broker{uri: uri} +} + +func (b *broker) Consume(event *yabl.Event) { + var bytes []byte + var err error + if bytes, err = json.Marshal(event); err != nil { + return + } + + route := fmt.Sprintf( + "%s.%s.%s.%d", + hostname, + event.ActionName, + event.Field, + event.GetUnitId()) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + if err = b.ch.PublishWithContext(ctx, + exchange, + route, + false, + false, + amqp.Publishing{ + ContentType: "application/json", + Body: bytes, + }); err != nil { + fmt.Printf("Can't publish msg: %v", err) + } +} + +func (b *broker) Start() { + var err error + b.conn, err = amqp.Dial(b.uri) + if err != nil { + panic(fmt.Sprintf("Can't connect to AMQP: %v", err)) + } + + b.ch, err = b.conn.Channel() + if err != nil { + panic(fmt.Sprintf("Can't create AMQP channel: %v", err)) + } + + fmt.Printf("AMQP client connected to %v, sending data to server..", b.uri) +} + +func (b *broker) Stop() { + if b.conn != nil { + b.conn.Close() + } + if b.ch != nil { + b.ch.Close() + } +} diff --git a/ui/amqp_test.go b/ui/amqp_test.go new file mode 100644 index 0000000..53671c6 --- /dev/null +++ b/ui/amqp_test.go @@ -0,0 +1,35 @@ +package ui + +import ( + "cli-mon/yabl" + "testing" + "time" +) + +func TestNewAmqp(t *testing.T) { + t.Run("Amqp Test", func(t *testing.T) { + client := NewAmqp("amqp://user:password@localhost:5672/") + + if client == nil { + t.Errorf("Can't create client") + } + + client.Start() + + now := time.Now() + + event := &yabl.Event{ + Field: yabl.FBoardReady, + ActionName: yabl.PPuErrors, + Object: nil, + //unit: 3, + Updated: &now, + Value: yabl.ERROR, + } + + client.Consume(event) + + client.Stop() + }) + +} diff --git a/yabl/strings.go b/yabl/strings.go index 6a295d9..ffdcd2d 100644 --- a/yabl/strings.go +++ b/yabl/strings.go @@ -1,6 +1,10 @@ package yabl -import "fmt" +import ( + "encoding/json" + "fmt" + "time" +) func (t BooleanType) String() string { switch t { @@ -211,3 +215,19 @@ func (t SignedAirTemp8BitType) String() string { func (c ConnectedOut8bitType) String() string { return fmt.Sprintf("%d", c) } + +func (u *Event) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Unit uint + ActionName AName + Field FName + Updated *time.Time + Value string + }{ + Unit: u.GetUnitId(), + ActionName: u.ActionName, + Field: u.Field, + Updated: u.Updated, + Value: fmt.Sprintf("%v", u.Value), + }) +} -- 2.36.3 From 89bf574dec6f22073da7e11f5c79b5544b667071 Mon Sep 17 00:00:00 2001 From: Terekhin Alexandr Date: Sun, 15 Oct 2023 02:53:06 +0300 Subject: [PATCH 7/7] Add hostname as tag --- cli-mon.go | 2 +- ui/amqp.go | 9 +++------ ui/amqp_test.go | 8 ++++++-- ui/table.go | 2 +- ui/ui.go | 46 ++---------------------------------------- yabl/init.go | 52 ++++++++++++++++++++++++------------------------ yabl/protocol.go | 31 +++++++++++++++++++---------- yabl/strings.go | 6 ++++-- yabl/types.go | 7 ++++--- 9 files changed, 68 insertions(+), 95 deletions(-) diff --git a/cli-mon.go b/cli-mon.go index 8469bbc..c35c69a 100644 --- a/cli-mon.go +++ b/cli-mon.go @@ -71,7 +71,7 @@ func main() { os.Exit(0) } - converter := yabl.NewProtocolConverter() + converter := yabl.NewProtocolConverter("") var display ui.UI diff --git a/ui/amqp.go b/ui/amqp.go index d2020e4..c3852bf 100644 --- a/ui/amqp.go +++ b/ui/amqp.go @@ -6,14 +6,11 @@ import ( json "encoding/json" "fmt" amqp "github.com/rabbitmq/amqp091-go" - "os" "time" ) const exchange = "yabl-newproto-in" -var hostname, _ = os.Hostname() - type broker struct { uri string conn *amqp.Connection @@ -33,9 +30,9 @@ func (b *broker) Consume(event *yabl.Event) { route := fmt.Sprintf( "%s.%s.%s.%d", - hostname, - event.ActionName, - event.Field, + *event.Tag, + *event.ActionName, + *event.Field, event.GetUnitId()) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) diff --git a/ui/amqp_test.go b/ui/amqp_test.go index 53671c6..4216079 100644 --- a/ui/amqp_test.go +++ b/ui/amqp_test.go @@ -17,10 +17,14 @@ func TestNewAmqp(t *testing.T) { client.Start() now := time.Now() + field := yabl.FBoardReady + action := yabl.PPuErrors + tag := "localhost" event := &yabl.Event{ - Field: yabl.FBoardReady, - ActionName: yabl.PPuErrors, + Tag: &tag, + Field: &field, + ActionName: &action, Object: nil, //unit: 3, Updated: &now, diff --git a/ui/table.go b/ui/table.go index eb21c81..9b91172 100644 --- a/ui/table.go +++ b/ui/table.go @@ -21,7 +21,7 @@ type key struct { } func (t *table) update(event *yabl.Event) { - if cell, ok := t.views[key{event.ActionName, event.Field, event.GetUnitId()}]; ok { + if cell, ok := t.views[key{*event.ActionName, *event.Field, event.GetUnitId()}]; ok { cell.SetText(fmt.Sprintf("%v", event.Value)) } } diff --git a/ui/ui.go b/ui/ui.go index c0909d7..8b725db 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -67,48 +67,6 @@ func (g *gui) Consume(event *yabl.Event) { g.convertersErrors.update(event) g.cpu.update(event) - switch event.Object.(type) { - case *yabl.PuPresentEnergy: - break - case *yabl.PuPeriphery: - break - case *yabl.PuDebug: - break - case *yabl.PuErrors: - break - case *yabl.ContactorInternalErrors: - break - case *yabl.ContactorInternalDebug: - break - case *yabl.ContactorInternalState: - break - case *yabl.ContactorsInternalForce: - break - case *yabl.PeripheryState: - break - case *yabl.PeripheryInfo: - break - case *yabl.PeripheryDebug: - break - case *yabl.ConverterPresentEnergy: - break - case *yabl.ConverterErrors: - break - case *yabl.ConverterDebug: - break - case *yabl.CpuPresentEnergy: - break - case *yabl.CpuEnergySettings: - break - case *yabl.CpuErrors: - break - case *yabl.CpuPeriphery: - break - case *yabl.CpuDebug: - break - default: - return - } g.redraw = true } @@ -241,8 +199,8 @@ 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.ActionName, + *event.Field, event.GetUnitId(), event.Value) } diff --git a/yabl/init.go b/yabl/init.go index 1c88a4d..e1d91da 100644 --- a/yabl/init.go +++ b/yabl/init.go @@ -1,7 +1,7 @@ package yabl func (c *converter) initialize() { - c.protocolMap = make(map[key]action) + c.protocolMap = make(map[key]*action) for i := uint(1); i <= CONNECTOR_COUNT; i++ { key := key{CanIdCpuPresentEnergy, i} @@ -12,7 +12,7 @@ func (c *converter) initialize() { {length: 10, setter: cpe.setPresentCurrent, name: FPresentCurrent}, {length: 11, setter: cpe.setPresentVoltage, name: FPresentVoltage}, } - c.protocolMap[key] = action{fields: fields, interval: 50, name: PCpuPresentEnergy, object: cpe} + c.protocolMap[key] = &action{fields: fields, interval: 50, name: PCpuPresentEnergy, object: cpe} } c.cpuPeripheryInstance = &CpuPeriphery{unit: 0} @@ -21,7 +21,7 @@ func (c *converter) initialize() { {length: 2, setter: c.cpuPeripheryInstance.setCircuitBreakerInput, name: FCircuitBreakerInput}, {length: 2, setter: c.cpuPeripheryInstance.setCircuitBreakerPowerCBInput, name: FCircuitBreakerPowerCBInput}, } - c.protocolMap[key{CanIdCpuPeriphery, 0}] = action{ + c.protocolMap[key{CanIdCpuPeriphery, 0}] = &action{ fields: fields, interval: 1000, name: PCpuPeriphery, @@ -39,7 +39,7 @@ func (c *converter) initialize() { {length: 11, setter: ces.setTargetBatteryVoltage, name: FTargetBatteryVoltage}, {length: 11, setter: ces.setTargetGoalVoltage, name: FTargetGoalVoltage}, } - c.protocolMap[key] = action{fields: fields, interval: 1000, name: PCpuEnergySettings, object: ces} + c.protocolMap[key] = &action{fields: fields, interval: 1000, name: PCpuEnergySettings, object: ces} } c.cpuErrorsInstance = &CpuErrors{unit: 0} @@ -63,7 +63,7 @@ func (c *converter) initialize() { {length: 2, setter: c.cpuErrorsInstance.setContactorInputError, name: FContactorInputError}, {length: 2, setter: c.cpuErrorsInstance.setNotReadyPeriphery, name: FNotReadyPeriphery}, } - c.protocolMap[key{CanIdCpuErrors, 0}] = action{ + c.protocolMap[key{CanIdCpuErrors, 0}] = &action{ fields: fields, interval: 1000, name: PCpuErrors, @@ -77,7 +77,7 @@ func (c *converter) initialize() { {length: 3, setter: c.cpuDebugInstance.setDebugCircuitBreakerOn, name: FDebugCircuitBreakerOn}, {length: 3, setter: c.cpuDebugInstance.setDebugRedButtonSoftware, name: FDebugRedButtonSoftware}, } - c.protocolMap[key{CanIdCpuDebug, 0}] = action{ + c.protocolMap[key{CanIdCpuDebug, 0}] = &action{ fields: fields, interval: 1000, name: PCpuDebug, @@ -94,7 +94,7 @@ func (c *converter) initialize() { {length: 11, setter: ppe.setVoltageAfter, name: FVoltageAfter}, {length: 10, setter: ppe.setPresentCurrent, name: FPresentCurrent}, } - c.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++ { @@ -111,7 +111,7 @@ func (c *converter) initialize() { {length: 2, setter: pp.setPwmEnabled, name: FPwmEnabled}, {length: 9, setter: pp.setCpLineVoltage, name: FCpLineVoltage}, } - c.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++ { @@ -136,7 +136,7 @@ func (c *converter) initialize() { {length: 2, setter: pe.setOutputCircuitBreakerEnabled, name: FOutputCircuitBreakerEnabled}, {length: 12, setter: pe.setOutputCircuitBreakerEnabledValue, name: FOutputCircuitBreakerEnabledValue}, } - c.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++ { @@ -147,7 +147,7 @@ func (c *converter) initialize() { {length: 2, setter: pd.setDebugModeOn, name: FDebugModeOn}, {length: 3, setter: pd.setDebugContactorOutputOn, name: FDebugContactorOutputOn}, } - c.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++ { @@ -160,7 +160,7 @@ func (c *converter) initialize() { {length: 11, setter: ste.setTargetGoalVoltage, name: FTargetGoalVoltage}, {length: 10, setter: ste.setTargetCurrent, name: FTargetCurrent}, } - c.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++ { @@ -171,7 +171,7 @@ func (c *converter) initialize() { {length: 3, setter: se.setBoardReady, name: FBoardReady}, {length: 2, setter: se.setNotReadyLogic, name: FNotReadyLogic}, } - c.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++ { @@ -182,7 +182,7 @@ func (c *converter) initialize() { {length: 2, setter: la.setAuthMode, name: FAuthMode}, {length: 3, setter: la.setAuthState, name: FAuthState}, } - c.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++ { @@ -195,7 +195,7 @@ func (c *converter) initialize() { {length: 11, setter: lem.setVoltageMax, name: FVoltageMax}, {length: 14, setter: lem.setPowerMax, name: FPowerMax}, } - c.protocolMap[key] = action{fields: fields, interval: 1000, name: PLogicEnergyMode, object: lem} + c.protocolMap[key] = &action{fields: fields, interval: 1000, name: PLogicEnergyMode, object: lem} } c.logicErrorsInstance = &LogicErrors{unit: 0} @@ -203,7 +203,7 @@ func (c *converter) initialize() { {length: 3, setter: c.logicErrorsInstance.setBoardReady, name: FBoardReady}, {length: 2, setter: c.logicErrorsInstance.setNotReadySettings, name: FNotReadySettings}, } - c.protocolMap[key{CanIdLogicErrors, 0}] = action{ + c.protocolMap[key{CanIdLogicErrors, 0}] = &action{ fields: fields, interval: 1000, name: PLogicErrors, @@ -218,7 +218,7 @@ func (c *converter) initialize() { {length: 5, setter: lwm.setTargetContactorMode, name: FTargetContactorMode}, {length: 2, setter: lwm.setAvailability, name: FAvailability}, } - c.protocolMap[key] = action{ + c.protocolMap[key] = &action{ fields: fields, interval: 1000, name: PLogicWorkingMode, @@ -237,7 +237,7 @@ func (c *converter) initialize() { {length: 2, setter: cis.setIsolated, name: FIsolated}, {length: 2, setter: cis.setDebugEnabled, name: FDebugEnabled}, } - c.protocolMap[key] = action{fields: fields, interval: 1000, name: PContactorInternalState, object: cis} + c.protocolMap[key] = &action{fields: fields, interval: 1000, name: PContactorInternalState, object: cis} } c.contactorInternalErrorsInstance = &ContactorInternalErrors{unit: 0} @@ -251,7 +251,7 @@ func (c *converter) initialize() { {length: 2, setter: c.contactorInternalErrorsInstance.setDebug, name: FDebug}, {length: 5, setter: c.contactorInternalErrorsInstance.setPresentContactorMode, name: FPresentContactorMode}, } - c.protocolMap[key{CanIdContIntErr, 0}] = action{ + c.protocolMap[key{CanIdContIntErr, 0}] = &action{ fields: fields, interval: 1000, name: PContactorInternalErrors, @@ -263,7 +263,7 @@ func (c *converter) initialize() { {length: 2, setter: c.contactorsInternalForce.setForceModeEnabled, name: FForceModeEnabled}, {length: 4, setter: c.contactorsInternalForce.setForceModeValue, name: FForceModeValue}, } - c.protocolMap[key{CanIdContIntForce, 0}] = action{ + c.protocolMap[key{CanIdContIntForce, 0}] = &action{ fields: fields, interval: 1000, name: PContactorsInternalForce, @@ -278,7 +278,7 @@ func (c *converter) initialize() { {length: 2, setter: cid.setDebugModeOn, name: FDebugModeOn}, {length: 3, setter: cid.setDebugContactorOn, name: FDebugContactorOn}, } - c.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++ { @@ -309,7 +309,7 @@ func (c *converter) initialize() { {length: 2, setter: ps.setErrorContactorsInternalCircuitBreaker, name: FErrorContactorsInternalCircuitBreaker}, {length: 2, setter: ps.setErrorPlcCircuitBreaker, name: FErrorPlcCircuitBreaker}, } - c.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++ { @@ -323,7 +323,7 @@ func (c *converter) initialize() { {length: 2, setter: pi.setStateShsnFan, name: FStateShsnFan}, {length: 2, setter: pi.setStateShptFan, name: FStateShptFan}, } - c.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++ { @@ -336,7 +336,7 @@ func (c *converter) initialize() { {length: 3, setter: pd.setDebugShptFan, name: FDebugShptFan}, {length: 3, setter: pd.setDebugIoBoardTestLamp, name: FDebugIoBoardTestLamp}, } - c.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++ { @@ -349,7 +349,7 @@ func (c *converter) initialize() { {length: 10, setter: cpe.setPresentCurrent, name: FPresentCurrent}, {length: 8, setter: cpe.setConnectedOut, name: FConnectedOut}, } - c.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++ { @@ -375,7 +375,7 @@ func (c *converter) initialize() { {length: 2, setter: ce.setDebugConvEnabled, name: FDebugConvEnabled}, {length: 2, setter: ce.setDebugConvDisabled, name: FDebugConvDisabled}, } - c.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++ { @@ -388,7 +388,7 @@ func (c *converter) initialize() { {length: 11, setter: cd.setDebugTargetVoltage, name: FDebugTargetVoltage}, {length: 10, setter: cd.setDebugTargetCurrent, name: FDebugTargetCurrent}, } - c.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 diff --git a/yabl/protocol.go b/yabl/protocol.go index 5979162..bec4e80 100644 --- a/yabl/protocol.go +++ b/yabl/protocol.go @@ -3,6 +3,7 @@ package yabl import ( can "cli-mon/can" "encoding/binary" + "os" time "time" ) @@ -27,7 +28,8 @@ type key struct { } type converter struct { - protocolMap map[key]action + tag string + protocolMap map[key]*action cpuPresentEnergyArray [CONNECTOR_MAX]*CpuPresentEnergy cpuPeripheryInstance *CpuPeriphery cpuEnergySettingsArray [CONNECTOR_MAX]*CpuEnergySettings @@ -60,8 +62,15 @@ type Converter interface { CheckTimeouts(isOffline bool) ([]*Event, bool) } -func NewProtocolConverter() Converter { - c := &converter{} +func NewProtocolConverter(tag string) Converter { + if len(tag) == 0 { + tag = os.Getenv("HOSTNAME") + if len(tag) == 0 { + tag, _ = os.Hostname() + } + } + + c := &converter{tag: tag} c.initialize() return c } @@ -86,9 +95,10 @@ func (c *converter) EventsFromFrame(frame *can.CanFrame) ([]*Event, bool) { obj := f.setter(val) event := &Event{ - Field: f.name, - ActionName: param.name, - Object: param.object, + Tag: &c.tag, + Field: &f.name, + ActionName: ¶m.name, + Object: ¶m.object, unit: unit(unitId), Updated: frame.Date, Value: obj, @@ -148,9 +158,10 @@ func (c *converter) CheckTimeouts(isOffline bool) ([]*Event, bool) { } event := &Event{ - Field: fld.name, - ActionName: param.name, - Object: param.object, + Tag: &c.tag, + Field: &fld.name, + ActionName: ¶m.name, + Object: ¶m.object, unit: unit(k.unitId), Updated: &deadline, Value: nil, @@ -169,7 +180,7 @@ func (c *converter) CheckTimeouts(isOffline bool) ([]*Event, bool) { return events, events != nil } -func getMaxTime(protocolMap *map[key]action) time.Time { +func getMaxTime(protocolMap *map[key]*action) time.Time { now := time.Unix(0, 0) for _, param := range *protocolMap { diff --git a/yabl/strings.go b/yabl/strings.go index ffdcd2d..75b5457 100644 --- a/yabl/strings.go +++ b/yabl/strings.go @@ -218,12 +218,14 @@ func (c ConnectedOut8bitType) String() string { func (u *Event) MarshalJSON() ([]byte, error) { return json.Marshal(struct { + Host *string Unit uint - ActionName AName - Field FName + ActionName *AName + Field *FName Updated *time.Time Value string }{ + Host: u.Tag, Unit: u.GetUnitId(), ActionName: u.ActionName, Field: u.Field, diff --git a/yabl/types.go b/yabl/types.go index 1d60d82..69d75ab 100644 --- a/yabl/types.go +++ b/yabl/types.go @@ -13,9 +13,10 @@ type Action interface { type Event struct { unit - ActionName AName - Field FName - Object Action + Tag *string + ActionName *AName + Field *FName + Object *Action //TODO Actually obj, or copy on event generation time? Updated *time.Time Value any } -- 2.36.3