From 2cb30baf6a097459c5f49d9310b7c12475efb574 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Sun, 31 May 2026 07:22:06 +0100 Subject: [PATCH] first approach to implementing virtual binds virtual binds will just be some middleware that sits between telemetry primitives and computed values from it like dash lights and a fuel calc --- layouts/layout.yaml | 474 ++++++++++++++++++----------------- providers/iracing/iracing.go | 25 +- telemetry/data.go | 24 +- telemetry/rpm_lights.go | 26 ++ 4 files changed, 317 insertions(+), 232 deletions(-) create mode 100644 telemetry/rpm_lights.go diff --git a/layouts/layout.yaml b/layouts/layout.yaml index 9528241..a38dadb 100755 --- a/layouts/layout.yaml +++ b/layouts/layout.yaml @@ -1,149 +1,5 @@ Windows: 1: - uiwindow: - Dims: - X0: 207 - Y0: 412 - Width: 111 - Height: 57 - Decor: - BGColour: 4161 - FGColour: 65535 - TitleColour: 65535 - BorderColour: 63488 - TitleSize: 2 - TextSize: 4 - HasBorder: 1 - Padding: 0 - Opts: - ShowID: 0 - WinType: 2 - PreviewValue: "61.4" - Title: BBias - uidata: - WID: 1 - TelemetryField: BrakeBias - 2: - uiwindow: - Dims: - X0: 710 - Y0: 8 - Width: 84 - Height: 57 - Decor: - BGColour: 4161 - FGColour: 65535 - TitleColour: 65535 - BorderColour: 63488 - TitleSize: 2 - TextSize: 4 - HasBorder: 1 - Padding: 0 - Opts: - ShowID: 0 - WinType: 2 - PreviewValue: PIT - Title: Pit Sp - uidata: - WID: 2 - TelemetryField: Pit Speed Limiter - 3: - uiwindow: - Dims: - X0: 74 - Y0: 413 - Width: 57 - Height: 57 - Decor: - BGColour: 4161 - FGColour: 65535 - TitleColour: 65535 - BorderColour: 63488 - TitleSize: 2 - TextSize: 4 - HasBorder: 1 - Padding: 0 - Opts: - ShowID: 0 - WinType: 2 - PreviewValue: "12" - Title: TC - uidata: - WID: 3 - TelemetryField: TC Control - 4: - uiwindow: - Dims: - X0: 60 - Y0: 91 - Width: 85 - Height: 57 - Decor: - BGColour: 4161 - FGColour: 65535 - TitleColour: 65535 - BorderColour: 63488 - TitleSize: 2 - TextSize: 4 - HasBorder: 1 - Padding: 0 - Opts: - ShowID: 0 - WinType: 2 - PreviewValue: "123" - Title: Lap - uidata: - WID: 4 - TelemetryField: Lap Number - 5: - uiwindow: - Dims: - X0: 142 - Y0: 19 - Width: 500 - Height: 20 - Decor: - BGColour: 4161 - FGColour: 65535 - TitleColour: 65535 - BorderColour: 63488 - TitleSize: 1 - TextSize: 2 - HasBorder: 1 - Padding: 0 - Opts: - ShowID: 0 - WinType: 1 - PreviewValue: "5678" - Title: TACHO - uidata: - WID: 5 - TelemetryField: RPM - 6: - uiwindow: - Dims: - X0: 331 - Y0: 190 - Width: 116 - Height: 70 - Decor: - BGColour: 4161 - FGColour: 65535 - TitleColour: 65535 - BorderColour: 63488 - TitleSize: 2 - TextSize: 6 - HasBorder: 1 - Padding: 0 - Opts: - ShowID: 0 - WinType: 2 - PreviewValue: "234" - Title: SPEEDO - uidata: - WID: 6 - TelemetryField: Speed - 7: uiwindow: Dims: X0: 9 @@ -165,57 +21,9 @@ Windows: PreviewValue: "12" Title: ABS uidata: - WID: 7 + WID: 1 TelemetryField: ABS Control - 8: - uiwindow: - Dims: - X0: 590 - Y0: 367 - Width: 100 - Height: 50 - Decor: - BGColour: 4161 - FGColour: 65535 - TitleColour: 65535 - BorderColour: 63488 - TitleSize: 2 - TextSize: 3 - HasBorder: 1 - Padding: 0 - Opts: - ShowID: 0 - WinType: 2 - PreviewValue: "101.5" - Title: Water T - uidata: - WID: 8 - TelemetryField: Water Temperature - 9: - uiwindow: - Dims: - X0: 354 - Y0: 71 - Width: 74 - Height: 111 - Decor: - BGColour: 4161 - FGColour: 65535 - TitleColour: 65535 - BorderColour: 63488 - TitleSize: 2 - TextSize: 12 - HasBorder: 1 - Padding: 0 - Opts: - ShowID: 0 - WinType: 2 - PreviewValue: R - Title: Box - uidata: - WID: 9 - TelemetryField: Gear - 10: + 2: uiwindow: Dims: X0: 140 @@ -237,33 +45,9 @@ Windows: PreviewValue: "6" Title: Thr uidata: - WID: 10 + WID: 2 TelemetryField: Throttle Control - 11: - uiwindow: - Dims: - X0: 694 - Y0: 423 - Width: 100 - Height: 50 - Decor: - BGColour: 4161 - FGColour: 65535 - TitleColour: 65535 - BorderColour: 63488 - TitleSize: 2 - TextSize: 3 - HasBorder: 1 - Padding: 0 - Opts: - ShowID: 0 - WinType: 2 - PreviewValue: "4.56" - Title: Oil P - uidata: - WID: 11 - TelemetryField: Oil Pressure - 12: + 3: uiwindow: Dims: X0: 60 @@ -285,9 +69,105 @@ Windows: PreviewValue: "06:45.123" Title: Last Lap uidata: - WID: 12 + WID: 3 TelemetryField: Last Lap Time - 13: + 4: + uiwindow: + Dims: + X0: 74 + Y0: 413 + Width: 57 + Height: 57 + Decor: + BGColour: 4161 + FGColour: 65535 + TitleColour: 65535 + BorderColour: 63488 + TitleSize: 2 + TextSize: 4 + HasBorder: 1 + Padding: 0 + Opts: + ShowID: 0 + WinType: 2 + PreviewValue: "12" + Title: TC + uidata: + WID: 4 + TelemetryField: TC Control + 5: + uiwindow: + Dims: + X0: 590 + Y0: 367 + Width: 100 + Height: 50 + Decor: + BGColour: 4161 + FGColour: 65535 + TitleColour: 65535 + BorderColour: 63488 + TitleSize: 2 + TextSize: 3 + HasBorder: 1 + Padding: 0 + Opts: + ShowID: 0 + WinType: 2 + PreviewValue: "101.5" + Title: Water T + uidata: + WID: 5 + TelemetryField: Water Temperature + 6: + uiwindow: + Dims: + X0: 354 + Y0: 71 + Width: 74 + Height: 111 + Decor: + BGColour: 4161 + FGColour: 65535 + TitleColour: 65535 + BorderColour: 63488 + TitleSize: 2 + TextSize: 12 + HasBorder: 1 + Padding: 0 + Opts: + ShowID: 0 + WinType: 2 + PreviewValue: R + Title: Box + uidata: + WID: 6 + TelemetryField: Gear + 7: + uiwindow: + Dims: + X0: 694 + Y0: 423 + Width: 100 + Height: 50 + Decor: + BGColour: 4161 + FGColour: 65535 + TitleColour: 65535 + BorderColour: 63488 + TitleSize: 2 + TextSize: 3 + HasBorder: 1 + Padding: 0 + Opts: + ShowID: 0 + WinType: 2 + PreviewValue: "4.56" + Title: Oil P + uidata: + WID: 7 + TelemetryField: Oil Pressure + 8: uiwindow: Dims: X0: 694 @@ -309,9 +189,9 @@ Windows: PreviewValue: "101.4" Title: Oil T uidata: - WID: 13 + WID: 8 TelemetryField: Oil Temperature - 14: + 9: uiwindow: Dims: X0: 436 @@ -333,5 +213,149 @@ Windows: PreviewValue: "9999" Title: Dig Tacho uidata: - WID: 14 + WID: 9 TelemetryField: RPM + 10: + uiwindow: + Dims: + X0: 207 + Y0: 412 + Width: 111 + Height: 57 + Decor: + BGColour: 4161 + FGColour: 65535 + TitleColour: 65535 + BorderColour: 63488 + TitleSize: 2 + TextSize: 4 + HasBorder: 1 + Padding: 0 + Opts: + ShowID: 0 + WinType: 2 + PreviewValue: "61.4" + Title: BBias + uidata: + WID: 10 + TelemetryField: BrakeBias + 11: + uiwindow: + Dims: + X0: 710 + Y0: 8 + Width: 84 + Height: 57 + Decor: + BGColour: 4161 + FGColour: 65535 + TitleColour: 65535 + BorderColour: 63488 + TitleSize: 2 + TextSize: 4 + HasBorder: 1 + Padding: 0 + Opts: + ShowID: 0 + WinType: 2 + PreviewValue: PIT + Title: Pit Sp + uidata: + WID: 11 + TelemetryField: Pit Speed Limiter + 12: + uiwindow: + Dims: + X0: 60 + Y0: 91 + Width: 85 + Height: 57 + Decor: + BGColour: 4161 + FGColour: 65535 + TitleColour: 65535 + BorderColour: 63488 + TitleSize: 2 + TextSize: 4 + HasBorder: 1 + Padding: 0 + Opts: + ShowID: 0 + WinType: 2 + PreviewValue: "123" + Title: Lap + uidata: + WID: 12 + TelemetryField: Lap Number + 13: + uiwindow: + Dims: + X0: 142 + Y0: 19 + Width: 500 + Height: 20 + Decor: + BGColour: 4161 + FGColour: 65535 + TitleColour: 65535 + BorderColour: 63488 + TitleSize: 1 + TextSize: 2 + HasBorder: 1 + Padding: 0 + Opts: + ShowID: 0 + WinType: 1 + PreviewValue: "5678" + Title: TACHO + uidata: + WID: 13 + TelemetryField: RPM + 14: + uiwindow: + Dims: + X0: 331 + Y0: 190 + Width: 116 + Height: 70 + Decor: + BGColour: 4161 + FGColour: 65535 + TitleColour: 65535 + BorderColour: 63488 + TitleSize: 2 + TextSize: 6 + HasBorder: 1 + Padding: 0 + Opts: + ShowID: 0 + WinType: 2 + PreviewValue: "234" + Title: SPEEDO + uidata: + WID: 14 + TelemetryField: Speed + 15: + uiwindow: + Dims: + X0: 359 + Y0: 355 + Width: 120 + Height: 49 + Decor: + BGColour: 4161 + FGColour: 65535 + TitleColour: 65535 + BorderColour: 63488 + TitleSize: 2 + TextSize: 3 + HasBorder: 1 + Padding: 0 + Opts: + ShowID: 0 + WinType: 2 + PreviewValue: YELLOW + Title: RPMColour + uidata: + WID: 15 + TelemetryField: RPM State Colour diff --git a/providers/iracing/iracing.go b/providers/iracing/iracing.go index 8029d65..f40939b 100644 --- a/providers/iracing/iracing.go +++ b/providers/iracing/iracing.go @@ -123,13 +123,21 @@ func (i *IRacing) readData() { return } - // Read binded data + // Read 1 to 1 data for _, b := range i.data.ActiveBinds { v := i.SDK.Vars.Vars[b.Key].Value b.Transform(v, &i.data.Values[b.ID]) } + // Set up virtual binds + i.logger.Debug("Entering virtual binds loop") + for _, vBind := range i.data.VirtualBinds { + // NOTE: delete the logs here, they are really bad + i.logger.Debug("Processing virtual binds") + vBind.Process(i.data) + } + i.data.PenultimateDataPoll = i.data.LastDataPoll i.data.LastDataPoll = time.Now() } @@ -258,5 +266,20 @@ func (i *IRacing) Subscribe(requestFields map[int16]telem.FieldID) { boundCheck[id] = true } + // Subscribe to whatever we need of virtual binds I guess - we need to ensure + // the virtual binds fields are being read + needsRPMColour := false + for _, id := range requestFields { + if id == telem.RPMStateColour { + needsRPMColour = true + } + } + + i.logger.Debug(fmt.Sprintf("Subscribing to virtual bind? %+v", needsRPMColour)) + if needsRPMColour { + i.logger.Debug("Subscribing to virtual bind") + i.data.VirtualBinds = append(i.data.VirtualBinds, telem.NewRPMLights()) + } + i.logger.Debug(fmt.Sprintf("Subscribed: %+v\n", i.data.ActiveBinds)) } diff --git a/telemetry/data.go b/telemetry/data.go index ae468c2..d2f233a 100644 --- a/telemetry/data.go +++ b/telemetry/data.go @@ -17,9 +17,11 @@ type FieldMapper struct { Transform func(any) uint64 } -// VirtualField will define data that is acquired through middleware -// So fuel per lap predictions and so on -type VirtualField struct{} +// VirtualField will derive data from telemetry primitives +// So fuel per lap predictions, compound gauge lights and so on +type VirtualField interface { + Process(td *TelemetryData) +} // NOTE: Update the iracing SDK to write data to the same map ALWAYS, then // I can bind that address and read directly from there on the transform @@ -164,6 +166,8 @@ const ( SessionTime ReplaySessionTime Empty + // Virtual Fields -- fields derived from primitive fields + RPMStateColour MaxFields ) const FirstField = Speed @@ -202,7 +206,9 @@ var FieldNames = [MaxFields]string{ // Session Data SessionTime: "SessionTime", ReplaySessionTime: "ReplaySessionTime", - Empty: "Emtpy", + // Virtual Fields + RPMStateColour: "RPM State Colour", + Empty: "Emtpy", } func GetFieldName(id FieldID) string { @@ -246,8 +252,14 @@ func (td *TelemetryData) Pack() []byte { bufPtr := bufferPool.Get().(*[]byte) buf := (*bufPtr)[:0] - for _, bind := range td.ActiveBinds { - buf = td.Values[bind.ID].Pack(buf) + // for _, bind := range td.ActiveBinds { + // buf = td.Values[bind.ID].Pack(buf) + // } + + for k := range td.Values { + if len(td.Values[k].IDs) > 0 { + buf = td.Values[k].Pack(buf) + } } // We have to copy here because we have to return the buffer diff --git a/telemetry/rpm_lights.go b/telemetry/rpm_lights.go new file mode 100644 index 0000000..8cc4bd1 --- /dev/null +++ b/telemetry/rpm_lights.go @@ -0,0 +1,26 @@ +package telemetry + +type RPMLights struct { + State string +} + +func NewRPMLights() *RPMLights { + return &RPMLights{ + State: "WHITE", + } +} + +func (rl *RPMLights) Process(td *TelemetryData) { + curRPM := td.Values[RPM].Raw + + td.Values[RPMStateColour].Type = DataTypeSTRING + if curRPM >= 2000 && curRPM < 4000 { + td.Values[RPMStateColour].Str = "GREEN" + } else if curRPM >= 4000 && curRPM < 6000 { + td.Values[RPMStateColour].Str = "YELLOW" + } else if curRPM >= 6000 { + td.Values[RPMStateColour].Str = "RED" + } else { + td.Values[RPMStateColour].Str = "WHITE" + } +}