tools: add screenshot.sh screen-grabber wrapper
One-command screenshot helper around gd-77_screen_grabber.py: auto-detects the radio's serial port (cu.usbmodem* on macOS, ttyACM* on Linux) and creates a self-contained Python venv with pyserial + pillow on first run. Saves to screenshots/ (gitignored, along with the venv). Documented in TOOLS.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e20eabd203
commit
682a729e5c
4 changed files with 75 additions and 4 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -8,3 +8,7 @@ languages_builder
|
||||||
|
|
||||||
# Generated docs site
|
# Generated docs site
|
||||||
website/_build/
|
website/_build/
|
||||||
|
|
||||||
|
# Screenshot tool venv + scratch output
|
||||||
|
MDUV380_firmware/tools/.venv/
|
||||||
|
screenshots/
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,9 @@ single running list until the first versioned release.
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
_Nothing yet._
|
- **`screenshot.sh`** — a one-command wrapper around the OpenGD77 screen grabber
|
||||||
|
that auto-detects the serial port and sets up a self-contained Python venv
|
||||||
|
(pyserial + pillow) on first run. Saves to `screenshots/`.
|
||||||
|
|
||||||
## 0.5.0
|
## 0.5.0
|
||||||
|
|
||||||
|
|
|
||||||
16
TOOLS.md
16
TOOLS.md
|
|
@ -87,9 +87,19 @@ Models: `MD-UV380`, `DM-1701`, `MD-9600`, `MD-2017`, `MD-380`.
|
||||||
grabber (the "gd-77" name is historical). It talks over the USB **CDC serial port**,
|
grabber (the "gd-77" name is historical). It talks over the USB **CDC serial port**,
|
||||||
auto-detects the radio model and reads the MD-UV380's 160×128 RGB565 framebuffer into a PNG.
|
auto-detects the radio model and reads the MD-UV380's 160×128 RGB565 framebuffer into a PNG.
|
||||||
|
|
||||||
1. Power the radio on **normally** (not DFU mode) and navigate to the screen you want.
|
Power the radio on **normally** (not DFU mode), navigate to the screen you want, and
|
||||||
Connect USB.
|
connect USB.
|
||||||
2. Run it (`-o` takes the filename **without** `.png`):
|
|
||||||
|
**Easiest — the `./screenshot.sh` helper** (auto-detects the serial port and sets up a
|
||||||
|
self-contained Python venv with `pyserial` + `pillow` on first run):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./screenshot.sh # -> screenshots/screenshot-<timestamp>.png
|
||||||
|
./screenshot.sh vfo-7seg # -> screenshots/vfo-7seg.png
|
||||||
|
./screenshot.sh -d /dev/cu.usbmodemXXXX [name] # explicit port
|
||||||
|
```
|
||||||
|
|
||||||
|
**Or call the grabber directly** (`-o` takes the filename **without** `.png`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 MDUV380_firmware/tools/gd-77_screen_grabber.py \
|
python3 MDUV380_firmware/tools/gd-77_screen_grabber.py \
|
||||||
|
|
|
||||||
55
screenshot.sh
Normal file
55
screenshot.sh
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Grab a screenshot from the radio over USB (CDC serial), using the OpenGD77
|
||||||
|
# screen grabber. Runs natively (USB serial is not available inside Docker) and
|
||||||
|
# sets up a self-contained Python venv (pyserial + pillow) on first use.
|
||||||
|
#
|
||||||
|
# The radio must be powered on, running the firmware, and connected via USB.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./screenshot.sh # auto-detect port -> screenshots/screenshot-<timestamp>.png
|
||||||
|
# ./screenshot.sh vfo-7seg # -> screenshots/vfo-7seg.png
|
||||||
|
# ./screenshot.sh -d /dev/cu.usbmodem1234 [name] # explicit serial port
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
GRABBER="$REPO_DIR/MDUV380_firmware/tools/gd-77_screen_grabber.py"
|
||||||
|
VENV="$REPO_DIR/MDUV380_firmware/tools/.venv"
|
||||||
|
OUT_DIR="$REPO_DIR/screenshots"
|
||||||
|
|
||||||
|
# ---- optional explicit device (-d /dev/...) -------------------------------
|
||||||
|
DEVICE=""
|
||||||
|
if [[ "${1:-}" == "-d" ]]; then
|
||||||
|
DEVICE="${2:-}"; shift 2 || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- auto-detect the radio's serial port ----------------------------------
|
||||||
|
if [[ -z "$DEVICE" ]]; then
|
||||||
|
case "$(uname -s)" in
|
||||||
|
Darwin) DEVICE="$(ls /dev/cu.usbmodem* 2>/dev/null | head -1 || true)" ;;
|
||||||
|
*) DEVICE="$(ls /dev/ttyACM* 2>/dev/null | head -1 || true)" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
if [[ -z "$DEVICE" ]]; then
|
||||||
|
echo "!! No radio serial port found." >&2
|
||||||
|
echo " Connect the radio via USB (powered on, running firmware) and retry, or pass one:" >&2
|
||||||
|
echo " ./screenshot.sh -d /dev/cu.usbmodemXXXX" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- one-time Python venv with the grabber's dependencies ------------------
|
||||||
|
if [[ ! -x "$VENV/bin/python" ]]; then
|
||||||
|
echo "==> First run: creating Python venv with pyserial + pillow..."
|
||||||
|
python3 -m venv "$VENV"
|
||||||
|
"$VENV/bin/pip" install --quiet --upgrade pip
|
||||||
|
"$VENV/bin/pip" install --quiet pyserial pillow
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- output name -----------------------------------------------------------
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
NAME="${1:-screenshot-$(date +%Y%m%d-%H%M%S)}"
|
||||||
|
OUT="$OUT_DIR/$NAME"
|
||||||
|
|
||||||
|
echo "==> Grabbing from $DEVICE"
|
||||||
|
"$VENV/bin/python" "$GRABBER" -d "$DEVICE" -o "$OUT"
|
||||||
|
echo "==> Saved: $OUT.png"
|
||||||
Loading…
Reference in a new issue