Repository navigation
Fix dual-mode printers (SC03h) and add desktop and web apps - #90
Open
GabrielCatDev wants to merge 8 commits into
Open
GabrielCatDev wants to merge 8 commits into
GabrielCatDev wants to merge 8 commits into
Conversation
Bug: requirements pinned numpy<2.0, which has no wheels for Python 3.13 (Debian 13). pip had to build it from source and failed, so the CLI could not be installed. The code works with numpy 2, which opencv-python 4.x supports. Changes made by Claude (Claude Code). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Compared against iPrint 1.3.87, which is what these printers are made for: - Energy was sent big-endian; iPrint sends it little-endian (5000 -> 88 13). Only symmetric values such as the 0xffff default worked. - The print speed (0xbd) was never set before printing, so the printer kept whatever speed it had. Add cmd_set_speed() and a speed argument (re-sent every 200 rows, as iPrint does), plus --speed in print.py. - cmd_feed_paper() did not feed paper: it sent 0xbd, the speed command. Replace it with cmd_set_speed(FEED_SPEED), which produces the same bytes. - Send "update device" (0xa9) so the printer applies energy and speed. - Select image mode (0xbe 00) or text mode (0xbe 01) instead of always using text mode through the misnamed cmd_apply_energy(). - Add the battery query command (0xba). Changes made by Claude (Claude Code). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugs found with an SC03h on Debian 13 (BlueZ 5.82): - The SC03h is dual-mode (classic SPP + BLE). BlueZ tried a classic connection and failed with "br-connection-profile-unavailable". Set the device's PreferredBearer to "le" before connecting (needs "Experimental = true" in /etc/bluetooth/main.conf) and retry a couple of times if BlueZ still picks the classic bearer. - BlueZ negotiated an MTU of 512 and the whole job was written in ~1 s using 509-byte packets, which can overflow the printer's buffer and give blank prints. Cap packets at 180 bytes like iPrint. - The flow control notifications (pause/resume) were ignored. Pause sending while the printer reports that its buffer is full. - The SC03h never sends the "ready" notification, so every print ended with a 30 s timeout. Use the answer to the state query that ends every job as the "done" signal instead. New features: - PrinterConnection keeps a connection open between prints and reports disconnections, so apps can stay connected like the phone app does. - Parse the printer state (no paper, cover open, overheating, low battery, charging) and the battery level into PrinterStatus. Changes made by Claude (Claude Code). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A libadwaita app (Spanish UI) that: - Finds the printer, connects and stays connected like the phone app, reconnecting on its own if the link drops. - Shows the battery level and warns about low battery, no paper, open cover or overheating (the SC03h prints blank pages with low battery). - Prints images (SVG too), PDFs (pdftoppm), office documents (LibreOffice) and text files, with an exact preview of the dots that will be printed. - Offers photo dithering or sharp text, brightness, contrast, margin cropping, rotation, thicker strokes and a page range. - Uses the official app's concentration levels and print speed. - Can integrate itself with the desktop and the context menu of Files. Image processing is pure Python plus GdkPixbuf so the app runs on the system Python without numpy or OpenCV. Changes made by Claude (Claude Code). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
appimage/build.sh produces dist/CatPrinter-<version>-x86_64.AppImage (about 1 MB). It bundles the app and its pure Python dependencies (bleak 0.14, dbus-next) and runs on the system's Python 3 and GTK 4, so it keeps working when the distribution upgrades Python. AppRun explains which Debian packages to install if GTK 4 or libadwaita are missing. Running the AppImage with --instalar (or using the app menu) copies it to ~/.local/bin and adds it to the application menu, to "Open With" and to the context menu of Files. Changes made by Claude (Claude Code). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Explain how to build and install the AppImage, the new --speed option, how to fix "br-connection-profile-unavailable" on dual-mode printers such as the SC03h, and that blank prints usually mean a low battery. Changes made by Claude (Claude Code). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/ is a static web app, ready for GitHub Pages: - js/protocol.js ports catprinter/cmds.py and status.py; its output is byte-for-byte identical to the Python version. - js/printer.js connects over Web Bluetooth with the same behavior as PrinterConnection: 180-byte packets, flow control, the state answer as the "done" signal, battery and state flags, and automatic reconnection. - js/imaging.js ports the GUI's processing: images, PDFs (pdf.js) and text, margin cropping, rotation, dithering and thicker strokes. - The PWA works offline, can be installed, receives files from the Android share sheet and handles "Open With" when installed. - Browsers without Web Bluetooth (Firefox, Safari, iOS, Chrome on Linux without the flag) get a page explaining the alternatives. Changes made by Claude (Claude Code). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugs: - The service worker cached every same-origin GET response, not only the app's own files, so other requests ended up stored on disk. - Files shared from other apps were written to a cache until the page read them; if the page never read them, they stayed there. Now only the app shell (and the versioned pdf.js library) is cached. Shared files are kept in the service worker's memory and handed to the page with postMessage. The old shared-files cache is deleted on update. Files opened, dropped or pasted were never stored and still aren't. Changes made by Claude (Claude Code). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi! I have an SC03h printer and this project didn't work with it on Debian 13. This PR fixes what was going wrong and adds two optional apps on top of the library.
What was wrong
br-connection-profile-unavailable. catprinter now asks BlueZ to use BLE (needsExperimental = truein/etc/bluetooth/main.confon BlueZ ≥ 5.80) and retries if BlueZ picks classic Bluetooth anyway.0xffffworked.cmd_feed_paper()actually sent the speed command (0xbd), not a paper feed. It's nowcmd_set_speed()and produces the same bytes.0xa9) that applies energy and speed was missing.numpy<2.0has no wheels for it.What's new
--speedoption inprint.py.PrinterConnection, so apps can keep a connection open between prints.appimage/build.sh). Its UI is in Spanish.docs/that prints from Chrome/Edge over Web Bluetooth. Its command builder produces byte-identical output to the Python code.The README documents all of this.
Things to know
print.pyworks on it. I couldn't test the web app on real hardware, and the desktop app's persistent connection only briefly.ble.pyE203,img.pyE302) were already there.🤖 Generated with Claude Code