UNPKG

@betaflight/api

Version:

A high-level API to read data from betaflight flight controllers

177 lines 6.37 kB
import { apiVersion, execute, WriteBuffer } from "@betaflight/msp"; import semver from "semver"; import codes from "../codes"; import { partialWriteFunc, times } from "../utils"; import { VtxDeviceTypes, } from "./types"; export { VtxDeviceTypes }; export const readVtxConfig = async (port) => { const api = apiVersion(port); const data = await execute(port, { code: codes.MSP_VTX_CONFIG }); return { type: data.readU8(), band: data.readU8(), channel: data.readU8(), power: data.readU8(), pitMode: data.readU8() !== 0, frequency: data.readU16(), deviceReady: data.readU8() !== 0, lowPowerDisarm: data.readU8(), ...(semver.gte(api, "1.42.0") ? { pitModeFrequency: data.readU16(), table: { available: data.readU8() !== 0, numBands: data.readU8(), numBandChannels: data.readU8(), numPowerLevels: data.readU8(), }, } : { pitModeFrequency: 0, table: { available: false, numBands: 0, numBandChannels: 0, numPowerLevels: 0, }, }), }; }; export const writeVtxConfig = async (port, config, clearVtxTable = false) => { const buffer = new WriteBuffer(); const api = apiVersion(port); buffer .push16(config.frequency) .push8(config.power) .push8(config.pitMode ? 1 : 0) .push8(config.lowPowerDisarm); if (semver.gte(api, "1.42.0")) { buffer .push16(config.pitModeFrequency) .push8(config.band) .push8(config.channel) .push16(config.frequency) .push8(config.table.numBands) .push8(config.table.numBandChannels) .push8(config.table.numPowerLevels) .push8(clearVtxTable ? 1 : 0); } await execute(port, { code: codes.MSP_SET_VTX_CONFIG, data: buffer }); }; export const clearVtxTable = async (port) => { const config = await readVtxConfig(port); await writeVtxConfig(port, config, true); }; export const writePartialVtxConfig = partialWriteFunc(readVtxConfig, writeVtxConfig); /** * Read the VTX table row, row number indexes from 1 */ export const readVtxTablePowerLevelsRow = async (port, rowNumber) => { const buffer = new WriteBuffer(); buffer.push8(rowNumber); const data = await execute(port, { code: codes.MSP_VTXTABLE_POWERLEVEL, data: buffer, }); return { rowNumber: data.readU8(), value: data.readU16(), label: String.fromCharCode(...times(() => data.readU8(), data.readU8())), }; }; export const writeVtxTablePowerLevelsRow = async (port, row) => { const buffer = new WriteBuffer(); buffer.push8(row.rowNumber).push16(row.value); buffer.push8(row.label.length); buffer.push(...Buffer.from(row.label)); await execute(port, { code: codes.MSP_SET_VTXTABLE_POWERLEVEL, data: buffer, }); }; /** * Read the VTX table row, row number indexes from 1 */ export const readVtxTableBandsRow = async (port, rowNumber) => { const buffer = new WriteBuffer(); buffer.push8(rowNumber); const data = await execute(port, { code: codes.MSP_VTXTABLE_BAND, data: buffer, }); return { rowNumber: data.readU8(), name: String.fromCharCode(...times(() => data.readU8(), data.readU8())), letter: String.fromCharCode(data.readU8()), isFactoryBand: data.readU8() !== 0, frequencies: times(() => data.readU16(), data.readU8()), }; }; export const writeVtxTableBandsRow = async (port, row) => { const buffer = new WriteBuffer(); buffer.push8(row.rowNumber); buffer.push8(row.name.length); buffer.push(...Buffer.from(row.name)); if (row.letter !== "") { buffer.push8(row.letter.charCodeAt(0)); } else { buffer.push8(" ".charCodeAt(0)); } buffer.push8(row.isFactoryBand ? 1 : 0); buffer.push8(row.frequencies.length); row.frequencies.forEach((frequency) => { buffer.push16(frequency); }); await execute(port, { code: codes.MSP_SET_VTXTABLE_BAND, data: buffer }); }; export const readVtxDeviceStatus = async (port) => { const data = await execute(port, { code: codes.MSP2_GET_VTX_DEVICE_STATUS }); if (data.byteLength < 1) { return undefined; } const vtxType = data.readU8(); const deviceIsReady = Boolean(data.readU8()); const isBandAndChannelAvailable = Boolean(data.readU8()); const band = data.readU8(); const channel = data.readU8(); const powerIndexAvailable = Boolean(data.readU8()); const powerIndex = data.readU8(); const frequencyAvailable = Boolean(data.readU8()); const frequency = data.readU16(); const vtxStatusAvailable = Boolean(data.readU8()); const vtxStatus = data.readU32(); // pitmode and/or locked const powerLevelCount = data.readU8(); const powersAndLevels = times(() => [data.readU16(), data.readU16()], powerLevelCount); const baseConfig = { deviceIsReady, band: isBandAndChannelAvailable ? band : undefined, channel: isBandAndChannelAvailable ? channel : undefined, powerIndex: powerIndexAvailable ? powerIndex : undefined, frequency: frequencyAvailable ? frequency : undefined, vtxStatus: vtxStatusAvailable ? vtxStatus : undefined, levels: powersAndLevels.map((value) => value[0]), powers: powersAndLevels.map((value) => value[1]), }; data.readU8(); // custom device status size switch (vtxType) { case VtxDeviceTypes.VTXDEV_SMARTAUDIO: return { type: vtxType, version: data.readU8(), mode: data.readU8(), orfreq: data.readU8(), willBootIntoPitMode: Boolean(data.readU8()), ...baseConfig, }; case VtxDeviceTypes.VTXDEV_RTC6705: case VtxDeviceTypes.VTXDEV_TRAMP: case VtxDeviceTypes.VTXDEV_UNKNOWN: default: return { type: vtxType, ...baseConfig, }; } }; //# sourceMappingURL=index.js.map