Open-source project
marshallrichards/turbodrone avatar
marshallrichards/turbodrone

Turbodrone: driving cheap WiFi drones from your own code

reverse engineering the best-selling drones on Amazon to control programmatically

576 stars77 forksPythonApache-2.0

At a glance

What is it?
Turbodrone is a reverse-engineered API and client for controlling inexpensive WiFi camera drones that otherwise only speak to a closed-source phone app, with per-model protocol implementations for the S2x, wifi_uav, cooingdv and x69_lg families and a Python backend with a web frontend. The project lists fifteen supported or suspected models and is explicit about which have actually been flown.
Who is it for?
Adopt Turbodrone if you want to fly one of these drones from a script or from a browser rather than from the vendor's app, and you are comfortable with the fact that the protocol is a best-effort reverse engineering that the vendor could change at any time.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 122 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Freeing a drone from its app

Turbodrone is a reverse-engineered API and client for controlling some of the best-selling fifty dollar toy drones on Amazon from a computer, replacing the closed-source mobile apps the drones come with.

The motivation is spelled out in the introduction. These are incredibly cheap toy drones, pared-down clones of the early DJI Mavic, for about fifty dollars, with a 1080p camera for FPV and recording, a tiny downward-facing optical flow sensor for position and altitude hold, and a well-tuned flight profile out of the box. The only problem is that they run closed-source firmware and are locked to being controlled by a custom mobile app.

So the project takes the drone apart in software terms. The author's stated aim is to free some of these drones from their jail and write an API and client for accessing the video feed and sending control commands down to the drone, by reverse-engineering how the mobile apps work. The result is that a capable fifty dollar toy drone becomes something programmatically controllable and usable for applications and experiments.

That framing explains the architecture. There is a backend and a frontend, and the backend is where the protocol implementations live, because the protocol is per app family rather than per model. The repository top level shows a backend directory, a frontend directory, a docs directory and an experimental directory, and the project is Apache 2.0 licensed with a NOTICE file, which is what you would expect for a project that documents reverse-engineered protocols.

The language is Python, the last push was on 2026-06-23, and the repository publishes no GitHub releases, so there is no versioned artefact to point at.

The compatibility table is the specification

The hardware section is a table of drone models, and it is the most useful page in the repository, because it tells you exactly what works and what is a guess.

Each row gives a brand, model numbers, a compatibility verdict, the name of the protocol implementation, the motor type, a purchase link and notes. The verdicts are defined precisely at the foot of the table. Tested means the drone has been physically run with turbodrone to ensure its compatibility. Suspected means the APK for the drone appears to use the exact same packages and libraries as one of the tested drones. Untested means the APK has been reverse engineered and implementation code exists, but the drone has not yet been physically flown with TurboDrone. TODO means the APK operates with different byte packets and protocols and will have to be added as a new implementation in the API.

Those four states are a genuinely careful way to present reverse-engineering work, and they map to very different levels of trust. A tested row means somebody flew the thing. A suspected row means the app looks similar, which is a reasonable inference but not a guarantee, since app publishers reuse libraries across models and then diverge. A TODO row means the protocol is different and no work has been done.

The implementations are named after the app families rather than the models: cooingdv, s2x, wifi_uav, x69_lg and Unknown. So a single implementation covers several models, which is the whole reason the model list has to be per model, because the same app family is used across models with different behaviour in places.

The list covers fifteen rows, and the spread is instructive. The generic M10 with the cooingdv implementation is the author's current favourite, with a note that the RTSP video stream is very reliable. The Plegble PL-515 shares the S2x implementation and takes the same batteries, but with upgraded brushless motors. The Karuisrc K417 was the first model supported with brushless motors. Several models are brushed, and the motors matter because a brushless motor changes the control response, which is exactly the kind of detail a per-model table would surface.

The Loiley S29 and Hiturbo S20 both use the s2x implementation, with the S20 noted as the original test platform. The Loiley X69 is a new app family, and the note records that RC, camera tilt and an experimental FFmpeg-backed H.265 video are implemented. The FlyVista V88 and the D16/GT3/V66 use wifi_uav, with the D16 noted as a smaller DJI Neo clone that is only really good for indoor flight.

The video path, and the WiFi dongle question

Two practical issues will stop you before any code runs, and both are hardware.

The first is the network. The drone broadcasts its own WiFi network, so your computer has to connect to it. Once it does, your computer is on the drone's network and not on the internet, which is fine for flying but not for anything else you want the machine to do.

The recommended answer is a WiFi dongle, with the ALFA Network AWUS036ACM or similar suggested. The readme is careful to say this is not strictly necessary, because you can use your computer's built-in WiFi radio to connect to the drone's network, but it is nice to have so you can stay connected to the internet while flying the drone.

That framing is the right way to think about it. The dongle is not for range, it is so that the machine running the control code keeps its internet connection while the built-in radio handles the drone link, and in practice you want the controller to be somewhere you can see the video feed and the laptop screen at the same time.

The second issue is the video path itself, and the quality of it varies by implementation. The M10 gets the note that its RTSP video stream is very reliable, which suggests the RTSP path is specific to certain implementations rather than universal. The X69 has experimental FFmpeg-backed H.265 video, which is a different pipeline again. The Loiley S29 has a servo for tilting the camera, and the table flags that this is not implemented in the API yet.

