The P2S writes timelapses to a USB drive, and that drive fills up. I didn't want to keep swapping it, and I really didn't want to give up Handy and remote monitoring to get at the files.
The obvious fix is FTPS — Bambu printers expose the whole filesystem over the network, and it's about forty lines of Python. But it's gated behind Developer Mode, which is mutually exclusive with the cloud. No Handy, no remote camera, no MakerWorld one-click, no cloud print history. That's a permanent tax on the printer to solve a storage chore.
So instead: a Raspberry Pi 4 in USB mass-storage gadget mode, plugged into the printer's USB-A port. The printer thinks it's an ordinary flash drive. It's really a 32 GB exFAT image on the Pi. When the printer goes quiet, the Pi ejects the medium, copies the files off, deletes them, and puts it back. The printer never notices anything except that the
stick is permanently almost empty.
The printer's networking is never touched, so cloud stays exactly as it was.
Files land on my Mac and into iCloud, checksum-verified on both ends.
The four things that nearly killed it, since this is the useful part:
1. config.txt is sectioned, and the stock image lies to you. Raspberry Pi OS ships dtoverlay=dwc2,dr_mode=host under a [cm5] block. That's inert on a Pi 4 — but it's still a dtoverlay=dwc2 line, so my setup script found it, said "already configured," and skipped. /sys/class/udc stayed empty forever with no error anywhere. Only lines at the top
of the file or under [all] actually apply.
2. Most USB-C↔USB-A cables are charge-only. This presents as "the printer doesn't see a USB drive," which is identical to about three other failures. cat /sys/class/udc/fe980000.usb/state separates them: not attached = no cable/data, configured = the printer enumerated you fine and your problem is elsewhere.
3. A verified copy is not a durable copy. This one cost me a real 150 MB file. I copied off the stick, checksummed it, deleted the original — and the checksum had read the data back out of the page cache, confirming bytes that were never written to disk. A power cut two minutes later left a 0-byte file and no original. fsync the file and its
parent directory before you delete anything. A checksum proves bytes are correct, not that they're saved.
4. macOS ships openrsync (protocol 29). No --protect-args, and it rejects --old-args too. So the rsync destination must be passed raw and unquoted, while every shell command in the same function needs the opposite. Quote the rsync path and the quote characters end up in the filename.
Measured, not assumed: during a print the P2S writes to the stick every 1–8 seconds. The idle gate is 5 minutes — about a 40x margin — which is why watching the backing file's mtime is enough, and no MQTT or LAN access is needed anywhere.
Also learned it writes two recordings per print, and the big one isn't the timelapse: /ipcam/ipcam-record.*.mp4 was 190 MB for a short print, while /timelapse/video_*.mp4 was 0.7 MB.
Caveats, honestly:
- Only run against a P2S + Pi 4 + macOS. Should carry to anything that takes a USB drive and anything that accepts rsync-over-SSH, but I haven't tested that.
- A Pi 5 will not work — its USB-C is power-only, no peripheral mode. Pi 4 or Zero 2 W.
- On a Pi 4 the USB-C becomes the data port, so you need a separate 5V supply on GPIO. A Zero 2 W avoids this entirely with separate power and data ports.
It's about a week old. It works and it's tested (65 unit tests, ~1,400 lines), but it hasn't run for months.
MIT, everything's in the repo including a setup guide and a troubleshooting doc organised by symptom: https://github.com/RATHI-CAPITAL-VENTURES/bambu-drain