diff --git a/go.sum b/go.sum index b7ac7ad..f74517d 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/layouts/beamng.yaml b/layouts/beamng.yaml index 03f7d05..38d9ffa 100755 --- a/layouts/beamng.yaml +++ b/layouts/beamng.yaml @@ -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 diff --git a/providers/beamng/beamng.go b/providers/beamng/beamng.go index 52b1286..e488c51 100644 --- a/providers/beamng/beamng.go +++ b/providers/beamng/beamng.go @@ -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 diff --git a/providers/beamng/fieldMapping.go b/providers/beamng/fieldMapping.go index a1de681..ce0cae2 100644 --- a/providers/beamng/fieldMapping.go +++ b/providers/beamng/fieldMapping.go @@ -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", +// } diff --git a/telemetry/data.go b/telemetry/data.go index 16648c7..f2229af 100644 --- a/telemetry/data.go +++ b/telemetry/data.go @@ -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",