The name Turbodrone comes from the family of apps it targets, and the repo includes an experimental directory, which is where work in progress lives. The X69 note about an experimental FFmpeg-backed H.265 video and the Loiley S29 note about the unimplemented camera tilt servo are the kind of detail that only appears in a table maintained by someone who has actually tried each row.

Setting up the backend and frontend

The setup is a Python backend and a Node frontend, and the readme walks through it in order.

You move to the backend directory and create a virtual environment:

bash
cd backend
bash
python -m venv venv
source venv/bin/activate

Then the Python dependencies, and the Windows caveat:

bash
pip install -r requirements.txt
bash
pip install windows-curses

The curses note is specific. On Windows you have to install the curses library manually, because the terminal interface is built on it and Windows does not ship it.

In a new terminal window you install the frontend dependencies, and the readme is explicit that you need Node.js 20 or newer:

bash
cd frontend
npm install

The two-terminal arrangement is not accidental. You need the terminal running the frontend to be separate from the one with the backend activated, because the backend has the virtual environment loaded and the frontend needs a clean shell with Node on the path.

Before proceeding, the WiFi dongle has to be plugged in and the drone turned on, and you connect to the network named BRAND-MODEL-XXXXXX, following the pattern of the drone's own name.

Then you create a .env file in the backend directory with a DRONE_TYPE setting, and the readme gives the commented examples for the families, including s2x for the com.vison.macrochip based drones such as the S20 and S29, wifi_uav for the WiFi UAV based drones such as the V88 and D16, and cooingdv for the publisher drone apps like RC UFO and KY UFO.

The setting is the switch that selects the protocol implementation, which is why it is the one piece of configuration you must get right.

What a reverse-engineered drone API can and cannot promise

The design has an inherent fragility that is worth naming before anyone builds on it, and the project is honest enough to let you see it.

The protocol is inferred from a closed-source mobile application by whatever means the author used, and it is not versioned or published by the vendor. The vendor can change the app, and then the implementation is wrong until someone re-reverses it. There is no compatibility promise and no release series, since the repository publishes no GitHub releases.

The table's four-state vocabulary is the practical way to reason about that. If your exact model is Tested, you have a working implementation that someone flew. If it is Suspected, you are relying on an inference that app reuse usually but not always supports, and you should expect to debug packet formats yourself. If it is Untested, the code exists but nobody has confirmed it against hardware. If it is TODO, nothing exists.

The motor distinction in the table is a good example of the kind of thing that only surfaces through physical testing. A brushed drone and a brushless one of the same model may use the same app and the same packets, but they respond differently to control input, and a control loop tuned for one can behave differently on the other. The Plegble PL-515, the S2x airframe with upgraded brushless motors, and the Karuisrc K417, the first brushless model supported, are all called out for that reason.

The other visible boundary is what the API does not expose. The Loiley S29's tilting camera servo is noted as not implemented, and the X69's list of implemented features, RC, camera tilt and experimental FFmpeg-backed H.265 video, is a partial set against what those drones can physically do.

The practical advice that follows from all this is simple and does not need the project to say it. Check your model against the table before you buy the parts, and treat a Suspected row as a research task rather than a supported configuration.

Editorial conclusion

Adopt Turbodrone if you want to fly one of these drones from a script or from a browser rather than from the vendor's app, and you are comfortable with the fact that the protocol is a best-effort reverse engineering that the vendor could change at any time. Do not adopt it if you need flight guarantees, and treat the model list as the real specification, since the readme distinguishes drones that have been physically flown from those that are only suspected to share a protocol. Before you commit, check that your exact model appears in the table, note that the drone broadcasts its own WiFi network so you need a second radio or an internet connection that survives the switch, and set DRONE_TYPE to the family your drone's app belongs to.

Frequently asked questions

What is Turbodrone?

It is a reverse-engineered API and client for controlling some of the best-selling fifty dollar toy drones on Amazon from a computer, replacing the closed-source mobile apps they come with. It lets you access the video feed and send control commands to the drone programmatically, and it is licensed under Apache 2.0.

Which drones does Turbodrone support?

The table covers fifteen models, from the generic M10, the Plegble PL-515, the Karuisrc K417, the Loiley S29 and X69, the Hiturbo S20, the FlyVista V88, the D16/GT3/V66 and several E58, E88, E99, A35, LSRC-S1S and X29 variants, each marked as tested, suspected, untested or to do, with the protocol implementation named for the app family involved.

What do the compatibility states in the Turbodrone table mean?

Tested means the drone has been physically run with turbodrone. Suspected means the drone's APK appears to use the same packages and libraries as a tested drone. Untested means the APK has been reverse engineered and implementation code exists but the drone has not been flown. TODO means the APK uses different byte packets and protocols and needs a new implementation.

Why do I need a WiFi dongle to use Turbodrone?

The drone broadcasts its own WiFi network, so your computer has to connect to it, which takes the machine off the internet. The readme recommends a dongle such as the ALFA Network AWUS036ACM so you can stay connected to the internet while flying, while the built-in radio handles the drone link.

How do I set up the Turbodrone backend and frontend?

Move to the backend directory, create and activate a virtual environment, install the requirements with pip install -r requirements.txt, and on Windows also install windows-curses. Then in a separate terminal install the frontend with npm install, which needs Node.js 20 or newer, and set DRONE_TYPE in a .env file in the backend directory to the family your drone's app belongs to.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. marshallrichards/turbodrone on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/marshallrichards-turbodrone.svg)](https://hysenlabs.com/projects/marshallrichards-turbodrone)

Was this useful?