import { NextApiRequest, NextApiResponse } from 'next' import { serialConnection, parser } from '../serial/connect' import { RangeResult, DeviceData } from '@/lib/uwb-types' // Data storage for real-time updates let latestRangeData: RangeResult | null = null let latestDeviceData: DeviceData[] = [] // Parse UWB range data (from ESP32 UWBHelper parseRangeData format) function parseUWBRangeData(data: string): RangeResult | DeviceData[] | null { if (!data.startsWith("AT+RANGE=")) { return null } // Parse tid (Tag ID) const tidMatch = data.match(/tid:(\d+)/) if (!tidMatch) return null const tagId = parseInt(tidMatch[1]) // Parse detailed range data format const maskMatch = data.match(/mask:(\d+)/) const seqMatch = data.match(/seq:(\d+)/) const timerMatch = data.match(/timer:(\d+)/) const timerSysMatch = data.match(/timerSys:(\d+)/) // Parse range data const rangeMatch = data.match(/range:\(([^)]+)\)/) const rssiMatch = data.match(/rssi:\(([^)]+)\)/) const ancidMatch = data.match(/ancid:\(([^)]+)\)/) if (rangeMatch && rssiMatch) { const ranges = rangeMatch[1].split(',').map(r => parseFloat(r) / 100) // Convert cm to meters const rssi = rssiMatch[1].split(',').map(r => parseFloat(r)) const anchorIds = ancidMatch ? ancidMatch[1].split(',').map(a => parseInt(a)) : Array(8).fill(0) const result: RangeResult = { tagId, mask: maskMatch ? parseInt(maskMatch[1]) : 0, sequence: seqMatch ? parseInt(seqMatch[1]) : 0, ranges: ranges.slice(0, 8).concat(Array(8 - ranges.length).fill(0)), rssi: rssi.slice(0, 8).concat(Array(8 - rssi.length).fill(0)), anchorIds: anchorIds.slice(0, 8).concat(Array(8 - anchorIds.length).fill(0)), timer: timerMatch ? parseInt(timerMatch[1]) : 0, timerSys: timerSysMatch ? parseInt(timerSysMatch[1]) : 0 } latestRangeData = result return result } return null } // Set up data listener when connection is established if (parser) { parser.on('data', (data: string) => { const parsed = parseUWBRangeData(data.trim()) if (parsed) { console.log('UWB Data received:', parsed) } }) } export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method === 'GET') { if (!serialConnection?.isOpen) { return res.status(400).json({ message: 'Serial connection not established' }) } // Return latest data res.status(200).json({ rangeData: latestRangeData, deviceData: latestDeviceData, timestamp: Date.now() }) } else if (req.method === 'POST') { // Send command to UWB device const { command } = req.body if (!serialConnection?.isOpen) { return res.status(400).json({ message: 'Serial connection not established' }) } if (!command) { return res.status(400).json({ message: 'Command is required' }) } try { serialConnection.write(command + '\r\n') res.status(200).json({ message: 'Command sent', command }) } catch (error) { res.status(500).json({ message: 'Failed to send command', error: error instanceof Error ? error.message : 'Unknown error' }) } } else { res.status(405).json({ message: 'Method not allowed' }) } }