Unattended SHOTOVER drive-label printer. A modern (Python 3, open-source)
remake of the old labels.py Tkinter tool from the SerialNumbers share.
Instead of popping up a prompt, it reads every field from label.json,
allocates the next serial number, renders a 24 mm round label to a PDF, and
prints it on the USB-connected Brother QL-810W via SumatraPDF (no Adobe
Acrobat). Each label is recorded to the shared master list and to a local CSV
mirror that keeps working even when the network drive is offline.
setup.bat— double-click it (or run from a terminal). On a fresh Windows 11 machine it installs Python if needed, creates a virtual environment, installs dependencies, downloads SumatraPDF, seeds the local records mirror, and walks you through installing the Brother printer driver. You can re-run it any time to repair or update the install.- Edit
label.json— set the customer, purpose, hardware, who prepared it, and the box serial for the label you want to print. manualRun.bat— prints one label usinglabel.jsonand records the serial number.
{
"printer_name": "Brother QL-810W",
"cage_code": "5ET05",
"qr_url": "churchillnavigation.com/specifications",
"copies": 1,
"label_media": "0.94\" Dia",
"print_scale": "noscale",
"master_records_path": "Z:\\SerialNumbers\\SERIAL_NUMBERS.txt",
"label": {
"customer": "Australia",
"purpose": "Master",
"hardware": "Other",
"prepared_by": "Max",
"box_serial": "000000"
}
}| Key | Meaning |
|---|---|
printer_name |
Installed printer to print to. Matched as a substring, so Brother QL-810W matches Brother QL-810W Printer. Change this if your printer has a different name. |
cage_code |
CAGE code printed on the label. |
qr_url |
URL encoded into the QR code. |
copies |
How many copies to print per run (default 1). |
label_media |
The loaded label roll, as a substring of a Brother paper-kind name (e.g. 0.94" Dia for the DK-1218 24 mm round), or a numeric driver paper-kind id. This makes the printer use the right media and avoids the "roll does not match" prompt. |
print_scale |
SumatraPDF scaling: noscale (default, exact size — correct for die-cut labels), fit, or shrink. |
master_records_path |
The shared, authoritative serial list. The program also keeps a local copy and works when this path is offline. |
label.customer |
Top line on the label. |
label.purpose |
Second line (the old "Purpose"/description). |
label.hardware |
Hardware type (recorded, not printed). |
label.prepared_by |
Who prepared it (recorded, not printed). |
label.box_serial |
"Box #" printed on the label (leave "" to omit it). |
Note: the internal serial number is recorded but, exactly as in the original, is not printed on the label — the "Box #" is what appears.
Run these via manualRun.bat (which passes arguments straight through):
| Command | What it does |
|---|---|
manualRun.bat |
Print a real label and record the serial number. |
manualRun.bat --test-print |
Print a label for testing. Nothing is recorded and no serial is consumed. |
manualRun.bat --no-print |
Render the PDF only (to local/test_label.pdf). No print, no record. |
manualRun.bat --self-test |
Run the unit-test suite. Never prints, never records. |
manualRun.bat --verbose |
Add --verbose to any of the above for DEBUG output on the console. |
Two stores are kept in sync:
- Master —
Z:\SerialNumbers\SERIAL_NUMBERS.txt. Shared and authoritative. It is append-only: the program only ever adds lines, in the exact comma format already in the file, and never deletes or rewrites it. - Local mirror —
logs/serial_numbers.csv. A full copy of the same data (seeded from the master on setup) plus asyncedcolumn.
If the Z drive is offline, the program logs it and keeps going using the local
mirror; the new label is written locally with synced=false. The next time the
master is reachable, those rows are appended to it ("the master is updated to
match the local CSV") and marked synced=true.
logs/current.log— verbose log of the most recent run only.logs/logPrev.log— the previous up-to-5 runs, newest first, each under a===== RUN ... =====banner.
Logging is intentionally verbose to make debugging (by people or agents) easy.
driveLabelPrinter/
setup.bat One-shot installer / repairer (living file)
manualRun.bat Everyday wrapper around the program
label.json The inputs for the next label
README.md This file (living)
AGENTS.md Notes for engineers/agents (living)
.gitignore
src/
driveLabelPrinter.py Entry point + CLI + orchestration
config.py Loads/validates label.json
records.py Master + local CSV + offline sync
render.py PDF label rendering (vector QR)
printing.py Printer detection + SumatraPDF printing
logsetup.py Verbose logging + run rotation
bootstrap.py Setup helper (run by setup.bat)
paths.py Central path definitions
requirements.txt Python dependencies
test_*.py Unit tests
assets/ Bundled font + logo
drivers/ Brother driver installer (bsq16aw140aus.exe)
bin/ SumatraPDF.exe (downloaded by setup.bat)
local/ Virtual env + rendered PDFs (git-ignored)
logs/ Logs + local CSV mirror (git-ignored)
- "Printer ... is not installed" — connect the Brother QL-810W via USB and
run
setup.batto install the driver. Confirm the name in Windows Settings > Printers & scanners matchesprinter_nameinlabel.json. - "The roll of labels or tape ... does not match" —
label_mediainlabel.jsondoes not match the roll that is loaded. Set it to a substring of the correct Brother media name (e.g.0.94" Diafor the 24 mm round). The available names are logged at DEBUG inlogs/current.logwhen a media lookup fails; you can also list them in Windows Printing Preferences. - Label didn't print — the rendered PDF is at
local/last_label.pdf; open and print it manually. Checklogs/current.logfor the SumatraPDF exit code. - Z drive offline — expected and handled; the run still records locally and
syncs later. You'll see a
Master ... not accessiblewarning in the log. - SumatraPDF missing — re-run
setup.bat, or download the 64-bit portable build from https://www.sumatrapdfreader.org/download-free-pdf-viewer, rename it toSumatraPDF.exe, and place it insrc/bin/.
- DK-1218 — 0.94" round labels (current).
- DK-1201 — old 3.5 x 1 style.
Set the printer's default paper size to 0.94" Round and Quality to "prefer quality" in Windows Printing Preferences.