Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bfctl — Betaflight config from the terminal

Minimal terminal wrapper around Betaflight flight-controller config management. Similar spirit to the Betaflight Configurator browser app, but focused on the bare essentials:

  • find serial ports / auto-detect the FC, including a named registry for a fleet of drones
  • connect over USB serial (CLI text protocol)
  • pull configs (diff all / dump all) and save them under configs/ — one FC or --all of them
  • push a saved config back to the drone, auto-backing up the live config first
  • diff two local configs, or a board's saved backup history over time
  • list / enable / disable feature flags
  • read/write CLI variables, run raw commands, interactive shell

Use at your own risk. This tool writes directly to your flight controller's CLI. Provided as-is with no warranty — always take props off before connecting, verify a config before pushing it, and keep backups (see Safety notes).

Setup

cd betaflight_config
make install          # creates .venv and installs bfctl (editable)
source .venv/bin/activate

Or without Make:

python3 -m venv .venv
source .venv/bin/activate
pip install -e .

Useful Make targets: make help, make check (offline tests: scripts/check.py

  • pytest, no FC required), make doctor, make ports, make status PORT=STM32G473, make pull PORT=…, make clean.

Optional tab-completion (commands, flags, --port fragments):

pip install -e ".[completion]"
eval "$(register-python-argcomplete bfctl)"   # add to ~/.bashrc or ~/.zshrc

Quick start

# List serial ports (* = FC, S = sticky default)
bfctl ports

# FC status / version (see "Multiple drones" below for how the target is picked)
bfctl status
bfctl status --port TUNERCF405   # skip prompt

# Pull config (recommended: diff of non-defaults across all profiles)
# Saves as configs/TUNERCF405.txt (board_name from the FC)
bfctl pull
bfctl pull --timestamp              # configs/TUNERCF405-diff-<utc>.txt
bfctl pull --mode dump --name my-freestyle-5inch
bfctl pull --all                    # snapshot every connected FC in one go (always timestamped)

# List local backups
bfctl list

# Push a config back (props OFF; confirm prompts)
# Uses device tags in the file (usb_serial / board_name) to pick the right FC,
# shows a live change preview, backs up the live config, then applies.
# `save` makes the FC reboot itself.
bfctl push configs/TUNERCF405.txt
bfctl push TUNERCF405.txt --yes
bfctl push TUNERCF405.txt --force     # override version/board hard fails
bfctl push TUNERCF405.txt --no-reboot # prefer save noreboot if firmware supports it
bfctl push TUNERCF405.txt --verify    # after reboot, re-dump and compare
bfctl push TUNERCF405.txt --no-preview  # skip pre-push change diff
bfctl push TUNERCF405.txt --no-backup   # skip the automatic pre-push backup

# Standalone verify (optional --wait after a manual reboot)
bfctl verify TUNERCF405.txt
bfctl verify TUNERCF405.txt --wait --timeout 120

# Local diffing (no FC needed)
bfctl diff configs/TUNERCF405-diff-A.txt configs/TUNERCF405-diff-B.txt
bfctl history TUNERCF405             # chronological diff across TUNERCF405's timestamped backups
bfctl history TUNERCF405 --mode dump

# Features
bfctl features
bfctl feature enable LED_STRIP
bfctl feature disable SOFTSERIAL --save

# Variables
bfctl get p_roll
bfctl set p_roll=45
bfctl set gyro_lpf1_static_hz=0 --save

# Raw CLI / interactive
bfctl cmd version
bfctl cmd -- diff all
bfctl shell

Auto-detects the first port whose product/manufacturer looks like Betaflight. Override with --port /dev/cu.usbmodem….

Safety notes

  • Never push a dump/diff from a different firmware version — variable names and ranges change and can silently corrupt settings.
  • bfctl push runs a metadata compatibility check (board name + firmware major/minor from dump headers vs the live FC) and blocks on hard mismatches unless you pass --force.
  • That check is not a full CLI schema validator: individual set lines are only validated by the FC while applying. Unknown settings may error mid-push.
  • Prefer diff all backups over full dump all for day-to-day restore.
  • bfctl push backs up the live config before applying, by default (a full dump all, same file bfctl pull --mode dump --timestamp would produce). Pass --no-backup to skip. bfctl history <board> shows what changed across a board's saved backups over time.
  • Take props off before connecting or writing.
  • push --defaults runs defaults nosave first (factory reset of config) — destructive.
  • save is what reboots the FC (Betaflight writes EEPROM then reboots). bfctl only sends that CLI command; a USB disconnect right after is expected and treated as success.
  • push --verify / bfctl verify: wait for USB to return, pull a live dump all, and check that every setting from the local file is present with the same value. Reports missing/mismatched lines (failed applies). This is expected⊆live comparison, not a byte-identical file diff.

Multiple drones

With more than one FC plugged in, bfctl needs to pick a target port. It resolves one in priority order, stopping at the first hit:

  1. --port — explicit path (/dev/cu.usbmodem…), a registered device nickname (see below), a serial number, or a product/name fragment (e.g. TUNERCF405). Never prompts. If a fragment matches more than one connected FC, bfctl refuses to guess (fails loudly rather than picking one).
  2. Device tags on the file (push only) — bfctl pull stamps every saved config with usb_serial / usb_product / board_name in its header. Pushing that file back auto-targets the FC it was pulled from, even with other drones connected — you'll see a Target board: line confirming the match before anything is sent. bfctl verify doesn't read these tags; it falls through to sticky/single-FC like everything else.
  3. Sticky defaultbfctl select remembers a device (by serial number, falling back to product/board name) in .bfctl/state.json. Every later command uses it automatically as long as that FC is plugged in.
  4. Single FC — if only one is connected, it's used with no extra flags needed.
  5. Interactive prompt — multiple FCs, no tag/sticky/--port match: bfctl lists them and asks (non-interactive shells get a clear error instead of hanging).
bfctl select                 # interactive picker
bfctl select STM32G473       # by product / path / serial, no prompt
bfctl select --show          # what's sticky, and is it currently plugged in
bfctl select --clear         # go back to prompt-per-command

Named devices (fleet of more than one sticky pick)

bfctl select only remembers one default at a time. For an actual fleet, register each drone under a nickname — --port <nickname> then resolves it regardless of which physical port it enumerates on:

bfctl devices add racer --port TUNERCF405   # registers whatever --port resolves to
bfctl devices add freestyle5                # or resolve interactively/via sticky, then register
bfctl devices list                          # nicknames + current plugged-in status
bfctl devices remove racer

bfctl status --port racer                   # works from any command that takes --port
bfctl push configs/racer.txt --port racer

How it talks to the FC

Uses the same text CLI the Configurator “CLI” tab uses:

  1. Open serial @ 115200
  2. Send # to enter CLI
  3. Run commands (diff all, feature, set …, …)
  4. Optionally save / exit noreboot

Firmware build options (compile-time USE_* / radio protocol flags from cloud build) are only partially visible over CLI. bfctl status prints them when the firmware exposes them; otherwise use Configurator’s firmware flasher / cloud build UI for full option sets. Runtime feature flags (feature GPS, etc.) are fully supported.

Layout

bfctl/           Python package
configs/         Local dumps saved by `bfctl pull`
tests/           pytest suite (offline, no FC required)
scripts/         check.py — pure-function smoke checks run by `make check`

About

Minimal terminal wrapper around Betaflight flight-controller config management

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages