add the identification ID for a telemetry field
we will use this so the serial device knows where to send the data
This commit is contained in:
@@ -121,12 +121,12 @@ func (i *IRacing) Stream() (<-chan telem.TelemetryData, error) {
|
||||
return i.streamCh, nil
|
||||
}
|
||||
|
||||
func (i *IRacing) Subscribe(requestFields []telem.FieldID) {
|
||||
func (i *IRacing) Subscribe(requestFields map[int16]telem.FieldID) {
|
||||
i.logger.Debug(fmt.Sprintf("Len Req: %d\n", len(requestFields)))
|
||||
|
||||
i.data.ActiveBinds = make([]telem.BoundField, 0, len(requestFields))
|
||||
|
||||
for _, id := range requestFields {
|
||||
for winID, id := range requestFields {
|
||||
// Translate the UI FieldIDs to this provider's field names
|
||||
sdkKey, ok := internalToSDKFieldNames[id]
|
||||
if !ok {
|
||||
@@ -178,6 +178,7 @@ func (i *IRacing) Subscribe(requestFields []telem.FieldID) {
|
||||
}
|
||||
}
|
||||
|
||||
i.data.Values[id].ID = winID
|
||||
i.data.ActiveBinds = append(i.data.ActiveBinds, binding)
|
||||
}
|
||||
|
||||
|
||||
+8
-4
@@ -47,6 +47,7 @@ const (
|
||||
// application.
|
||||
// From my testing, using an uint64 bucket is around 50x faster than any
|
||||
type TelemetryField struct {
|
||||
ID int16 // Identification: I have to learn how I will use this on other devices
|
||||
Type DataType
|
||||
Raw uint64
|
||||
Str string // Only to be used with DataTypeSTRING
|
||||
@@ -54,17 +55,20 @@ type TelemetryField struct {
|
||||
|
||||
// Pack will pack this current TelemetryField into bytes to send over the wire
|
||||
// Format:
|
||||
// 0x00 - DataType
|
||||
// 0x01 - if its a (u)int8
|
||||
// 0x00 - Field ID
|
||||
// 0x00 |
|
||||
// 0x01 - DataType
|
||||
// 0x02 - if its a (u)int8
|
||||
// or
|
||||
// 0x01 - if its a (u)int16 - first byte
|
||||
// 0x01 - if its a (u)int16 - second byte
|
||||
// 0x02 - if its a (u)int16 - first byte
|
||||
// 0x02 - if its a (u)int16 - second byte
|
||||
// or
|
||||
// 0x02 - str len max is 255 chars
|
||||
// [0x02] - str
|
||||
func (tf *TelemetryField) Pack(dest []byte) []byte {
|
||||
// NOTE: maybe we can have a pool of these so we don't have to create them here
|
||||
// or whatever
|
||||
dest = append(dest, uint8(tf.ID), uint8(tf.ID>>8))
|
||||
dest = append(dest, uint8(tf.Type))
|
||||
|
||||
switch tf.Type {
|
||||
|
||||
+15
-7
@@ -17,51 +17,57 @@ func Test_TelemetryField(t *testing.T) {
|
||||
{
|
||||
name: "test_max_uint8",
|
||||
tf: TelemetryField{
|
||||
ID: 0x01,
|
||||
Type: DataTypeUINT8,
|
||||
Raw: uint64(math.MaxUint8),
|
||||
},
|
||||
expect: []byte{0x00, 0xFF},
|
||||
expect: []byte{0x01, 0x00, 0x00, 0xFF},
|
||||
},
|
||||
{
|
||||
name: "test_max_int8",
|
||||
tf: TelemetryField{
|
||||
ID: 0x02,
|
||||
Type: DataTypeINT8,
|
||||
Raw: uint64(math.MaxInt8),
|
||||
},
|
||||
expect: []byte{0x01, 0x7F},
|
||||
expect: []byte{0x02, 0x00, 0x01, 0x7F},
|
||||
},
|
||||
{
|
||||
name: "test_max_uint16",
|
||||
tf: TelemetryField{
|
||||
ID: 0x03,
|
||||
Type: DataTypeUINT16,
|
||||
Raw: uint64(math.MaxUint16),
|
||||
},
|
||||
expect: []byte{0x02, 0xFF, 0xFF},
|
||||
expect: []byte{0x03, 0x00, 0x02, 0xFF, 0xFF},
|
||||
},
|
||||
{
|
||||
name: "test_max_int16",
|
||||
tf: TelemetryField{
|
||||
ID: 0x04,
|
||||
Type: DataTypeINT16,
|
||||
Raw: uint64(math.MaxInt16),
|
||||
},
|
||||
expect: []byte{0x03, 0xFF, 0x7F},
|
||||
expect: []byte{0x04, 0x00, 0x03, 0xFF, 0x7F},
|
||||
},
|
||||
{
|
||||
name: "test_string",
|
||||
tf: TelemetryField{
|
||||
ID: 0x05,
|
||||
Type: DataTypeSTRING,
|
||||
Str: "a cool string!",
|
||||
},
|
||||
expect: []byte{0x08, 0x0E, 0x61, 0x20, 0x63, 0x6F, 0x6F, 0x6C, 0x20, 0x73,
|
||||
expect: []byte{0x05, 0x00, 0x08, 0x0E, 0x61, 0x20, 0x63, 0x6F, 0x6F, 0x6C, 0x20, 0x73,
|
||||
0x74, 0x72, 0x69, 0x6E, 0x67, 0x21},
|
||||
},
|
||||
{
|
||||
name: "test_char",
|
||||
tf: TelemetryField{
|
||||
ID: 0x06,
|
||||
Type: DataTypeCHAR,
|
||||
Raw: uint64('R'),
|
||||
},
|
||||
expect: []byte{0x09, 0x52},
|
||||
expect: []byte{0x06, 0x00, 0x09, 0x52},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -92,16 +98,18 @@ func Test_TelemetryData(t *testing.T) {
|
||||
}
|
||||
|
||||
data.Values[Speed] = TelemetryField{
|
||||
ID: 0x01,
|
||||
Type: DataTypeUINT16,
|
||||
Raw: uint64(254),
|
||||
}
|
||||
|
||||
data.Values[Gear] = TelemetryField{
|
||||
ID: 0x02,
|
||||
Type: DataTypeCHAR,
|
||||
Raw: uint64('R'),
|
||||
}
|
||||
|
||||
expect := []byte{0x02, 0xFE, 0x00, 0x09, 0x52}
|
||||
expect := []byte{0x01, 0x00, 0x02, 0xFE, 0x00, 0x02, 0x00, 0x09, 0x52}
|
||||
|
||||
result := data.Pack()
|
||||
if !bytes.Equal(result, expect) {
|
||||
|
||||
@@ -3,5 +3,5 @@ package telemetry
|
||||
|
||||
type TelemetryProvider interface {
|
||||
Stream() (<-chan TelemetryData, error)
|
||||
Subscribe([]FieldID)
|
||||
Subscribe(map[int16]FieldID)
|
||||
}
|
||||
|
||||
@@ -89,12 +89,15 @@ func (sc *StreamingCtrl) Start() {
|
||||
// goes into the layout tool, sets up the data to transmit to his devices and
|
||||
// then comes here to stream that data. We call this to set the fields the user
|
||||
// has subscrived to in his tooling
|
||||
//
|
||||
// Performance reasoning: this is not used during the high frequency data transmission
|
||||
// so we can get away with using a map for convenience here
|
||||
func (sc *StreamingCtrl) SetInternalState() {
|
||||
// Get the subscribed fields
|
||||
fields := make([]telemetry.FieldID, 0, len(sc.Service.CDash.State.Layout.Windows))
|
||||
fields := make(map[int16]telemetry.FieldID, len(sc.Service.CDash.State.Layout.Windows))
|
||||
|
||||
for _, w := range sc.Service.CDash.State.Layout.Windows {
|
||||
fieldID, _ := telemetry.GetFieldID(w.UIData.TelemetryField)
|
||||
fields = append(fields, fieldID)
|
||||
fields[w.UIData.IDX] = fieldID
|
||||
}
|
||||
|
||||
sc.TelemServ.ActiveProvider.Subscribe(fields)
|
||||
|
||||
Reference in New Issue
Block a user