Docstrings and documentation

This commit is contained in:
2025-01-14 14:29:46 +00:00
parent 6b595fabb1
commit 90a0321e9f
4 changed files with 190 additions and 17 deletions
+107 -8
View File
@@ -1,14 +1,113 @@
# TODO
- [x] Read live telemetry (from a live session or replay)
- [x] Read data from a stored `.ibt` file
- [x] Allow to export the data to an `.ibt` file
- [x] Allow to export the session info data to a `.yaml` file
- [ ] Add the message broadcasting system
- [ ] Explore a more convenient API for fetching the data for the SDK user
- [ ] Change the pattern in which the data is fetched from the telemetry and
how it is exported into `.ibt` files
# About
This project will be able to parse `.ibt` files, read live data from races and
broadcast messages to the service. Its still not very mature at all, but after
this commit I will turn it into a package instead and give it a stable API.
Will also put some examples then.
This project is a simple Go SDK for the popular iRacing racing simulator.
It has the capabilites to:
- Read live data (live session or replay)
- Read data from a `.ibt` telemetry file
It should run on Linux, MacOS and Windows. With the caveat that live sessions
only happen on Windows (that I know about), therefore Linux and MacOS can only
read data from telemetry files.
## The SDK
I used various sources to develop and understand how `iRacing` works, and learn
a lot with it. Once I have matured this project a bit I will document its
inner workings too.
## Usage
The SDK instance is created by calling `goirsdk.Init(Reader, exportTelem, exportYAML)`
- `Reader` is a variable that implements the interface:
```go
type Reader interface {
io.Reader
io.ReaderAt
io.ReadCloser
}
```
To read data from a `.ibt` file, the user should pass the `*os.File` of it, and
to read live telemetry the user should pass nil
- `exportTelem` should be an empty string if the user doesn't want to export
the data, otherwise pass a string with the path for the destination telemetry
file
- `exportYAML` is just like the exportTelem but for the session info `yaml` data
### Example
```go
package main
import (
"fmt"
"log"
"os"
"time"
"github.com/ESilva15/goirsdk"
)
func msToKph(v float32) int {
return int((3600 * v) / 1000)
}
func main() {
// Open the data source file
file, err := os.Open("/path/to/ibtFile")
if err != nil {
log.Fatalf("Failed to open IBT file: %v", err)
}
// Instantiate our iRacing SDK instance
irsdk, err := goirsdk.Init(file, "", "")
if err != nil {
log.Fatalf("Failed to create iRacing interface: %v", err)
}
defer irsdk.Close()
// Set up a loop to iterate our data
mainLoopTicker := time.NewTicker(time.Second / 60)
defer mainLoopTicker.Stop()
for {
// Update the data that the SDK is holding with the next tick
_, err := irsdk.Update(100 * time.Millisecond)
if err != nil {
log.Printf("could not update data: %v", err)
continue
}
// Vehicle Movement data gathered from the names we can find on the
// telemetry_docs.pdf file
// - I wish to make this less verbose if possible
if _, ok := irsdk.Vars.Vars["Gear"]; !ok {
log.Fatal("Field `Gear` doesn't exist")
}
if _, ok := irsdk.Vars.Vars["RPM"]; !ok {
log.Fatal("Field `RPM` doesn't exist")
}
if _, ok := irsdk.Vars.Vars["Speed"]; !ok {
log.Fatal("Field `Speed` doesn't exist")
}
gear := int32(irsdk.Vars.Vars["Gear"].Value.(int))
rpm := int32(irsdk.Vars.Vars["RPM"].Value.(float32))
speed := int32(msToKph(irsdk.Vars.Vars["Speed"].Value.(float32)))
fmt.Printf("\033[?25l\033[2J\033[H")
fmt.Printf("Gear: %d, RPM: %d, Speed: %d", gear, rpm, speed)
<-mainLoopTicker.C
}
}
```
## SharedMem
+67
View File
@@ -0,0 +1,67 @@
package main
import (
"fmt"
"log"
"os"
"time"
"github.com/ESilva15/goirsdk"
)
func msToKph(v float32) int {
return int((3600 * v) / 1000)
}
func main() {
// Open the data source file
file, err := os.Open("/path/to/ibtFile")
if err != nil {
log.Fatalf("Failed to open IBT file: %v", err)
}
// Instantiate our iRacing SDK instance
irsdk, err := goirsdk.Init(file, "", "")
if err != nil {
log.Fatalf("Failed to create iRacing interface: %v", err)
}
defer irsdk.Close()
// Set up a loop to iterate our data
mainLoopTicker := time.NewTicker(time.Second / 60)
defer mainLoopTicker.Stop()
for {
// Update the data that the SDK is holding with the next tick
_, err := irsdk.Update(100 * time.Millisecond)
if err != nil {
log.Printf("could not update data: %v", err)
continue
}
// Vehicle Movement data gathered from the names we can find on the
// telemetry_docs.pdf file
// - I wish to make this less verbose if possible
if _, ok := irsdk.Vars.Vars["Gear"]; !ok {
log.Fatal("Field `Gear` doesn't exist")
}
if _, ok := irsdk.Vars.Vars["RPM"]; !ok {
log.Fatal("Field `RPM` doesn't exist")
}
if _, ok := irsdk.Vars.Vars["Speed"]; !ok {
log.Fatal("Field `Speed` doesn't exist")
}
gear := int32(irsdk.Vars.Vars["Gear"].Value.(int))
rpm := int32(irsdk.Vars.Vars["RPM"].Value.(float32))
speed := int32(msToKph(irsdk.Vars.Vars["Speed"].Value.(float32)))
fmt.Printf("\033[?25l\033[2J\033[H")
fmt.Printf("Gear: %d, RPM: %d, Speed: %d", gear, rpm, speed)
<-mainLoopTicker.C
}
}
+14 -9
View File
@@ -2,8 +2,6 @@
package goirsdk
import (
// "github.com/ESilva15/goirsdk/logger"
"fmt"
"os"
@@ -79,21 +77,27 @@ func (i *IBT) exportYAML() error {
}
func (i *IBT) exportIBT(data []byte, offset int64) error {
log := logger.GetInstance()
log := logger.GetInstance()
_, err := i.IBTExport.WriteAt(data, offset)
if err != nil {
i.IBTExport.Close()
i.IBTExport = nil
log.Println("Won't attempt to export anymore")
return err
}
if err != nil {
i.IBTExport.Close()
i.IBTExport = nil
log.Println("Won't attempt to export anymore")
return err
}
return nil
}
// Init serves to initialize and get a hold of a IBT struct
// f -> is the source data, pass nil for the SDK to read live data or a
// *os.File to read from a file
// exportTelem -> is a string with the path to export the telemetry data, pass
// an empty string to not export any data
// exportTelem -> is a string with the path to export the session info data, pass
// an empty string to not export any data
func Init(f Reader, exportTelem string, exportYAML string) (*IBT, error) {
// log := logger.GetInstance()
@@ -172,6 +176,7 @@ func Init(f Reader, exportTelem string, exportYAML string) (*IBT, error) {
return &ibt, nil
}
// Close cleans up our irsdk instance
func (i *IBT) Close() {
if i.winUtils != nil {
// If its not live data, the user is the one with ownership of the handle
+2
View File
@@ -167,6 +167,8 @@ func (i *IBT) readData(buf []byte) error {
return nil
}
// Update will read the next data chunk from the telemetry data, works for both the
// live and offline data
func (i *IBT) Update(timeout time.Duration) (IRacingState, error) {
if i.winUtils != nil {
// Put a way to check if the sim is active here