A library, written in TypeScript, to encode and decode ImmersionRC LapRF binary messages.
Convert all the data coming from a LapRF into a form that is easily converted to and from JSON, or consumed directly in a JavaScript application.
class Protocol {
// Serialize a LapRF packet to request the rtc time.
static getRctTime(): Uint8Array;
// Serialize a LapRF packet to request the minimum lap time.
static getMinLapTime(): Uint8Array;
// Serialize a LapRF packet to set the minimum lap time.
static setMinLapTime(milliseconds: number): Uint8Array;
// Serialize a LapRF packet to set the status interval.
static setStatusInterval(milliseconds: number): Uint8Array;
// Serialize a LapRF packet to request the rfSetup of either an individual slot,
// or all slots if `slotIndex` isn't provided.
static getRfSetup(slotIndex?: number): Uint8Array;
// Serialize a LapRF packet to configure a rfSetup slot.
static setRfSetup(input: {
slotIndex: SlotIndex;
band: BandIndex;
channel: ChannelIndex;
gain: number;
threshold: number;
enabled: boolean;
}): Uint8Array;
// Takes a `DataView` containing a LapRF packet and return an array of
// `DeviceRecord`s (A LapRF packet can contain more than one record).
static decode(packet: DataView): DeviceRecord[];
// Takes a `DataView` containing an unescaped LapRF record and returns a `DeviceRecord`.
static decodeRecord(record: DataView): DeviceRecord;
}
interface RfSetupRecord {
type: 'rfSetup';
slotIndex: SlotIndex;
enabled: number;
channel: ChannelIndex;
band: BandIndex;
threshold: number;
gain: number;
frequency: number;
}
interface RssiRecord {
type: 'rssi';
slotIndex: SlotIndex;
minRssi: number;
maxRssi: number;
meanRssi: number;
}
interface SettingsRecord {
type: 'settings';
updatePeriod: number;
saveSettings: number;
minLapTime: number;
}
interface PassingRecord {
type: 'passing';
slotIndex: SlotIndex;
rtcTime: number;
decoderId: number;
passingNumber: number;
peakHeight: number;
flags: number;
}
interface StatusRecord {
type: 'status';
flags: number;
gateState: number;
batteryVoltage: number;
detectionCount: number;
slots: Record<SlotIndex, { lastRssi: number }>;
}
interface TimeRecord {
type: 'time';
rtcTime: number;
timeRtcTime: number;
}
type DeviceRecord =
| RfSetupRecord
| RssiRecord
| SettingsRecord
| PassingRecord
| StatusRecord
| TimeRecord;
import { Socket } from 'net';
import { Protocol } from '@fpvcult/laprf';
const client = new Socket();
client.connect(5403, '192.168.1.9');
client.write(Protocol.setMinLapTime(10_000));
client.on('data', (buffer: Buffer) => {
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
const records = Protocol.decode(view); // Argument needs to be an DataView
// ... do something with the records
});
Inspired by IRCSwiftyLapRF and LapRFUtilities