Skip to content

Commit

Permalink
fix floats reported in scientific notation
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickdemers6 committed Oct 28, 2024
1 parent 32bac78 commit d41976f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
18 changes: 18 additions & 0 deletions telemetry/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package telemetry

import (
"fmt"
"regexp"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -36,6 +38,7 @@ var (
return &protos.Payload{}
},
}
scientificNotationFloatRegex = regexp.MustCompile("^[+-]?(\\d*\\.\\d+|\\d+\\.\\d*)([eE][+-]?\\d+)$")
)

// Record is a structs that represents the telemetry records vehicles send to the backend
Expand Down Expand Up @@ -170,6 +173,7 @@ func (record *Record) applyProtoRecordTransforms() error {
}
message.Vin = record.Vin
transformLocation(message)
transformScientificNotation(message)
record.PayloadBytes, err = proto.Marshal(message)
return err
default:
Expand Down Expand Up @@ -226,6 +230,20 @@ func transformLocation(message *protos.Payload) {
}
}

// transformScientificNotation fixes floating point values which are represented in scientific notation
// example: 1e-3 => 0.001
func transformScientificNotation(message *protos.Payload) {
for _, datum := range message.Data {
if strVal := datum.GetValue().GetStringValue(); strVal != "" {
if scientificNotationFloatRegex.MatchString(strVal) {
if floatVal, err := strconv.ParseFloat(strVal, 32); err == nil {
datum.Value = &protos.Value{Value: &protos.Value_StringValue{StringValue: fmt.Sprintf("%.5f", floatVal)}}
}
}
}
}
}

// ParseLocation parses a location string (such as "(37.412374 N, 122.145867 W)") into a *proto.Location type.
func ParseLocation(s string) (*protos.LocationValue, error) {
var lat, lon float64
Expand Down
36 changes: 36 additions & 0 deletions telemetry/record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,42 @@ var _ = Describe("Socket handler test", func() {
Expect(second.Key).To(Equal(protos.Field_VehicleName))
})

DescribeTable("number formatting fixes",
func(in string, expected string) {
brakePedalPos := stringDatum(protos.Field_BrakePedalPos, in)

message := messages.StreamMessage{TXID: []byte("1234"), SenderID: []byte("vehicle_device.42"), MessageTopic: []byte("V"), Payload: generatePayload("cybertruck", "42", nil, brakePedalPos)}
recordMsg, err := message.ToBytes()
Expect(err).NotTo(HaveOccurred())

record, err := telemetry.NewRecord(serializer, recordMsg, "1", false)
Expect(err).NotTo(HaveOccurred())
Expect(record).NotTo(BeNil())

data := &protos.Payload{}
err = proto.Unmarshal(record.Payload(), data)
Expect(err).NotTo(HaveOccurred())
Expect(data.Data).To(HaveLen(2))

// Give some predictability to the test
sort.Slice(data.Data, func(i, j int) bool {
return data.Data[i].Key < data.Data[j].Key
})

first := data.Data[0]
Expect(first.Key).To(Equal(protos.Field_VehicleName))

second := data.Data[1]
Expect(second.Key).To(Equal(protos.Field_BrakePedalPos))
Expect(second.Value.GetStringValue()).To(Equal(expected))
},
Entry("scientific notation is reported as regular float", "1.1920928955078125e-05", "0.00001"),
Entry("scientific notation close to zero turns to zero", "1.23e-9", "0.00000"),
Entry("long floats are not modified", "0.00000012", "0.00000012"),
Entry("regular floats are not modified", "0.03", "0.03"),
Entry("integers are not modified", "3", "3"),
)

DescribeTable("handleAlerts",
func(payloadTimestamp *timestamppb.Timestamp, expectedTimestamp *timestamppb.Timestamp, isActive bool) {
alert := &protos.VehicleAlert{
Expand Down

0 comments on commit d41976f

Please sign in to comment.