Added fields for the BeamNG provider and am working on some changes for the telem

I need to simplify the way telemetry is fetched and updated on the app
side.
Reduce the use of any for example and so on
This commit is contained in:
2026-07-06 23:31:41 +01:00
parent 8def8cac68
commit 16e6a336b0
5 changed files with 449 additions and 173 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
github.com/ESilva15/ESgoRepl v0.1.0 h1:hOVcRBfdP8Yw1kLr2tFoM3SetV7vxFswKjzfAtq8UgM=
github.com/ESilva15/ESgoRepl v0.1.0/go.mod h1:O2JQMyEgHy0zf9UvzvLNvp2w95T2uazc3torrzRmG9Y=
github.com/ESilva15/gobngsdk v0.0.2 h1:N6stNOE14Wg80BAZMFu/Qd9Qa/J0DmExCfdPoDf7lco=
github.com/ESilva15/gobngsdk v0.0.2/go.mod h1:cKLaZRgM0tGGXDvosaSjHnxeyC5Y6rg7zCLqEUJnOzw=
github.com/ESilva15/gobngsdk v1.1.3 h1:CFaz2KjHKnBLrQuEN1QHOd1761cWM/rmTwLpSLrgbe4=
github.com/ESilva15/gobngsdk v1.1.3/go.mod h1:cKLaZRgM0tGGXDvosaSjHnxeyC5Y6rg7zCLqEUJnOzw=
github.com/ESilva15/goirsdk v0.2.11 h1:C/HuO9xGmRJ01vMR0KRjrhcMEfq1Mea1rQK0CICaOU4=
github.com/ESilva15/goirsdk v0.2.11/go.mod h1:5borQbw+L4fe9b58JFHRHZwrzz0sMVAteuYbRnFOc0Q=
github.com/arl/statsviz v0.8.0 h1:O6GjjVxEDxcByAucOSl29HaGYLXsuwA3ujJw8H9E7/U=
+232 -88
View File
@@ -1,5 +1,53 @@
Windows:
1:
uiwindow:
Dims:
X0: 170
Y0: 136
Width: 40
Height: 55
Decor:
BGColour: 4161
FGColour: 65535
TitleColour: 65535
BorderColour: 63488
TitleSize: 2
TextSize: 4
HasBorder: 1
Padding: 0
Opts:
ShowID: 0
WinType: 2
PreviewValue: '>'
Title: ->
uidata:
WID: 1
TelemetryField: Right Indicator
2:
uiwindow:
Dims:
X0: 341
Y0: 417
Width: 40
Height: 55
Decor:
BGColour: 4161
FGColour: 65535
TitleColour: 65535
BorderColour: 63488
TitleSize: 2
TextSize: 4
HasBorder: 1
Padding: 0
Opts:
ShowID: 0
WinType: 2
PreviewValue: A
Title: ABS
uidata:
WID: 2
TelemetryField: ABS Dash Light
3:
uiwindow:
Dims:
X0: 470
@@ -21,81 +69,9 @@ Windows:
PreviewValue: "9999"
Title: Dig Tacho
uidata:
WID: 2
WID: 3
TelemetryField: RPM
4:
uiwindow:
Dims:
X0: 321
Y0: 195
Width: 134
Height: 80
Decor:
BGColour: 4161
FGColour: 65535
TitleColour: 65535
BorderColour: 63488
TitleSize: 2
TextSize: 7
HasBorder: 1
Padding: 0
Opts:
ShowID: 0
WinType: 2
PreviewValue: "234"
Title: SPEEDO
uidata:
WID: 4
TelemetryField: Speed
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
10:
uiwindow:
Dims:
X0: 470
Y0: 132
Width: 169
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: "123.4"
Title: Fuel Level
uidata:
WID: 10
TelemetryField: Fuel Level
11:
uiwindow:
Dims:
X0: 321
@@ -117,33 +93,33 @@ Windows:
PreviewValue: R
Title: Box
uidata:
WID: 11
WID: 4
TelemetryField: Gear
16:
5:
uiwindow:
Dims:
X0: 694
Y0: 423
Width: 100
Height: 50
X0: 80
Y0: 136
Width: 40
Height: 55
Decor:
BGColour: 4161
FGColour: 65535
TitleColour: 65535
BorderColour: 63488
TitleSize: 2
TextSize: 3
TextSize: 4
HasBorder: 1
Padding: 0
Opts:
ShowID: 0
WinType: 2
PreviewValue: "4.56"
Title: Oil P
PreviewValue: <
Title: <-
uidata:
WID: 16
TelemetryField: Oil Pressure
17:
WID: 5
TelemetryField: Left Indicator
6:
uiwindow:
Dims:
X0: 694
@@ -165,9 +141,177 @@ Windows:
PreviewValue: "101.4"
Title: Oil T
uidata:
WID: 17
WID: 6
TelemetryField: Oil Temperature
20:
7:
uiwindow:
Dims:
X0: 386
Y0: 417
Width: 40
Height: 55
Decor:
BGColour: 4161
FGColour: 65535
TitleColour: 65535
BorderColour: 63488
TitleSize: 2
TextSize: 4
HasBorder: 1
Padding: 0
Opts:
ShowID: 0
WinType: 2
PreviewValue: T
Title: TC
uidata:
WID: 7
TelemetryField: Traction Control Light
8:
uiwindow:
Dims:
X0: 431
Y0: 417
Width: 40
Height: 55
Decor:
BGColour: 4161
FGColour: 65535
TitleColour: 65535
BorderColour: 63488
TitleSize: 2
TextSize: 4
HasBorder: 1
Padding: 0
Opts:
ShowID: 0
WinType: 2
PreviewValue: B
Title: Bat
uidata:
WID: 8
TelemetryField: Battery Light
9:
uiwindow:
Dims:
X0: 321
Y0: 195
Width: 134
Height: 80
Decor:
BGColour: 4161
FGColour: 65535
TitleColour: 65535
BorderColour: 63488
TitleSize: 2
TextSize: 7
HasBorder: 1
Padding: 0
Opts:
ShowID: 0
WinType: 2
PreviewValue: "234"
Title: SPEEDO
uidata:
WID: 9
TelemetryField: Speed
10:
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: 10
TelemetryField: Water Temperature
11:
uiwindow:
Dims:
X0: 470
Y0: 132
Width: 169
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: "123.4"
Title: Fuel Level
uidata:
WID: 11
TelemetryField: Fuel Level
12:
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: 12
TelemetryField: Oil Pressure
13:
uiwindow:
Dims:
X0: 296
Y0: 417
Width: 40
Height: 55
Decor:
BGColour: 4161
FGColour: 65535
TitleColour: 65535
BorderColour: 63488
TitleSize: 2
TextSize: 4
HasBorder: 1
Padding: 0
Opts:
ShowID: 0
WinType: 2
PreviewValue: P
Title: HB
uidata:
WID: 13
TelemetryField: Parking Brake Dash Light
14:
uiwindow:
Dims:
X0: 142
@@ -189,5 +333,5 @@ Windows:
PreviewValue: "5678"
Title: TACHO
uidata:
WID: 20
WID: 14
TelemetryField: RPM
+153 -42
View File
@@ -5,7 +5,6 @@ import (
"context"
"fmt"
"log/slog"
"strconv"
"sync"
"time"
@@ -16,7 +15,7 @@ import (
)
type BeamNG struct {
SDK *bngsdk.BNGSDK
SDK *bngsdk.BeamNGSDK
// data handling
mut sync.Mutex
@@ -67,6 +66,7 @@ func (b *BeamNG) Stream() (<-chan telemetry.TelemetryData, error) {
}
func (b *BeamNG) Subscribe(requestFields map[int16]telemetry.FieldID) {
// NOTE: document how the Subscribe funtion works
slog.Debug(fmt.Sprintf("Len Req: %d\n", len(requestFields)))
b.data.ActiveBinds = make([]telemetry.BoundField, 0, len(requestFields))
@@ -99,74 +99,187 @@ func (b *BeamNG) Subscribe(requestFields map[int16]telemetry.FieldID) {
continue
}
// Translate the UI FieldIDs to this provider's field names
sdkKey, ok := internalToSDKFieldNames[id]
if !ok {
slog.Debug("failed to get internal id")
// Need to find a way to pass a message saying something wasn't right
continue
}
binding := telemetry.BoundField{
Key: sdkKey,
ID: id,
ID: id,
}
switch id {
case telemetry.Speed:
binding.Fetch = func() any {
return b.SDK.Data.Speed
}
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeUINT16
out.Raw = uint64(conv.MsToKph(v.(float32)))
}
case telemetry.Gear:
binding.Fetch = func() any {
return b.SDK.Data.Gear
}
binding.Transform = GearTransform
case telemetry.RPM:
binding.Fetch = func() any {
return b.SDK.Data.RPM
}
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeUINT16
out.Raw = uint64(uint16(v.(float32)))
}
case telemetry.FuelLevel:
binding.Fetch = func() any {
return b.SDK.Data.Fuel
}
binding.Transform = telemetry.FloatToStringTransform
// Engine Data
case telemetry.OilPress:
binding.Fetch = func() any {
return b.SDK.Data.OilPressure
}
binding.Transform = telemetry.FloatToStringTransform
case telemetry.OilTemp:
binding.Fetch = func() any {
return b.SDK.Data.OilTemp
}
binding.Transform = telemetry.FloatToStringTransform
case telemetry.WaterTemp:
binding.Fetch = func() any {
return b.SDK.Data.EngTemp
}
binding.Transform = telemetry.FloatToStringTransform
// Something else
case telemetry.PitSpeedLimiter:
binding.Fetch = func() any {
return b.SDK.Pitspeed()
}
binding.Transform = PitSpeedLimiterTransform
// Electrics (dash lights and so on)
case telemetry.LeftIndicator:
binding.Fetch = func() any {
return b.SDK.LeftIndicator()
}
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeCHAR
chr := ' '
if r, ok := v.(bool); ok {
if r {
chr = '<'
}
}
out.Raw = uint64(chr)
}
case telemetry.RightIndicator:
binding.Fetch = func() any {
return b.SDK.RightIndicator()
}
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeCHAR
chr := ' '
if r, ok := v.(bool); ok {
if r {
chr = '>'
}
}
out.Raw = uint64(chr)
}
case telemetry.ABSWarningLight:
binding.Fetch = func() any {
return b.SDK.ABS()
}
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeCHAR
chr := ' '
if r, ok := v.(bool); ok {
if r {
chr = 'A'
}
}
out.Raw = uint64(chr)
}
case telemetry.ParkingBrakeLight:
binding.Fetch = func() any {
return b.SDK.Handbrake()
}
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeCHAR
chr := ' '
if r, ok := v.(bool); ok {
if r {
chr = 'P'
}
}
out.Raw = uint64(chr)
}
case telemetry.TCLight:
binding.Fetch = func() any {
return b.SDK.TractionControl()
}
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeCHAR
chr := ' '
if r, ok := v.(bool); ok {
if r {
chr = 'T'
}
}
out.Raw = uint64(chr)
}
case telemetry.BatteryLight:
binding.Fetch = func() any {
return b.SDK.BatteryLight()
}
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeCHAR
chr := ' '
if r, ok := v.(bool); ok {
if r {
chr = 'B'
}
}
out.Raw = uint64(chr)
}
// Adjustements
case telemetry.BrakeBias:
binding.Transform = telemetry.FloatToStringTransform
case telemetry.ABSSetting:
binding.Transform = telemetry.FloatToUInt8Transform
case telemetry.TCSetting:
binding.Transform = telemetry.FloatToUInt8Transform
case telemetry.ThrottleSetting:
binding.Transform = telemetry.FloatToUInt8Transform
case telemetry.LFtempM:
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeSTRING
out.Str = strconv.FormatFloat(float64(v.(float32)), 'f', 1, 32)
}
case telemetry.SessionTime:
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeSTRING
out.Str = strconv.FormatFloat(v.(float64), 'f', 1, 32)
}
case telemetry.ReplaySessionTime:
binding.Transform = func(v any, out *telemetry.TelemetryField) {
out.Type = telemetry.DataTypeSTRING
out.Str = strconv.FormatFloat(v.(float64), 'f', 1, 32)
}
// case telemetry.BrakeBias:
// binding.Transform = telemetry.FloatToStringTransform
// case telemetry.ABSSetting:
// binding.Transform = telemetry.FloatToUInt8Transform
// case telemetry.TCSetting:
// binding.Transform = telemetry.FloatToUInt8Transform
// case telemetry.ThrottleSetting:
// binding.Transform = telemetry.FloatToUInt8Transform
// case telemetry.LFtempM:
// binding.Transform = func(v any, out *telemetry.TelemetryField) {
// out.Type = telemetry.DataTypeSTRING
// out.Str = strconv.FormatFloat(float64(v.(float32)), 'f', 1, 32)
// }
// case telemetry.SessionTime:
// binding.Transform = func(v any, out *telemetry.TelemetryField) {
// out.Type = telemetry.DataTypeSTRING
// out.Str = strconv.FormatFloat(v.(float64), 'f', 1, 32)
// }
// case telemetry.ReplaySessionTime:
// binding.Transform = func(v any, out *telemetry.TelemetryField) {
// out.Type = telemetry.DataTypeSTRING
// out.Str = strconv.FormatFloat(v.(float64), 'f', 1, 32)
// }
case telemetry.Empty:
binding.Transform = telemetry.EmptyTransform
case telemetry.LapLastLapTime:
binding.Transform = LapTimeTransform
case telemetry.LapNumber:
binding.Transform = telemetry.UInt8Transform
// case telemetry.LapLastLapTime:
// binding.Transform = LapTimeTransform
// case telemetry.LapNumber:
// binding.Transform = telemetry.UInt8Transform
}
b.data.ActiveBinds = append(b.data.ActiveBinds, binding)
@@ -194,9 +307,7 @@ func (b *BeamNG) readData() {
// Read 1 to 1 data
slog.Debug("Reading normal data binds")
for _, bind := range b.data.ActiveBinds {
v := b.SDK.DataDict[bind.Key]
bind.Transform(v, &b.data.Values[bind.ID])
bind.Transform(bind.Fetch(), &b.data.Values[bind.ID])
}
// Set up virtual binds
+41 -41
View File
@@ -2,44 +2,44 @@ package beamng
// This file maps the data from the desktop provider data structure to iRacing
import (
"esdi/telemetry"
)
var internalToSDKFieldNames = map[telemetry.FieldID]string{
telemetry.Speed: "Speed",
telemetry.Gear: "Gear",
telemetry.RPM: "RPM",
telemetry.FuelLevel: "Fuel",
// Engine Data
telemetry.OilPress: "OilPressure",
telemetry.OilTemp: "OilTemp",
telemetry.WaterTemp: "EngTemp",
// Engine Warnings
telemetry.PitSpeedLimiter: "irsdk_pitSpeedLimiter",
// Ajudstements
telemetry.BrakeBias: "dcBrakeBias",
telemetry.ABSSetting: "dcABS",
telemetry.TCSetting: "dcTractionControl",
telemetry.ThrottleSetting: "dcThrottleShape",
// Lap Data
telemetry.LapLastLapTime: "LapLastLapTime",
telemetry.LapNumber: "Lap",
// Tire data
telemetry.LFtempL: "LFtempCL",
telemetry.LFtempM: "LFtempCM",
telemetry.LFtempR: "LFtempCR",
telemetry.RFtempL: "RFtempCL",
telemetry.RFtempM: "RFtempCM",
telemetry.RFtempR: "RFtempCR",
telemetry.LRtempL: "LRtempCL",
telemetry.LRtempM: "LRtempCM",
telemetry.LRtempR: "LRtempCR",
telemetry.RRtempL: "RRtempCL",
telemetry.RRtempM: "RRtempCM",
telemetry.RRtempR: "RRtempCR",
// Session Data
telemetry.SessionTime: "SessionTime",
telemetry.ReplaySessionTime: "ReplaySessionTime",
telemetry.Empty: "empty",
}
// var internalToSDKFieldNames = map[telemetry.FieldID]string{
// telemetry.Speed: "Speed",
// telemetry.Gear: "Gear",
// telemetry.RPM: "RPM",
// telemetry.FuelLevel: "Fuel",
// // Engine Data
// telemetry.OilPress: "OilPressure",
// telemetry.OilTemp: "OilTemp",
// telemetry.WaterTemp: "EngTemp",
// // Engine Warnings
// telemetry.PitSpeedLimiter: "irsdk_pitSpeedLimiter",
// // Electrics (dash lights and so on)
// telemetry.LeftIndicator: "sssssssss",
// telemetry.RightIndicator: "something",
// telemetry.Hazards: "something",
// // Ajudstements
// telemetry.BrakeBias: "dcBrakeBias",
// telemetry.ABSSetting: "dcABS",
// telemetry.TCSetting: "dcTractionControl",
// telemetry.ThrottleSetting: "dcThrottleShape",
// // Lap Data
// telemetry.LapLastLapTime: "LapLastLapTime",
// telemetry.LapNumber: "Lap",
// // Tire data
// telemetry.LFtempL: "LFtempCL",
// telemetry.LFtempM: "LFtempCM",
// telemetry.LFtempR: "LFtempCR",
// telemetry.RFtempL: "RFtempCL",
// telemetry.RFtempM: "RFtempCM",
// telemetry.RFtempR: "RFtempCR",
// telemetry.LRtempL: "LRtempCL",
// telemetry.LRtempM: "LRtempCM",
// telemetry.LRtempR: "LRtempCR",
// telemetry.RRtempL: "RRtempCL",
// telemetry.RRtempM: "RRtempCM",
// telemetry.RRtempR: "RRtempCR",
// // Session Data
// telemetry.SessionTime: "SessionTime",
// telemetry.ReplaySessionTime: "ReplaySessionTime",
// telemetry.Empty: "empty",
// }
+21
View File
@@ -27,9 +27,14 @@ type VirtualField interface {
// 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
// BoundField is the data structure we use to bind the telemetry provider's data
// to our internal telemetry fields
// NOTE: we must deprecate the `Key` member. We used it to map the internal
// telemetry fields to the providers name. But we shouldn't be using `string` keys.
type BoundField struct {
Key string
ID FieldID
Fetch func() any
Transform func(any, *TelemetryField)
}
@@ -143,6 +148,14 @@ const (
WaterTemp
// Engine Warnings
PitSpeedLimiter
// Electrics (dash lights and so on)
LeftIndicator
RightIndicator
Hazards
ABSWarningLight
ParkingBrakeLight
TCLight
BatteryLight
// Adjustements
BrakeBias
ABSSetting
@@ -191,6 +204,14 @@ var FieldNames = [MaxFields]string{
WaterTemp: "Water Temperature",
// Engine Warnings
PitSpeedLimiter: "Pit Speed Limiter",
// Electrics (dash lights and so on)
LeftIndicator: "Left Indicator",
RightIndicator: "Right Indicator",
Hazards: "Hazards",
ABSWarningLight: "ABS Dash Light",
ParkingBrakeLight: "Parking Brake Dash Light",
TCLight: "Traction Control Light",
BatteryLight: "Battery Light",
// Ajustments
BrakeBias: "BrakeBias",
ABSSetting: "ABS Control",