diff --git a/examples.go b/examples.go new file mode 100644 index 0000000..600c2a7 --- /dev/null +++ b/examples.go @@ -0,0 +1,69 @@ +package main + +import ( + "esdi/sources/beamng" + "fmt" + "log" + "strings" + "time" +) + +func beamngExample(esdi ESDI) { + bIF, err := beamng.Init("127.0.0.1", 4444) + if err != nil { + log.Fatalf("Failed to create BeamNG interface: %v", err) + } + + esdi.Source = &bIF + + lastTime := time.Now().UnixMilli() + lastDataSent := time.Now().UnixMilli() + for { + var err error + var buffer strings.Builder + buffer.WriteString("\033[?25l\033[2J\033[H") + + err = esdi.Source.UpdateData() + if err != nil { + fmt.Printf("could not update data: %v", err) + continue + } + + curGear, err := esdi.Source.GetData("Gear") + if err != nil { + log.Fatalf("could not get field `Gear`: %v", err) + } + + curRPM, err := esdi.Source.GetData("RPM") + if err != nil { + log.Fatalf("could not get field `RPM`: %v", err) + } + + gear := int(curGear.(int8)) + rpm := int(curRPM.(float32)) + + buffer.WriteString(fmt.Sprintf("Gear: %d, RPM: %d", gear, rpm)) + + curTime := time.Now().UnixMilli() + message := fmt.Sprintf("%d,%d\n", gear-1, rpm) + buffer.WriteString("\n" + message) + + messageWasSentMark := "N" + if curTime-lastDataSent > 75 { + _, err = esdi.SerialConn.Write([]byte(message)) + if err != nil { + log.Printf("Unable to write data: %v", err) + break + } + + messageWasSentMark = "Y" + lastDataSent = curTime + } + + buffer.WriteString(" -> " + messageWasSentMark) + if curTime-lastTime > 100 { + fmt.Print(buffer.String()) + lastTime = curTime + } + } +} diff --git a/go.mod b/go.mod index 211c595..0c4ccf7 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,15 @@ module esdi -go 1.22.0 +go 1.23.2 -require github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 +require ( + github.com/ESilva15/gobngsdk v0.0.1 + github.com/ESilva15/goirsdk v0.0.0-20241105180527-300c86190b42 + github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 +) -require golang.org/x/sys v0.26.0 // indirect - -require esilva.org.localhost/bngsdk v0.1.0 - -replace esilva.org.localhost/bngsdk => ../pkg/bngsdk +require ( + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum index 5f28ef9..a9e5697 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,16 @@ +github.com/ESilva15/gobngsdk v0.0.1 h1:EbzIp3pTycqOXbGEX8omhhyaR+N9vixQ8/xSXCbYplQ= +github.com/ESilva15/gobngsdk v0.0.1/go.mod h1:3BpgdToILwl+w3IjUJinK9AzYqUefnQBJbfYlR6Ibbk= +github.com/ESilva15/goirsdk v0.0.0-20241105180527-300c86190b42 h1:66k8QHzJWrC0Ke2OGQvjFkQUusGfASOsLzfOS0uHoII= +github.com/ESilva15/goirsdk v0.0.0-20241105180527-300c86190b42/go.mod h1:Vtqm7KbFJ4pjDSz2pUI4TaMWtnVQXn5m7Ee3vmo9yNc= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 6a85140..13dedc7 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,12 @@ package main import ( - "esdi/sources/beamng" + "bytes" + "encoding/binary" + "esdi/sources/iracing" "fmt" "log" + "os" "strings" "time" ) @@ -13,22 +16,46 @@ type GameSource interface { UpdateData() error } +type DataPacket struct { + Speed int32 + Gear int32 + RPM int32 +} + +func msToKph(v float32) int { + return int((3600 * v) / 1000) +} + func main() { - esdi, err := ESDIInit("COM10", 9600) + if len(os.Args) == 3 { + fmt.Printf("Port: %s\n", os.Args[1]) + fmt.Printf("File: %s\n", os.Args[2]) + } else { + log.Fatal("Wrong usage.") + } + + esdi, err := ESDIInit(os.Args[1], 115200) if err != nil { log.Fatalf("Failed to get Desktop Interface: %v", err) } - bIF, err := beamng.Init("127.0.0.1", 4444) + file, err := os.Open(os.Args[2]) if err != nil { - log.Fatalf("Failed to create BeamNG interface: %v", err) + log.Fatalf("Failed to open IBT file: %v", err) } - esdi.Source = &bIF + irsdk, err := iracing.Init(file) + if err != nil { + log.Fatalf("Failed to create iRacing interface: %v", err) + } + + esdi.Source = &irsdk lastTime := time.Now().UnixMilli() lastDataSent := time.Now().UnixMilli() for { + time.Sleep(time.Second / 60) + var err error var buffer strings.Builder buffer.WriteString("\033[?25l\033[2J\033[H") @@ -49,18 +76,33 @@ func main() { log.Fatalf("could not get field `RPM`: %v", err) } - gear := int(curGear.(int8)) - rpm := int(curRPM.(float32)) + curSpeed, err := esdi.Source.GetData("Speed") + if err != nil { + log.Fatalf("could not get field `Speed`: %v", err) + } - buffer.WriteString(fmt.Sprintf("Gear: %d, RPM: %d", gear, rpm)) + gear := int32(curGear.(int)) + rpm := int32(curRPM.(float32)) + speed := int32(msToKph(curSpeed.(float32))) + + buffer.WriteString(fmt.Sprintf("Gear: %d, RPM: %d, Speed: %d", gear, rpm, speed)) curTime := time.Now().UnixMilli() message := fmt.Sprintf("%d,%d\n", gear-1, rpm) buffer.WriteString("\n" + message) messageWasSentMark := "N" - if curTime-lastDataSent > 75 { - _, err = esdi.SerialConn.Write([]byte(message)) + if curTime-lastDataSent > 25 { + packet := DataPacket{ + Speed: speed, + Gear: gear, + RPM: rpm, + } + + var buf bytes.Buffer + err = binary.Write(&buf, binary.LittleEndian, packet) + + _, err = esdi.SerialConn.Write(buf.Bytes()) if err != nil { log.Printf("Unable to write data: %v", err) break diff --git a/sources/beamng/beamngSink.go b/sources/beamng/beamngSink.go index f31cf02..f47bce0 100644 --- a/sources/beamng/beamngSink.go +++ b/sources/beamng/beamngSink.go @@ -3,7 +3,7 @@ package beamng import ( "fmt" - "esilva.org.localhost/bngsdk" + "github.com/ESilva15/gobngsdk" ) // This will implement the GameSink interface from the main package diff --git a/sources/iracing/iracingSink.go b/sources/iracing/iracingSink.go index f26ff02..b955592 100644 --- a/sources/iracing/iracingSink.go +++ b/sources/iracing/iracingSink.go @@ -1,33 +1,41 @@ package iracing import ( - "esilva.org.localhost/bngsdk" + "fmt" + "time" + + "github.com/ESilva15/goirsdk" ) // This will implement the GameSink interface from the main package -type BeamNG struct { - SDK *bngsdk.BNGSDK +type IRacing struct { + SDK *goirsdk.IBT } const ( NAME = "iRacing" ) -func Init(ip string, port int) (BeamNG, error) { +func Init(f goirsdk.Reader) (IRacing, error) { var err error - sdk, err := bngsdk.Init(ip, port) + sdk, err := goirsdk.Init(f) if err != nil { - return BeamNG{}, err + return IRacing{}, err } - return BeamNG{SDK: &sdk}, nil + return IRacing{SDK: sdk}, nil } -func (b *BeamNG) GetData(fieldName string, out interface{}) error { - return nil +func (i *IRacing) GetData(fieldName string) (interface{}, error) { + if val, ok := i.SDK.Vars.Vars[fieldName]; ok { + return val.Value, nil + } + + return nil, fmt.Errorf("key `%s` doesn't exist", fieldName) } -func (b *BeamNG) UpdateData() error { - return b.SDK.ReadData() +func (i *IRacing) UpdateData() error { + _, err := i.SDK.Update(100 * time.Millisecond) + return err }