Skip to main content

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

Project description

hpgl-buddy

PyPI version Python versions License: MIT

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 devices:

  • HP 7475A (RS-232)

New devices are added as declarative profiles (see Extending); HP-IB is planned.


Install

pip install hpgl-buddy

Requires Python 3.13 and a USB-serial adapter (on macOS use the /dev/cu.* device). pyserial is the only runtime dependency. To work on hpgl-buddy itself, see Development.


Quick start

# 1. Generate a built-in demo to a file (no plotter needed)
hpgl-buddy demo --pens 6 --out demo.hpgl

# 2. Validate it offline (no plotter needed)
hpgl-buddy check demo.hpgl

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

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

Sample HP-GL files live in examples/.

Serial defaults: 9600 8N1, no flow control (configurable). Flow control is off by default; enable it with --xonxoff if your cabling needs it.


Commands

Command What it does
status Ad-hoc healthcheck: identification, buffer, status byte, errors, limits - all interpreted.
check FILE Offline HP-GL syntax check. No device. Exit non-zero on errors.
plot FILE Safe, buffer-aware plotting with progress + end-of-run report.
monitor enable|disable|watch Enable/disable monitor mode (computer port) or stream the echoed bytes (terminal port).
demo Generate demo HP-GL: --scene card (shapes/fills/labels/colours grid) or --scene house (a one-line drawing emitted as a single giant PD instruction - the >1024-byte oversized-instruction case, streamed in sub-blocks).

Global: -v/--verbose (DEBUG, incl. raw ASCII+hex wire dumps), -V/--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 the bytes it receives out a separate terminal port - so it's two single-purpose commands, one per port:

hpgl-buddy monitor enable  --port /dev/cu.COMPUTER   # turn monitor mode on (data port)
hpgl-buddy monitor watch   --port /dev/cu.TERMINAL   # stream the echo (terminal port)
hpgl-buddy monitor disable --port /dev/cu.COMPUTER   # turn it off when done

There are two monitor modes (enable --mode received|parsed): received (default, mode 1 in the documentstion) echoes every byte as it arrives, including ESC device-control sequences; parsed (mode 0 in the documentation) echoes only HP-GL as the plotter parses it from the buffer. 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). An instruction larger than the buffer (e.g. a single huge PD polyline) is streamed across several ESC.B-gated sub-blocks - never split as HP-GL, since the plotter reassembles the byte stream as it parses - so it plots like any other.
  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.)
  • Throughput is bound by the baud rate: a huge pen-down instruction with very short segments can outrun a 9600-baud link no matter how we feed it (the pen draws faster than bytes arrive). hpgl-buddy always feeds as fast as the buffer allows; raise the baud if a dense drawing dwells.

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 full design rationale, with HP manual citations, lives in DESIGN.md. To embed hpgl-buddy as a library (e.g. a GUI), see INTEGRATION.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

pip install -e . -r requirements-dev.txt   # editable install + pinned dev tooling
tox                                         # run the test suite (Python 3.13)
tox -e build                                # build the sdist + wheel

Dependencies follow a loose-rough -> pinned pattern, frozen in clean environments by the dependencies_update GitHub Actions workflow:

  • runtime: requirements-rough.txt (hand-maintained, loose; kept in sync with [project.dependencies]) -> requirements.txt (fully pinned).
  • dev / CI tooling: requirements-dev-rough.txt (loose: pytest, tox, build, twine) -> requirements-dev.txt (fully pinned), needed only in CI and dev environments.

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.

Vibe-code disclosure

This library is written heavily with Claude. The design is decided upon by the initial human-author. All hands-on tests are conducted by a human-operator.

The human-conducted code review (HCCR) is an optimisation of a sort. It will be done in the right time.

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.5.0.tar.gz (59.9 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.5.0-py3-none-any.whl (60.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: hpgl_buddy-1.5.0.tar.gz
  • Upload date:
  • Size: 59.9 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.5.0.tar.gz
Algorithm Hash digest
SHA256 0a51dbbb88829a9d9bcbf85ea1a5bbdcc359f374e07c3450c76fd65103bab7de
MD5 369963a7a766c50379bb04aab6ca51a2
BLAKE2b-256 716c7e2398df241116935278c559c73dff5c087bea56eede1b92c4d8f74f4962

See more details on using hashes here.

Provenance

The following attestation bundles were made for hpgl_buddy-1.5.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.5.0-py3-none-any.whl.

File metadata

  • Download URL: hpgl_buddy-1.5.0-py3-none-any.whl
  • Upload date:
  • Size: 60.1 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.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d1eacff6c48fbb120ea47c4f4e5fc9cde1eb504afa73629cd5b22f0efadd4f9b
MD5 5ef88ce14fb48130fd75130aea9f407a
BLAKE2b-256 23572ef387709133a216ccc6a893f388a10ad5ba1649c1fc16e6e35e46ed3ca2

See more details on using hashes here.

Provenance

The following attestation bundles were made for hpgl_buddy-1.5.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