Skip to main content

Carefree, observable plotting of HP-GL files on HP pen plotters over RS-232.

Project description

hpgl-buddy

Carefree, observable plotting of HP-GL files on HP pen plotters over RS-232.

It does not just shove a file at the plotter: it validates the file, splits it to fit the device buffer, feeds it so the buffer never overflows and an inked pen never stalls mid-stroke, watches the device for faults the whole time, and logs every exchange so a run can be understood and troubleshooted from the log alone.

Supported device: HP 7475A (RS-232). New devices are added as declarative profiles (see Extending); HP-IB is planned.


Install

Requires Python 3.13 and a USB-serial adapter (macOS: use the /dev/cu.* device).

pip install -e .          # editable, for development
# or build a wheel:
python -m build --wheel   # -> dist/hpgl_buddy-*.whl  (or: tox -e build)

pyserial is the only runtime dependency.


Quick start

# 1. Validate a file offline (no plotter needed)
hpgl-buddy check drawing.hpgl

# 2. Check the plotter is alive and interpret its status
hpgl-buddy status --port /dev/cu.usbserial-XXXX

# 3. Plot it (verbose shows every byte/ESC exchange)
hpgl-buddy -v plot drawing.hpgl --port /dev/cu.usbserial-XXXX

# 4. Generate and plot a built-in demo
hpgl-buddy demo --pens 6 --out demo.hpgl
hpgl-buddy plot demo.hpgl --port /dev/cu.usbserial-XXXX

Serial defaults: 9600 8N1, no flow control (configurable). Flow control is off by default because XON/XOFF corrupted the exchange on the on-site adapter; enable it with --xonxoff if your cabling needs it.


Commands

Command What it does
check FILE Offline HP-GL syntax check. No device. Exit non-zero on errors.
status Ad-hoc healthcheck: identification, buffer, status byte, errors, limits - all interpreted.
plot FILE Safe, buffer-aware plotting with progress + end-of-run report.
monitor on|off|watch Switch monitor mode (computer port) or stream the echoed bytes (terminal port).
demo Generate demo HP-GL (--scene card shapes/fills/labels/colours, or --scene house a continuous one-line drawing).

Global: -v/--verbose (DEBUG, incl. raw ASCII+hex wire dumps), --version.

Serial options (on status/plot/monitor): --port, --model (default hp7475a), --baud, --framing (e.g. 8N1), --timeout, --xonxoff, --rtscts.

plot options

  • --on-error abort|prompt|continue - on a reported error: stop and park the pen (default), ask interactively, or auto-recover (ESC.K discard -> IN -> replay the tracked state preamble -> carry on).
  • --live-hpgl-verify off|chunk|pu - optional on-device HP-GL error checking (see Verification). Default off.
  • --ignore-syntax-errors - plot even if the offline check found errors.
  • --stats-json PATH - write run statistics as JSON (- for stdout).

monitor (two ports)

The 7475A enables monitor mode via an ESC sequence on the computer (data) port, then echoes received bytes out a separate terminal port. So:

# stream the echo on the terminal port, enabling monitor on the computer port first
hpgl-buddy monitor watch --port /dev/cu.TERMINAL --command-port /dev/cu.COMPUTER --enable

watch prints every byte as binary, hex, decimal, and ASCII/control-name.


How plotting works

file -> parse -> offline syntax check -> plan into chunks -> stream to device -> report
  1. Parse the bytes into instructions, each tagged with its source line and sequence index (so any error names the exact command).
  2. Syntax check offline; plot refuses a file with errors unless --ignore-syntax-errors.
  3. Plan into chunks of <=256 bytes, split only at instruction boundaries (never inside a command), each tagged whether it ends with the pen up.
  4. Stream: a chunk is sent only when ESC.B reports enough free buffer space. This one gate both prevents overflow and keeps the buffer fed, so a long pen-down stroke spanning several chunks never underruns (an underrun would park an inked pen and blot).
  5. Watch (always on, after each chunk): ESC.E for I/O faults (overflow / framing / data loss) and ESC.O for environmental faults (paper lever or pinch wheels raised -> abort; VIEW pressed -> warn). Both are immediate and never stall the pen.
  6. Confirm: a final OS;OE;OI; tailgate waits for the pen to physically finish and reports the end status / any HP-GL error.
  7. Report instructions/chunks/bytes sent, elapsed time, recovered errors, and warnings (and the same as JSON via --stats-json).

