@@ -15,6 +15,20 @@ interface DecodedMessage {
1515 } ;
1616}
1717
18+ // Type for batch processing results
19+ type ProcessResult = DecodedMessage | DecodedMessage [ ] | null ;
20+
21+ // Type for input WebSocket messages
22+ interface WebSocketMessage {
23+ time ?: number ;
24+ timestamp ?: number ;
25+ canId ?: number ;
26+ id ?: number ;
27+ data ?: number [ ] ;
28+ }
29+
30+ type WebSocketInput = string | WebSocketMessage | WebSocketMessage [ ] ;
31+
1832/**
1933 * Parse the physValue string from Candied (format: "123.45 voltage:V")
2034 * @param physValue - Physical value string from Candied
@@ -301,19 +315,61 @@ export async function createCanProcessor(dbcPath: string): Promise<any> {
301315 return decodeCanMessage ( can , parsed . canId , parsed . data , parsed . time ) ;
302316 } ,
303317
318+ /**
319+ * Process multiple CAN messages in batch
320+ * @param messages - Array of CAN messages
321+ * @returns Array of decoded messages
322+ */
323+ processBatchMessages : function ( messages : WebSocketInput [ ] ) : DecodedMessage [ ] {
324+ const decodedMessages : DecodedMessage [ ] = [ ] ;
325+
326+ for ( const message of messages ) {
327+ const decoded = this . processWebSocketMessage ( message ) ;
328+ if ( decoded ) {
329+ // If the result is an array, flatten it
330+ if ( Array . isArray ( decoded ) ) {
331+ decodedMessages . push ( ...decoded ) ;
332+ } else {
333+ decodedMessages . push ( decoded ) ;
334+ }
335+ }
336+ }
337+
338+ return decodedMessages ;
339+ } ,
340+
304341 /**
305342 * Process WebSocket CAN message
306- * @param wsMessage - WebSocket message (can be string or object )
307- * @returns Decoded message or null
343+ * @param wsMessage - WebSocket message (can be string, object, or array of objects )
344+ * @returns Decoded message or array of decoded messages or null
308345 */
309- processWebSocketMessage : function ( wsMessage : any ) : DecodedMessage | null {
346+ processWebSocketMessage : function ( wsMessage : WebSocketInput ) : ProcessResult {
310347 // Handle different WebSocket message formats
311348
312349 // If it's a string, try parsing as CSV line
313350 if ( typeof wsMessage === 'string' ) {
314351 return this . processLogLine ( wsMessage ) ;
315352 }
316353
354+ // If it's an array of messages, process each one
355+ if ( Array . isArray ( wsMessage ) ) {
356+ const decodedMessages : DecodedMessage [ ] = [ ] ;
357+
358+ for ( const message of wsMessage ) {
359+ const decoded = this . processWebSocketMessage ( message ) ;
360+ if ( decoded ) {
361+ // If the recursive call returns an array, flatten it
362+ if ( Array . isArray ( decoded ) ) {
363+ decodedMessages . push ( ...decoded ) ;
364+ } else {
365+ decodedMessages . push ( decoded ) ;
366+ }
367+ }
368+ }
369+
370+ return decodedMessages . length > 0 ? decodedMessages : null ;
371+ }
372+
317373 // If it's an object with time, canId/id and data properties
318374 if ( typeof wsMessage === 'object' ) {
319375 const time = wsMessage . time || wsMessage . timestamp || Date . now ( ) ;
@@ -364,20 +420,31 @@ export async function createCanProcessor(dbcPath: string): Promise<any> {
364420 *
365421 * ws.onmessage = (event) => {
366422 * const decoded = processor.processWebSocketMessage(event.data);
367- * if (decoded) {
368- * console.log('Time:', decoded.time);
369- * console.log('CAN ID:', decoded.canId);
370- * console.log('Message:', decoded.messageName);
371- * console.log('Signals:', decoded.signals);
372- *
373- * // Next step to tabel or graph
374- * }
423+ *
424+ * // Handle both single messages and arrays of messages
425+ * const messages = Array.isArray(decoded) ? decoded : [decoded];
426+ *
427+ * messages.forEach(message => {
428+ * if (message) {
429+ * console.log('Time:', message.time);
430+ * console.log('CAN ID:', message.canId);
431+ * console.log('Message:', message.messageName);
432+ * console.log('Signals:', message.signals);
433+ *
434+ * // Next step to table or graph
435+ * }
436+ * });
375437 * };
376438 *
377439 * // Supported WebSocket message formats:
378440 * // 1. CSV string: "2952,CAN,170,4,12,9,0,0,16,64,0"
379441 * ^ relative timestamp will be rejected automatically in the future
380442 * The 2025-2026 DAQ system will have absolute timestamps
381- * // 2. JSON object: { time: 2952, canId: 170, data: [4,12,9,0,0,16,64,0] }
443+ * // 2. Single JSON object: { time: 2952, canId: 170, data: [4,12,9,0,0,16,64,0] }
382444 * // 3. JSON with timestamp: { timestamp: 1234567890, id: 170, data: [...] }
445+ * // 4. Array of JSON objects: [
446+ * { time: 2952, canId: 170, data: [4,12,9,0,0,16,64,0] },
447+ * { time: 2953, canId: 176, data: [215,1,19,254,51,9,170,14] },
448+ * { time: 2954, canId: 192, data: [216,1,0,0,0,1,252,8] }
449+ * ]
383450 */
0 commit comments