diff --git a/src/index.js b/src/index.js index 44d6232..c705473 100644 --- a/src/index.js +++ b/src/index.js @@ -6,44 +6,42 @@ module.exports = async function (context, req) { throw new Error('No file uploaded.') } - // Convert the raw body to a Buffer if it's a string const rawData = typeof req.rawBody === 'string' ? Buffer.from(req.rawBody, 'binary') : req.rawBody - console.log('Type of rawData:', typeof rawData) // Log the type of rawData for debugging + // Additional logging + context.log('Type of rawData:', typeof rawData) + context.log('Buffer size:', rawData.length) - // Process telemetry with the converted buffer - const telemetry = new Telemetry(rawData) + // Try to process telemetry + try { + // const telemetry = new Telemetry(rawData) + // const telemetry = await Telemetry.fromFile(rawData) // Adjust this line based on how your file loader works + const telemetry = await Telemetry.fromBuffer(rawData); + const telemetrySummary = { + uniqueId: telemetry.uniqueId(), + header: telemetry.headers, + sessionInfo: telemetry.sessionInfo, + varHeaders: telemetry.varHeaders, + diskHeaders: telemetry.diskHeaders, + sampleCount: telemetry.sampleCount(), + duration: telemetry.duration(), + laps: telemetry.laps(), + variables: telemetry.variables() + } - if (telemetry.error) { - // Handle error case context.res = { - status: 400, - body: telemetry.error + status: 200, + body: telemetrySummary } - return - } - console.log('Telemetry headers:', telemetry.headers) - console.log(telemetry.header) - - const telemetrySummary = { - uniqueId: telemetry.uniqueId(), - header: telemetry.headers, // Assuming this contains the parsed header data - sessionInfo: telemetry.sessionInfo, // Contains the parsed YAML session info - varHeaders: telemetry.varHeaders // Assuming this method returns the variable headers - // Add a method to extract summarized telemetry data - // telemetryData: telemetry.getTelemetryDataSummary() - // You can add more methods as needed to extract different parts of the telemetry data - } - - // Response - context.res = { - status: 200, - body: telemetrySummary + } catch (telemetryError) { + context.log.error('Error processing telemetry:', telemetryError) + throw telemetryError // Rethrow to be caught by outer catch } } catch (error) { context.res = { status: 500, - body: `Error: ${error.message}` + body: `Error: ${error.message} \r\nStack: ${error.stack}\r\nRawBody: ${rawData}` } + context.log.error('Function execution error:', error) } } diff --git a/src/telemetry.js b/src/telemetry.js index d566469..558c4a4 100644 --- a/src/telemetry.js +++ b/src/telemetry.js @@ -67,6 +67,10 @@ class Telemetry { return telemetryFileLoader(file) } + static fromBuffer (buffer) { + return telemetryFileLoader(buffer) + } + /** * Telemetry variable headers. */ @@ -152,50 +156,56 @@ class Telemetry { } getTelemetryDataSummary () { - let totalSpeed = 0 - let maxRpm = 0 - let totalLaps = 0 - let bestLapTime = Number.MAX_VALUE - const lapTimes = [] - let highestSpeed = 0 - let totalBrakePressure = 0 - let totalThrottle = 0 - let sampleCount = 0 - - for (const sample of this.samples()) { - totalSpeed += sample.speed - maxRpm = Math.max(maxRpm, sample.rpm) - highestSpeed = Math.max(highestSpeed, sample.speed) - totalBrakePressure += sample.brakePressure - totalThrottle += sample.throttle - sampleCount++ - - // Assuming sample.lapTime and sample.lapNumber are available - if (sample.lapTime < bestLapTime) { - bestLapTime = sample.lapTime - } - if (!lapTimes[sample.lapNumber]) { - lapTimes[sample.lapNumber] = [] + try { + let totalSpeed = 0 + let maxRpm = 0 + let totalLaps = 0 + let bestLapTime = Number.MAX_VALUE + const lapTimes = [] + let highestSpeed = 0 + let totalBrakePressure = 0 + let totalThrottle = 0 + let sampleCount = 0 + + for (const sample of this.samples()) { + totalSpeed += sample.speed + maxRpm = Math.max(maxRpm, sample.rpm) + highestSpeed = Math.max(highestSpeed, sample.speed) + totalBrakePressure += sample.brakePressure + totalThrottle += sample.throttle + sampleCount++ + + // Assuming sample.lapTime and sample.lapNumber are available + if (sample.lapTime < bestLapTime) { + bestLapTime = sample.lapTime + } + if (!lapTimes[sample.lapNumber]) { + lapTimes[sample.lapNumber] = [] + } + lapTimes[sample.lapNumber].push(sample.lapTime) } - lapTimes[sample.lapNumber].push(sample.lapTime) - } - totalLaps = lapTimes.length - - // Calculate averages - const avgSpeed = totalSpeed / sampleCount - const avgBrakePressure = totalBrakePressure / sampleCount - const avgThrottle = totalThrottle / sampleCount - - return { - averageSpeed: avgSpeed, - maxRPM: maxRpm, - totalLaps, - bestLapTime, - highestSpeed, - averageBrakePressure: avgBrakePressure, - averageThrottle: avgThrottle, - lapTimes: lapTimes.map(lap => lap.reduce((a, b) => a + b, 0) / lap.length) + totalLaps = lapTimes.length + + // Calculate averages + const avgSpeed = totalSpeed / sampleCount + const avgBrakePressure = totalBrakePressure / sampleCount + const avgThrottle = totalThrottle / sampleCount + + return { + averageSpeed: avgSpeed, + maxRPM: maxRpm, + totalLaps, + bestLapTime, + highestSpeed, + averageBrakePressure: avgBrakePressure, + averageThrottle: avgThrottle, + lapTimes: lapTimes.map(lap => lap.reduce((a, b) => a + b, 0) / lap.length) + } + } catch (error) { + console.error('Error in getTelemetryDataSummary:', error) + // Handle the error or rethrow, depending on your error handling strategy + throw error } } diff --git a/src/utils/telemetry-file-loader.js b/src/utils/telemetry-file-loader.js index 37a5a85..1962d45 100644 --- a/src/utils/telemetry-file-loader.js +++ b/src/utils/telemetry-file-loader.js @@ -5,6 +5,7 @@ const { SIZE_IN_BYTES: DISK_SUB_HEADER_SIZE_IN_BYTES, DiskSubHeader } = require( const { SIZE_IN_BYTES: VAR_HEADER_SIZE_IN_BYTES, VarHeader } = require('../headers/var-header') const readFileToBuffer = require('../utils/read-file-to-buffer') const Telemetry = require('../telemetry') +const yaml = require('js-yaml') // Utility function to log and check if a value is a number function isNumber (value, name) { @@ -84,24 +85,34 @@ const varHeadersFromFileDescriptor = (fd, telemetryHeader) => { }) } -const telemetryFileLoader = (file) => { - return openDataFile(file) - .then(fd => { - const headers = [ - telemetryHeaderFromFileDescriptor(fd), - diskSubHeaderFromFileDescriptor(fd) - ] - - return Promise.all(headers) - .then(([telemetryHeader, diskSubHeader]) => { - return Promise.all([ - sessionInfoStringFromFileDescriptor(fd, telemetryHeader), - varHeadersFromFileDescriptor(fd, telemetryHeader) - ]).then(([sessionInfo, varHeaders]) => { - return new Telemetry(telemetryHeader, diskSubHeader, sessionInfo, varHeaders, fd) - }) - }) - }) +const telemetryFileLoader = (buffer) => { + try { + // Assuming the buffer contains the entire .ibt file content + // Extract the headers and other information from the buffer + const telemetryHeader = TelemetryHeader.fromBuffer(buffer.slice(0, HEADER_SIZE_IN_BYTES)) + const diskSubHeader = DiskSubHeader.fromBuffer(buffer.slice(HEADER_SIZE_IN_BYTES, HEADER_SIZE_IN_BYTES + DISK_SUB_HEADER_SIZE_IN_BYTES)) + + // Extract session info string + const sessionInfoStart = telemetryHeader.sessionInfoOffset + const sessionInfoLength = telemetryHeader.sessionInfoLength + const sessionInfoString = buffer.toString('ascii', sessionInfoStart, sessionInfoStart + sessionInfoLength) + const sessionInfo = yaml.load(sessionInfoString) + + // Extract variable headers + const varHeadersStart = telemetryHeader.varHeaderOffset + const varHeaders = [] + for (let i = 0; i < telemetryHeader.numVars; i++) { + const start = varHeadersStart + i * VAR_HEADER_SIZE_IN_BYTES + const varHeader = VarHeader.fromBuffer(buffer.slice(start, start + VAR_HEADER_SIZE_IN_BYTES)) + varHeaders.push(varHeader) + } + + // Create and return the Telemetry instance + return new Telemetry(telemetryHeader, diskSubHeader, sessionInfo, varHeaders, null) // Last argument 'fd' is null as it's not applicable here + } catch (error) { + console.error('Error processing telemetry buffer:', error) + throw error // Rethrow to handle the error outside + } } module.exports = telemetryFileLoader