Verification

HP-GL/syntax errors are a property of the file (already validated offline), so on-device HP-GL error checking is optional and off by default. When enabled it never stalls the pen - it uses a one-deep tailgate: the OS;OE;OI; query is prefixed to the chunk after a pen-up, so its verdict reports the previous chunk while the current one is already drawing.

  • chunk - check at pen-up chunk boundaries.
  • pu - break a chunk at every pen-up so each completed stroke is checked (more, smaller chunks).

Either way you learn a chunk is clean within ~1 chunk, and a reported error names the span of chunks it could belong to with all candidate instructions.

Limits to know

  • No pen sensing on the 7475A: a missing or fallen pen plots dry and is not detectable by any status query. Pre-load the pens your file uses. (plot warns about this.)

Architecture

Thoroughly separated layers, each replaceable on its own:

hpgl/       parse HP-GL bytes into a Program; offline syntax check
devices/    declarative TOML profiles + abstract Device base (registry)
interface/  Transport abstraction + pyserial RS-232 implementation
status/     ESC + HP-GL command builders, response parsers, status interpretation, monitor
execution/  planner (Program -> chunks) + flow control + executor + progress/report
demo/       demo HP-GL generators

The authoritative design rationale (with HP manual citations) lives in DESIGN.md; the running decision log is the "Follow-up steering" section of TASK-1-BASIC-IMPLEMENTATION.md.

Extending

Add a simple device by dropping a <model>.toml into devices/profiles/ (buffer size, pen count, serial defaults, capabilities, pen_sensing). A device with unusual behavior can subclass Device and register it. The interface layer is transport-agnostic, so HP-IB can be added as another Transport without touching the rest.


Development

tox            # run the test suite (Python 3.13)
tox -e build   # build the wheel

Dependencies are managed two-file style: requirements-rough.txt (hand-maintained, loose top-level) is frozen into a fully-pinned requirements.txt by the dependencies_update GitHub Actions workflow. A Dockerfile provides a reproducible build/test image (not for serial I/O - hardware is not reachable from a container).

Conventions: extensive logging (no print), ASCII-only output, descriptive names, and errors that state what happened, where, and why.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hpgl_buddy-1.0.0.tar.gz (52.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hpgl_buddy-1.0.0-py3-none-any.whl (55.5 kB view details)

Uploaded Python 3

File details

Details for the file hpgl_buddy-1.0.0.tar.gz.

File metadata

  • Download URL: hpgl_buddy-1.0.0.tar.gz
  • Upload date:
  • Size: 52.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hpgl_buddy-1.0.0.tar.gz
Algorithm Hash digest
SHA256 45e9ad5edfe66445b4a3c67cf0e0d27367500197b88206d28225d50ddadb1eea
MD5 2f87718c33ba2964ceeb2ab58103517c
BLAKE2b-256 97bbec31b027268a41ed9febb8c0710fe70de3fa46cc8b6e856cabe998f3d5d2

See more details on using hashes here.

Provenance

The following attestation bundles were made for hpgl_buddy-1.0.0.tar.gz:

Publisher: release.yml on hpgl-buddy/hpgl-buddy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hpgl_buddy-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: hpgl_buddy-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 55.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hpgl_buddy-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d9624f1b7e07a38615fe0ff1cebdb353b2bea4d5602c3579a20eaf7a5e9b253f
MD5 1ad155f3eb09b8029ca3cdd3d7f1a25c
BLAKE2b-256 64734775d253cce1bb2953c8f462193e8968e02a056d028c4e6827334fe7c38e

See more details on using hashes here.

Provenance

The following attestation bundles were made for hpgl_buddy-1.0.0-py3-none-any.whl:

Publisher: release.yml on hpgl-buddy/hpgl-buddy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page