package ui import ( "cli-mon/yabl" "fmt" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" "os" ) const ( connectors_page = "Connectors" connectors_errors_page = "Connectors errors" contactors_errors_page = "Contactors errors" contactors_state_page = "Contactors states" periphery_state_page = "Periphery state" periphery_station_state_page = "Periphery station state" converters_page = "Converters" converters_errors_page = "Converters errors" cpu_page = "CPU" connectorCount = 6 contactorsCount = 18 convertersCount = 18 ) type page struct { left string right string primitive tview.Primitive } type UI interface { Consume(event *yabl.Event) Start() Stop() } type gui struct { app *tview.Application pages *tview.Pages pu *table puErrors *table contactorsErrors *table contactorsState *table peripheryState *table peripheryStationState *table converters *table convertersErrors *table cpu *table } type log struct { } func (g *gui) Consume(event *yabl.Event) { switch event.Object.(type) { case *yabl.PuPresentEnergy: g.pu.update(event) case *yabl.PuPeriphery: g.pu.update(event) case *yabl.PuDebug: g.pu.update(event) g.puErrors.update(event) case *yabl.PuErrors: g.pu.update(event) g.puErrors.update(event) case *yabl.ContactorInternalErrors: g.contactorsErrors.update(event) case *yabl.ContactorInternalDebug: g.contactorsErrors.update(event) g.contactorsState.update(event) case *yabl.ContactorInternalState: g.contactorsState.update(event) case *yabl.ContactorsInternalForce: g.contactorsErrors.update(event) case *yabl.PeripheryState: g.peripheryState.update(event) g.peripheryStationState.update(event) case *yabl.PeripheryInfo: g.peripheryState.update(event) g.peripheryStationState.update(event) case *yabl.PeripheryDebug: g.peripheryState.update(event) g.peripheryStationState.update(event) case *yabl.ConverterPresentEnergy: g.converters.update(event) case *yabl.ConverterErrors: g.converters.update(event) g.convertersErrors.update(event) case *yabl.ConverterDebug: g.converters.update(event) case *yabl.CpuPresentEnergy: g.pu.update(event) case *yabl.CpuEnergySettings: g.pu.update(event) case *yabl.CpuErrors: g.cpu.update(event) case *yabl.CpuPeriphery: g.cpu.update(event) case *yabl.CpuDebug: g.cpu.update(event) } g.app.Draw() } func NewUI() UI { g := &gui{} g.app = tview.NewApplication() g.pages = tview.NewPages() var active page var layout map[string]page g.pu = newTable(pu, 1, connectorCount, false, false).header(connectors_page).columns("Connector", connectorCount) g.puErrors = newTable(pu_errors, 1, connectorCount, false, false).header(connectors_errors_page).columns("Connector", connectorCount) g.contactorsErrors = newTable(contactors_errors, 0, 0, false, false).header(contactors_errors_page) g.contactorsState = newTable(contactors_state, 1, contactorsCount, true, true).header(contactors_state_page).rows("Contactor", contactorsCount) g.peripheryState = newTable(periphery_state, 1, connectorCount, false, false).header(periphery_state_page).columns("Connector", connectorCount) g.peripheryStationState = newTable(periphery_station_state, 0, 1, false, false).header(periphery_station_state_page) g.converters = newTable(converters, 1, convertersCount, false, true).header(converters_page).columns("", convertersCount) g.convertersErrors = newTable(converters_errors, 1, convertersCount, false, true).header(converters_errors_page).columns("", convertersCount) g.cpu = newTable(cpu, 0, 0, false, false).header(cpu_page) layout = map[string]page{ connectors_page: { left: cpu_page, right: connectors_errors_page, primitive: g.pu, }, connectors_errors_page: { left: connectors_page, right: contactors_errors_page, primitive: g.puErrors, }, contactors_errors_page: { left: connectors_errors_page, right: contactors_state_page, primitive: g.contactorsErrors, }, contactors_state_page: { left: contactors_errors_page, right: periphery_state_page, primitive: g.contactorsState, }, periphery_state_page: { left: contactors_state_page, right: periphery_station_state_page, primitive: g.peripheryState, }, periphery_station_state_page: { left: periphery_state_page, right: converters_page, primitive: g.peripheryStationState, }, converters_page: { left: periphery_station_state_page, right: converters_errors_page, primitive: g.converters, }, converters_errors_page: { left: converters_page, right: cpu_page, primitive: g.convertersErrors, }, cpu_page: { left: converters_errors_page, right: connectors_page, primitive: g.cpu, }, } for k, p := range layout { g.pages.AddPage(k, p.primitive, true, true) } active = layout[connectors_page] g.pages.SwitchToPage(connectors_page) g.app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { switch event.Key() { case tcell.KeyRight: g.pages.SwitchToPage(active.right) active = layout[active.right] return nil case tcell.KeyLeft: g.pages.SwitchToPage(active.left) active = layout[active.left] return nil case tcell.KeyCtrlC: g.Stop() } return event }) return g } func (g *gui) Start() { go func() { if err := g.app.SetRoot(g.pages, true).EnableMouse(true).Run(); err != nil { panic(err) } }() } func (g *gui) Stop() { g.app.Stop() os.Exit(0) } 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() { }