UNPKG

tello-custom-ip

Version:

Tello drone client with custom IP address support, forked from @0x77/tellots

103 lines (91 loc) 3.15 kB
import constants from "./constants"; import { getTelloIP } from "./config"; import dgram from "dgram"; import { ResponseParser, CommandType } from "./types"; import { parseCommandResponse } from "./parsers"; const client = dgram.createSocket('udp4'), _local = { state: "idle" } client.on('message', (msg) => { _local.state = msg.toString() }); client.bind(constants.ports.response) const bindStateManagement = (resolve: Function, reject: Function, parser?: ResponseParser) => { let timeoutId = setTimeout(() => { _local.state = "error" }, 10000); let intervalId = setInterval(() => { if (isIdle()) return if (isError()) reject(_local.state) else { const rawResponse = _local.state; if (parser) { // Parse the response using the provided parser try { const parsedResponse = parser(rawResponse); resolve(parsedResponse); } catch (error) { reject(error); } } else { // Return raw response if no parser is provided resolve(rawResponse); } } clearInterval(intervalId) clearTimeout(timeoutId) _local.state = "idle" }, 100); } const isIdle = () => _local.state === "idle" const isError = () => _local.state === "error" const transmit = (command: string) => { const message = Buffer.from(command) client.send(message, 0, message.length, constants.ports.command, getTelloIP(), (error) => { if (error) _local.state = "error" }) } /** * Send a command to the Tello drone * @param command - The command to send * @param parser - Optional parser function to convert the response to a specific type * @param type - The type of command (used for determining default parser) * @returns Promise resolving to the parsed response */ const send = <T = string>( command: string, parser?: ResponseParser<T>, type: CommandType = CommandType.READ ): Promise<T> => { return new Promise((resolve, reject) => { if (!isIdle()) reject("error") // Use provided parser or default based on command type const responseParser = parser || getDefaultParser<T>(type); bindStateManagement(resolve, reject, responseParser) transmit(command) }) } /** * Get the default parser based on command type */ const getDefaultParser = <T>(type: CommandType): ResponseParser<T> => { switch (type) { case CommandType.CONTROL: case CommandType.SET: // For control and set commands, parse "ok" as true, anything else as false return ((response: string) => { return parseCommandResponse(response) as unknown as T; }); case CommandType.READ: default: // For read commands, return the raw string return ((response: string) => response as unknown as T); } } export const exchanger = { send, _local }; export default exchanger;