Created a devices service and moved the CDashDisplay service to the sahdow realm

This commit is contained in:
2026-09-17 23:01:50 +01:00
parent 66012b6904
commit afc4b794bb
19 changed files with 444 additions and 184 deletions
@@ -116,7 +116,8 @@ type CDashDisplay struct {
State *CDashState
}
func NewCDashDisplay() (*CDashDisplay, error) {
// Connect will try to find and connect to the CDashDisplay
func Discover() (*CDashDisplay, error) {
// Look for the port
p, err := findDisplayPort()
if err != nil {
+9
View File
@@ -0,0 +1,9 @@
package cdashdisplay
import "esdi/peripheral/devices"
// TODO: I believe we don't need the #esdi/peripheral/devices thing anymore
const (
ID = devices.CDashDisplayDevID
Name = devices.CDashDisplayDevName
)
+9
View File
@@ -0,0 +1,9 @@
// Package devices simply defines what a device should have
// and some utils if necessary
package devices
import "esdi/telemetry"
type Device interface {
SendData(*telemetry.TelemetryData)
}
+1 -1
View File
@@ -1,6 +1,6 @@
module esdi
go 1.25.5
go 1.27.0
require (
github.com/ESilva15/ESgoRepl v0.1.0
+3 -2
View File
@@ -6,8 +6,9 @@ import "esdi/peripheral/types"
// IDs for our devices. They need to be correctly mapped on the devices
// themselves so we can discover them
const (
CDashDisplayDevID = 0x01
ESBtnBoxDevID = 0x02
CDashDisplayDevID = 0x01
CDashDisplayDevName = "CDashDisplay"
ESBtnBoxDevID = 0x02
)
// DeviceMap maps the implemented devices
+119 -136
View File
@@ -1,148 +1,131 @@
package services
import (
"context"
"fmt"
"log/slog"
"sync/atomic"
// type CDashService struct {
// Logger *slog.Logger
// CDash *cdashdisplay.CDashDisplay
// // DevClerk *peripheral.PeripheralDeviceClerk
// // Messages chan string
// // Telemetry Channel
// // streamCancel context.CancelFunc
// // TelemCh <-chan telemetry.TelemetryData
// }
"esdi/cdashdisplay"
helper "esdi/helpers"
"esdi/peripheral"
"esdi/telemetry"
)
// func NewCDashService(logger *slog.Logger) *CDashService {
// // sharedChannel := make(chan string, 10)
// return &CDashService{
// Logger: logger,
// CDash: nil,
// // DevClerk: peripheral.NewPeripheralDeviceClerk(),
// // Messages: sharedChannel,
// }
// }
type CDashService struct {
Logger *slog.Logger
CDash *cdashdisplay.CDashDisplay
DevClerk *peripheral.PeripheralDeviceClerk
Messages chan string
// Telemetry Channel
streamCancel context.CancelFunc
TelemCh <-chan telemetry.TelemetryData
}
// func (ds *CDashService) FindDevice() {
// ds.Messages <- "looking for cdash display...\n"
// ds.Logger.Info("Looking for CDashDisplay")
func NewCDashService(logger *slog.Logger) *CDashService {
sharedChannel := make(chan string, 10)
return &CDashService{
Logger: logger,
CDash: nil,
DevClerk: peripheral.NewPeripheralDeviceClerk(),
Messages: sharedChannel,
}
}
// cdashdisplay.SetLogger(ds.Logger.With("[device]", "cdashdisplay"))
func (cds *CDashService) FindDevice() {
cds.Messages <- "looking for cdash display...\n"
cds.Logger.Info("Looking for CDashDisplay")
// display, err := cdashdisplay.Discover()
// if err != nil {
// ds.Logger.Info("didn't find cdashdisplay")
// ds.Messages <- "didn't find cdash display\n"
// return
// }
//
// ds.CDash = display
// ds.Logger.Info("found cdashdisplay on: " + display.WT.Cfg.Name)
// ds.Messages <- "found cdashdisplay on: " + display.WT.Cfg.Name + "\n"
// }
cdashdisplay.SetLogger(cds.Logger.With("[device]", "cdashdisplay"))
// func (ds *CDashService) CreateWindow(
// win *cdashdisplay.DesktopUIWindow,
// ) (*cdashdisplay.DesktopUIWindow, error) {
// updatedWindow, err := ds.CDash.CreateWindow(win)
// if err != nil {
// return nil, err
// }
//
// return updatedWindow, nil
// }
//
// func (ds *CDashService) LoadLayout(layoutPath string) error {
// return ds.CDash.LoadLayout(layoutPath)
// }
//
// func (ds *CDashService) SaveLayout(layoutPath string) error {
// return ds.CDash.SaveLayout(layoutPath)
// }
//
// func (ds *CDashService) UnloadLayout() error {
// return ds.CDash.UnloadLayout()
// }
//
// func (ds *CDashService) UpdateWindow(win *cdashdisplay.DesktopUIWindow) error {
// ds.Messages <- fmt.Sprintf("Updating a window:\n%+v\n", win)
// return ds.CDash.UpdateWindow(win)
// }
//
// func (ds *CDashService) DeleteWindow(idx int16) error {
// return ds.CDash.DestroyWindow(idx)
// }
//
// func (ds *CDashService) ResizeWindow(idx int16, vec *helper.Vector) error {
// err := ds.CDash.ResizeWindow(idx, vec)
// if err != nil {
// return err
// }
//
// return nil
// }
//
// func (ds *CDashService) MoveWindow(idx int16, vec *helper.Vector) error {
// return ds.CDash.MoveWindow(idx, vec)
// }
display, err := cdashdisplay.NewCDashDisplay()
if err != nil {
cds.Logger.Info("didn't find cdashdisplay")
cds.Messages <- "didn't find cdash display\n"
return
}
// func (ds *CDashService) SetTelemetryChannel(ch <-chan telemetry.TelemetryData) {
// ds.TelemCh = ch
// }
cds.CDash = display
cds.Logger.Info("found cdashdisplay on: " + display.WT.Cfg.Name)
cds.Messages <- "found cdashdisplay on: " + display.WT.Cfg.Name + "\n"
}
func (cds *CDashService) CreateWindow(
win *cdashdisplay.DesktopUIWindow,
) (*cdashdisplay.DesktopUIWindow, error) {
updatedWindow, err := cds.CDash.CreateWindow(win)
if err != nil {
return nil, err
}
return updatedWindow, nil
}
func (cds *CDashService) LoadLayout(layoutPath string) error {
return cds.CDash.LoadLayout(layoutPath)
}
func (cds *CDashService) SaveLayout(layoutPath string) error {
return cds.CDash.SaveLayout(layoutPath)
}
func (cds *CDashService) UnloadLayout() error {
return cds.CDash.UnloadLayout()
}
func (cds *CDashService) UpdateWindow(win *cdashdisplay.DesktopUIWindow) error {
cds.Messages <- fmt.Sprintf("Updating a window:\n%+v\n", win)
return cds.CDash.UpdateWindow(win)
}
func (cds *CDashService) DeleteWindow(idx int16) error {
return cds.CDash.DestroyWindow(idx)
}
func (cds *CDashService) ResizeWindow(idx int16, vec *helper.Vector) error {
err := cds.CDash.ResizeWindow(idx, vec)
if err != nil {
return err
}
return nil
}
func (cds *CDashService) MoveWindow(idx int16, vec *helper.Vector) error {
err := cds.CDash.MoveWindow(idx, vec)
if err != nil {
return err
}
return nil
}
func (cds *CDashService) SetTelemetryChannel(ch <-chan telemetry.TelemetryData) {
cds.TelemCh = ch
}
func (cds *CDashService) StartStream() {
// NOTE: i'm using this pattern a whole lot. Maybe I can create a struct to handle this
var ctx context.Context
ctx, cds.streamCancel = context.WithCancel(context.Background())
go cds.transmit(ctx)
}
func (cds *CDashService) StopStream() {
if cds.streamCancel == nil {
return
}
cds.streamCancel()
cds.streamCancel = nil
}
// func (cds *CDashService) StartStream() {
// // NOTE: i'm using this pattern a whole lot. Maybe I can create a struct to handle this
// var ctx context.Context
// ctx, cds.streamCancel = context.WithCancel(context.Background())
//
// go cds.transmit(ctx)
// }
//
// func (cds *CDashService) StopStream() {
// if cds.streamCancel == nil {
// return
// }
//
// cds.streamCancel()
// cds.streamCancel = nil
// }
// INTERNAL
func (cds *CDashService) transmit(ctx context.Context) {
var isSending atomic.Bool
for {
select {
case <-ctx.Done():
return
case data, ok := <-cds.TelemCh:
if !ok {
return
}
if isSending.Load() {
continue
}
isSending.Store(true)
cds.CDash.SendData(&data)
isSending.Store(false)
}
}
}
// func (ds *CDashService) transmit(ctx context.Context) {
// var isSending atomic.Bool
//
// for {
// select {
// case <-ctx.Done():
// return
// case data, ok := <-ds.TelemCh:
// if !ok {
// return
// }
//
// if isSending.Load() {
// continue
// }
//
// isSending.Store(true)
//
// ds.CDash.SendData(&data)
// isSending.Store(false)
// }
// }
// }
-9
View File
@@ -1,9 +0,0 @@
package services
// DeviceService will handle sending the data from the telemetry service to the
// actual devices
// NOTE: create a virtual device and make it be the output window or something so
// we can just add it as a device or whatever instead of being a custom made thing
// that would be pretty cool I think
type DeviceService struct {
}
+123
View File
@@ -0,0 +1,123 @@
package services
import (
"context"
"fmt"
"log/slog"
"sync/atomic"
"esdi/devices"
"esdi/devices/cdashdisplay"
"esdi/telemetry"
)
// DeviceService will handle sending the data from the telemetry service to the
// actual devices
// NOTE: create a virtual device and make it be the output window or something so
// we can just add it as a device or whatever instead of being a custom made thing
// that would be pretty cool I think
type DeviceService struct {
Logger *slog.Logger
Devices map[string]devices.Device
// Strem handling
streamCancel context.CancelFunc
TelemCh <-chan telemetry.TelemetryData
// Output
Messages chan string
}
func NewDeviceService(logger *slog.Logger) *DeviceService {
sharedChannel := make(chan string, 10)
return &DeviceService{
Devices: make(map[string]devices.Device),
Logger: logger,
Messages: sharedChannel,
}
}
func (ds *DeviceService) FindDevices() {
// Need to define a list of devices to search for
// For now lets just try to find our cdashdisplay - will think about the rest later
// Find CDashDisplay
{
ds.Messages <- "looking for " + cdashdisplay.Name + "...\n"
ds.Logger.Info("Looking for " + cdashdisplay.Name)
cdashdisplay.SetLogger(ds.Logger.With("[device]", cdashdisplay.Name))
// Create a cdashdisplay
display, err := cdashdisplay.Discover()
if err == nil {
ds.Devices[cdashdisplay.Name] = display
ds.Logger.Info("found " + cdashdisplay.Name + " on: " + display.WT.Cfg.Name)
ds.Messages <- "found " + cdashdisplay.Name + " on: " + display.WT.Cfg.Name + "\n"
return
}
ds.Logger.Info("didn't find " + cdashdisplay.Name)
ds.Messages <- "didn't find " + cdashdisplay.Name + "\n"
// No CDashDisplay available for one reason or another, so we don't set the
// key
}
}
func (ds *DeviceService) GetDevice(name string) (devices.Device, error) {
val, ok := ds.Devices[name]
if !ok {
return nil, fmt.Errorf("device `%s` couldn't be found", name)
}
return val, nil
}
func (ds *DeviceService) StartStream() {
// NOTE: i'm using this pattern a whole lot. Maybe I can create a struct to handle this
var ctx context.Context
ctx, ds.streamCancel = context.WithCancel(context.Background())
go ds.transmit(ctx)
}
func (ds *DeviceService) StopStream() {
if ds.streamCancel == nil {
return
}
ds.streamCancel()
ds.streamCancel = nil
}
// SetTelemetryChannel sets the TelemCh to the passed channel
func (ds *DeviceService) SetTelemetryChannel(ch <-chan telemetry.TelemetryData) {
ds.TelemCh = ch
}
// transmit will send the data to the devices themselves
func (ds *DeviceService) transmit(ctx context.Context) {
var isSending atomic.Bool
for {
select {
case <-ctx.Done():
return
case data, ok := <-ds.TelemCh:
if !ok {
return
}
if isSending.Load() {
continue
}
isSending.Store(true)
// TODO: make a copy of the data and send that copy instead of keeping
// the data locked
for _, dev := range ds.Devices {
dev.SendData(&data)
}
isSending.Store(false)
}
}
}
+9 -6
View File
@@ -14,8 +14,8 @@ import (
// TelemetryService will be our base struct to handle telemetry data
// It should hook to a data sink and handle it like iRacing, BeamNG, AC and so on
type TelemetryService struct {
logger *slog.Logger
cdash *CDashService
logger *slog.Logger
devService *DeviceService
// Concurrency protection
mut sync.RWMutex
ativeProvider telem.TelemetryProvider
@@ -24,13 +24,16 @@ type TelemetryService struct {
cancelForward context.CancelFunc
}
func NewTelemetryService(logger *slog.Logger, cdash *CDashService) *TelemetryService {
func NewTelemetryService(logger *slog.Logger, devServo *DeviceService) *TelemetryService {
newService := &TelemetryService{
logger: logger,
cdash: cdash,
listeners: make(map[string]chan telem.TelemetryData),
logger: logger,
devService: devServo,
listeners: make(map[string]chan telem.TelemetryData),
}
// TODO: do not create and set a provider here, a background job should be
// detecting providers instead
// Need to instantiate a default provider here
// source := "/home/esilva/Desktop/projetos/simracing_peripherals/testTelemetry/gt3_mustang_bathurst.ibt"
firstProvider := providers.NewIRacingProvider(slog.Default(), goirsdk.Options{
@@ -5,11 +5,12 @@ import (
"os"
"strconv"
"esdi/cdashdisplay"
helper "esdi/helpers"
"esdi/devices/cdashdisplay"
"esdi/services"
"esdi/tui/internal/views"
helper "esdi/helpers"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
)
@@ -19,12 +20,14 @@ type LayoutController struct {
OnExit func()
LayoutToolView *views.LayoutToolView
Messages chan string
DevService *services.CDashService
DevService *services.DeviceService
MoveToolState *windowManipState
SelectedLayout string // NOTE: This should be a struct to handle its own things
// TODO: create a filter to select the layout
// filter telemetry provider, then filter vehicle in use and so on
}
func NewLayoutController(base *Controller, service *services.CDashService) *LayoutController {
func NewLayoutController(base *Controller, service *services.DeviceService) *LayoutController {
lc := &LayoutController{
Controller: base,
LayoutToolView: views.NewLayoutToolView(),
@@ -207,7 +210,20 @@ func (lc *LayoutController) createWindow() {
return
}
window, err = lc.DevService.CreateWindow(window)
// Acquire the cdashdisplay
displayIF, err := lc.DevService.GetDevice(cdashdisplay.Name)
if err != nil {
lc.Messages <- "failed to get " + cdashdisplay.Name
return
}
display, ok := displayIF.(*cdashdisplay.CDashDisplay)
if !ok {
lc.Messages <- "failed to acquire " + cdashdisplay.Name
return
}
// ---
window, err = display.CreateWindow(window)
if err != nil {
lc.Messages <- "failed to create window\n"
return
@@ -304,7 +320,20 @@ func (lc *LayoutController) newWindowAction() {
}
func (lc *LayoutController) updateWindowAction(win *cdashdisplay.DesktopUIWindow) {
err := lc.DevService.UpdateWindow(win)
// Acquire the cdashdisplay
displayIF, err := lc.DevService.GetDevice(cdashdisplay.Name)
if err != nil {
lc.Messages <- "failed to get " + cdashdisplay.Name
return
}
display, ok := displayIF.(*cdashdisplay.CDashDisplay)
if !ok {
lc.Messages <- "failed to acquire " + cdashdisplay.Name
return
}
// ---
err = display.UpdateWindow(win)
lc.Messages <- fmt.Sprintf("Window: %v\n", win)
@@ -317,7 +346,20 @@ func (lc *LayoutController) updateWindowAction(win *cdashdisplay.DesktopUIWindow
func (lc *LayoutController) displayLoadedLayouts() {
lc.Logger.Debug("We want to view our layout!")
for _, w := range lc.DevService.CDash.State.Layout.Windows {
// Acquire the cdashdisplay
displayIF, err := lc.DevService.GetDevice(cdashdisplay.Name)
if err != nil {
lc.Messages <- "failed to get " + cdashdisplay.Name
return
}
display, ok := displayIF.(*cdashdisplay.CDashDisplay)
if !ok {
lc.Messages <- "failed to acquire " + cdashdisplay.Name
return
}
// ---
for _, w := range display.State.Layout.Windows {
lc.Logger.Debug("==========================================================================")
lc.Logger.Debug(fmt.Sprintf("updating form view for a layout: %+v", w.UIData.TelemetryField))
err := lc.updateFormView(w)
@@ -349,8 +391,21 @@ func (lc *LayoutController) getCurrentTreeNodeModel() (*tview.TreeNode, int16, e
}
func (lc *LayoutController) loadLayout() {
// Acquire the cdashdisplay
displayIF, err := lc.DevService.GetDevice(cdashdisplay.Name)
if err != nil {
lc.Messages <- "failed to get " + cdashdisplay.Name
return
}
display, ok := displayIF.(*cdashdisplay.CDashDisplay)
if !ok {
lc.Messages <- "failed to acquire " + cdashdisplay.Name
return
}
// ---
// We would get the layout path from somewhere but for nots its layout.yaml
err := lc.DevService.LoadLayout(lc.SelectedLayout)
err = display.LoadLayout(lc.SelectedLayout)
if err != nil {
lc.Messages <- "failed to load layout: " + err.Error()
return
@@ -360,7 +415,20 @@ func (lc *LayoutController) loadLayout() {
}
func (lc *LayoutController) unloadLayout() {
err := lc.DevService.UnloadLayout()
// Acquire the cdashdisplay
displayIF, err := lc.DevService.GetDevice(cdashdisplay.Name)
if err != nil {
lc.Messages <- "failed to get " + cdashdisplay.Name
return
}
display, ok := displayIF.(*cdashdisplay.CDashDisplay)
if !ok {
lc.Messages <- "failed to acquire " + cdashdisplay.Name
return
}
// ---
err = display.UnloadLayout()
if err != nil {
lc.Logger.Error(fmt.Sprintf("Failed to unload layout: %+v", err))
return
@@ -368,7 +436,20 @@ func (lc *LayoutController) unloadLayout() {
}
func (lc *LayoutController) saveLayout() {
err := lc.DevService.SaveLayout(lc.SelectedLayout)
// Acquire the cdashdisplay
displayIF, err := lc.DevService.GetDevice(cdashdisplay.Name)
if err != nil {
lc.Messages <- "failed to get " + cdashdisplay.Name
return
}
display, ok := displayIF.(*cdashdisplay.CDashDisplay)
if !ok {
lc.Messages <- "failed to acquire " + cdashdisplay.Name
return
}
// ---
err = display.SaveLayout(lc.SelectedLayout)
if err != nil {
lc.Messages <- "failed to save layout: " + err.Error()
return
@@ -388,8 +469,21 @@ func (lc *LayoutController) deleteWindow() {
}
wID := curNode.GetReference().(int16)
// Acquire the cdashdisplay
displayIF, err := lc.DevService.GetDevice(cdashdisplay.Name)
if err != nil {
lc.Messages <- "failed to get " + cdashdisplay.Name
return
}
display, ok := displayIF.(*cdashdisplay.CDashDisplay)
if !ok {
lc.Messages <- "failed to acquire " + cdashdisplay.Name
return
}
// ---
// Delete it
err := lc.DevService.DeleteWindow(wID)
err = display.DestroyWindow(wID)
if err != nil {
lc.Messages <- "failed to delete window: " + err.Error() + "\n"
return
@@ -1,6 +1,7 @@
package controllers
import (
"esdi/devices/cdashdisplay"
helper "esdi/helpers"
"github.com/gdamore/tcell/v2"
@@ -43,40 +44,68 @@ func keyToVector(r rune) (helper.Vector, bool) {
}
func (lc *LayoutController) handleMovementCapture(idx int16,
ev *tcell.EventKey) *tcell.EventKey {
ev *tcell.EventKey,
) *tcell.EventKey {
vec, ok := keyToVector(ev.Rune())
if !ok {
return nil
}
err := lc.DevService.MoveWindow(idx, &vec)
// Acquire the cdashdisplay
displayIF, err := lc.DevService.GetDevice(cdashdisplay.Name)
if err != nil {
lc.Messages <- "failed to get " + cdashdisplay.Name
return nil
}
display, ok := displayIF.(*cdashdisplay.CDashDisplay)
if !ok {
lc.Messages <- "failed to acquire " + cdashdisplay.Name
return nil
}
// ---
err = display.MoveWindow(idx, &vec)
if err != nil {
lc.Messages <- "failed to move window: " + err.Error() + "\n"
return nil
}
// Success - update the form
window := lc.DevService.CDash.State.Layout.Windows[idx]
window := display.State.Layout.Windows[idx]
lc.LayoutToolView.UpdateFormView(idx, window)
return nil
}
func (lc *LayoutController) handleResizeCapture(idx int16,
ev *tcell.EventKey) *tcell.EventKey {
ev *tcell.EventKey,
) *tcell.EventKey {
vec, ok := keyToVector(ev.Rune())
if !ok {
return nil
}
err := lc.DevService.ResizeWindow(idx, &vec)
// Acquire the cdashdisplay
displayIF, err := lc.DevService.GetDevice(cdashdisplay.Name)
if err != nil {
lc.Messages <- "failed to get " + cdashdisplay.Name
return nil
}
display, ok := displayIF.(*cdashdisplay.CDashDisplay)
if !ok {
lc.Messages <- "failed to acquire " + cdashdisplay.Name
return nil
}
// ---
err = display.ResizeWindow(idx, &vec)
if err != nil {
lc.Messages <- "failed to resize window: " + err.Error() + "\n"
return nil
}
// Success - update the form
window := lc.DevService.CDash.State.Layout.Windows[idx]
window := display.State.Layout.Windows[idx]
lc.LayoutToolView.UpdateFormView(idx, window)
return nil
+5 -4
View File
@@ -15,12 +15,12 @@ type DeviceController struct {
DeviceAPIView *views.DeviceAPIView
LayoutCtrl *LayoutController
StreamCtrl *StreamingCtrl
DevService *serv.CDashService
DevService *serv.DeviceService
}
func NewDeviceController(
base *Controller,
devService *serv.CDashService,
devService *serv.DeviceService,
telemService *serv.TelemetryService,
) *DeviceController {
mc := &DeviceController{
@@ -56,7 +56,7 @@ func (mc *DeviceController) setDeviceAPIViewEvents() {
SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
switch ev.Rune() {
case 'r':
go mc.DevService.FindDevice()
go mc.DevService.FindDevices()
}
return ev
})
@@ -75,7 +75,8 @@ func (mc *DeviceController) AddDeviceAPIListItems() {
})
mc.DeviceAPIView.DevAPIList.
AddItem("stream", "stream data to the display", func() {
views.AddAndShowPage(mc.DeviceAPIView.DevAPIToolView.Pages,
views.AddAndShowPage(
mc.DeviceAPIView.DevAPIToolView.Pages,
"streaming-tool",
mc.StreamCtrl.StreamView.Flex,
)
+19 -5
View File
@@ -6,6 +6,7 @@ import (
"sync/atomic"
"esdi/config"
"esdi/devices/cdashdisplay"
"esdi/providers"
"esdi/services"
"esdi/telemetry"
@@ -17,7 +18,7 @@ import (
type StreamingCtrl struct {
*Controller
Service *services.CDashService
Service *services.DeviceService
StreamView *views.StreamToolView
Messages chan string
Internal chan string
@@ -32,7 +33,7 @@ type StreamingCtrl struct {
func NewStreamingCtrl(
base *Controller,
serCDash *services.CDashService,
devService *services.DeviceService,
serTelem *services.TelemetryService,
) *StreamingCtrl {
// NOTE: looks sus, put this somewhere also. Not very good in here
@@ -44,7 +45,7 @@ func NewStreamingCtrl(
ctrl := &StreamingCtrl{
Controller: base,
Service: serCDash,
Service: devService,
TelemServ: serTelem,
Messages: make(chan string, 10),
Internal: make(chan string, 10),
@@ -155,9 +156,22 @@ func (sc *StreamingCtrl) updateStream() {
// Performance reasoning: this is not used during the high frequency data transmission
// so we can get away with using a map for convenience here
func (sc *StreamingCtrl) SetInternalState() {
fields := make(map[int16]telemetry.FieldID, len(sc.Service.CDash.State.Layout.Windows))
// Acquire the cdashdisplay
displayIF, err := sc.Service.GetDevice(cdashdisplay.Name)
if err != nil {
sc.Messages <- "failed to get " + cdashdisplay.Name
return
}
display, ok := displayIF.(*cdashdisplay.CDashDisplay)
if !ok {
sc.Messages <- "failed to acquire " + cdashdisplay.Name
return
}
// ---
for _, w := range sc.Service.CDash.State.Layout.Windows {
fields := make(map[int16]telemetry.FieldID, len(display.State.Layout.Windows))
for _, w := range display.State.Layout.Windows {
fieldID, _ := telemetry.GetFieldID(w.UIData.TelemetryField)
fields[w.UIData.IDX] = fieldID
}
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"fmt"
"log/slog"
"esdi/cdashdisplay"
"esdi/devices/cdashdisplay"
tviewh "esdi/tui/internal/tview_helpers"
"github.com/gdamore/tcell/v2"
+1 -1
View File
@@ -3,7 +3,7 @@ package views
import (
"fmt"
"esdi/cdashdisplay"
"esdi/devices/cdashdisplay"
"esdi/telemetry"
"github.com/rivo/tview"
+3 -1
View File
@@ -23,7 +23,9 @@ func NewControlPanel(logger *slog.Logger) *ControlPanel {
App: tview.NewApplication(),
}
devService := services.NewCDashService(logger)
// NOTE: create our device service here
devService := services.NewDeviceService(logger)
telemService := services.NewTelemetryService(logger, devService)
if telemService == nil {
panic("failed to create the telemetry service")