package main import ( "bytes" "encoding/base64" "encoding/binary" "errors" "math" "strings" "github.com/johnjones4/model-rocket-telemetry/dashboard/core" ) func telemetryFloatFromByteIndex(bytes []byte, index int) float64 { start := 8 * index end := start + 8 if start >= len(bytes) || end >= len(bytes) { return 0 } bits := binary.LittleEndian.Uint64(bytes[start:end]) float := math.Float64frombits(bits) return float } func telemetryIntFromBytes(b []byte) int16 { buffer := bytes.NewReader(b) if len(b) != 2 { return 0 } var val int16 binary.Read(buffer, binary.LittleEndian, &val) return val } func decodeTelemetryBytes(bytes []byte) ([]byte, []byte, error) { parts := strings.Split(string(bytes), ",") if len(parts) != 3 || parts[0] != "T" { return nil, nil, errors.New(string(bytes)) } telemetryBytes, err := base64.StdEncoding.DecodeString(parts[1]) if err != nil { return nil, nil, err } rssiBytes, err := base64.StdEncoding.DecodeString(parts[2]) if err != nil { return nil, nil, err } return telemetryBytes, rssiBytes, nil } func bytesToDataSegment(stream core.FlightData, bytes []byte) ([]core.DataSegment, float64, core.Coordinate, error) { telemetryBytes, rssiBytes, err := decodeTelemetryBytes(bytes) if err != nil { return nil, 0, core.Coordinate{}, err } segments := make([]core.DataSegment, PointsPerDataFrame) var basePressure float64 var origin core.Coordinate for i := len(segments) - 1; i >= 0; i-- { offset := (i * 10) raw := core.RawDataSegment{ FlightTime: telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexFlightTime), FlightPhase: telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexFightPhase), Altitude: telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexAltitude), Velocity: telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexVelocity), Acceleration: telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexAcceleration), Temperature: telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexTemperature), Coordinate: core.Coordinate{ telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexCoordinateLat), telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexCoordinateLon), }, GPSInfo: core.GPSInfo{ telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexGpsQuality), telemetryFloatFromByteIndex(telemetryBytes, offset+core.IndexGpsSats), }, Rssi: telemetryIntFromBytes(rssiBytes), } var computed core.ComputedDataSegment computed, basePressure, origin = core.ComputeDataSegment(stream, raw) segments[i] = core.DataSegment{ raw, computed, } } return segments, basePressure, origin, nil }