Skip to content

Navigation Menu

Sign in
Sign up

Thread the resolved printer through rendering for correct per-model output - #56

Open
willumpie82 wants to merge 2 commits into
labelle-org:main from
willumpie82:fix/labelmanager-wireless-pnp-support
Open

Thread the resolved printer through rendering for correct per-model output #56
willumpie82 wants to merge 2 commits into
labelle-org:main from
willumpie82:fix/labelmanager-wireless-pnp-support

Conversation

@willumpie82

@willumpie82 willumpie82 commented Aug 28, 2026

Copy link
Copy Markdown

Summary

Companion to labelle-org/labelle#156, which validates real calibration data for the DYMO LabelManager Wireless PnP (previously an unvalidated placeholder, ~7.1 px/mm, that produced "squished"/incorrectly-scaled output for that model).

That fix only has an effect if labelle-web actually uses it. Right now, rendering (preview and the print payload) and printing each construct a plain DymoLabeler, ignoring device-specific calibration entirely — so a model with its own margins/resolution renders and prints using generic defaults regardless of which printer is actually selected.

  • label_builder.py's render functions now accept an optional resolved device, used via DymoLabeler.for_device() when given. Also passes the labeler's real per-model vertical resolution into RenderContext, so the preview's mm-ruler labels match reality for a model whose cross-tape and along-tape resolutions genuinely differ (previously always assumed one shared PIXELS_PER_MM for both axes).
  • printer_service.py's actual print path (print_label, print_bitmap) builds its DymoLabeler the same way, so what's printed always matches the resolved device's own protocol.
  • app.py's preview and cut-mark-print paths resolve a device via a new resolve_device_for_render (best-effort: falls back to generic rendering for a virtual printer, unresolved printerId, or a scan failure, rather than turning a preview request into an error the way an actual print correctly would).
  • Adds 24mm as a selectable tape size (client + server validation) — physically supported per the LabelManager Wireless PnP's own datasheet, though only for models whose SUPPORTED_TAPE_SIZES_MM actually includes it; selecting it for one that doesn't still fails clearly at print time. A fully correct fix would query the selected device's own supported sizes instead of this static list — out of scope here.

Dependency note

This is written against labelle's current main API (DymoLabeler.for_device()). labelle#156 targets develop instead (per a maintainer's standing preference for device-specific work), whose DymoLabeler API differs meaningfully (no for_device(), height_pxget_label_height_px(), preview engines take the labeler instance directly, etc.) — so depending on which branch labelle-org ends up releasing the fix from, this PR may need adjusting to match. Flagging that now rather than have it be a surprise in review.

Test plan

  • Full server test suite: 300/300 passing
  • Exercised end-to-end against real hardware: correct preview mm-labels, correct print positioning/sizing on 24mm tape
  • ruff check clean (pre-existing findings elsewhere in the codebase left untouched, no config enforces them here)

🤖 Generated with Claude Code

Willem Oldemans added 2 commits August 28, 2026 22:05
Rendering (preview and the actual print payload) and printing each
constructed a plain DymoLabeler, ignoring model-specific subclasses like
DymoLabelManagerWirelessPnP (labelle-org/labelle#<PR>) entirely -- so a
model with its own calibration/margins would render and print using the
generic (wrong, for it) defaults regardless of which printer was
actually selected.
- label_builder.py's render functions now accept an optional resolved
 `device`, used via DymoLabeler.for_device when given. Also passes the
 labeler's real per-model vertical resolution into RenderContext, so
 the preview's mm-ruler labels match reality for a model whose
 cross-tape and along-tape resolutions genuinely differ (previously
 always assumed the same PIXELS_PER_MM for both axes).
- printer_service.py's actual print path (print_label, print_bitmap)
 now builds its DymoLabeler the same way, so what's printed always
 matches the resolved device's own protocol.
- app.py's preview and cut-mark-print paths resolve a device via the
 new resolve_device_for_render (best-effort: falls back to generic
 rendering for a virtual printer, unresolved printer_id, or scan
 failure, rather than turning a preview request into an error the way
 an actual print correctly would).
Also adds 24mm as a selectable tape size (client + server validation):
physically supported per the LabelManager Wireless PnP's own datasheet,
though only for models whose SUPPORTED_TAPE_SIZES_MM actually includes
it -- selecting it for one that doesn't still fails clearly at print
time. A fully correct fix would query the selected device's own
supported sizes instead of this static list; out of scope here.
Full test suite: 300/300 passing (three pre-existing tests needed
`git config --global --add safe.directory` in the sandbox they were
verified in -- a testing-environment quirk, not a code issue).
Adds an "autoCut" checkbox to the settings bar that sends the printer's
hardware cut command after printing, wired through printer_service.py's
two print call sites as cut=settings.get("autoCut", False).
Deliberately kept separate from the persisted per-printer settings and
from the existing cutMark feature (which only draws a dotted line for a
manual cut): some models crash if sent an unconditional cut with no
cutter installed (labelle-org/labelle#81), so this is a non-persisted,
per-session toggle that defaults off and resets on reload or printer
switch rather than silently following a printer selection to a unit
that can't handle it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant

AltStyle によって変換されたページ (->オリジナル) /