Printer Debug 2

This commit is contained in:
2026-09-07 11:22:14 +10:00
parent eb986581e4
commit b1a793302d
3 changed files with 123 additions and 1 deletions
+105
View File
@@ -0,0 +1,105 @@
/**
* Renders a badge and prints it, showing everything on the way through.
*
* For working out why a printer will not accept a job, without going through the
* kiosk or the admin console. Run inside the container:
*
* docker compose exec visitor-signin node scripts/print-test.mjs
* docker compose exec visitor-signin node scripts/print-test.mjs --label 62x100
* docker compose exec visitor-signin node scripts/print-test.mjs --dry
*
* Options:
* --site N which site to use (default: the first one)
* --label ID override the roll id sent to the printer, without saving it
* --rotate DEG override the rotation, without saving it
* --dry render only, do not print
*/
import fs from 'node:fs';
import { execFileSync } from 'node:child_process';
import db from '../src/db.js';
import config from '../src/config.js';
import * as printer from '../src/printer.js';
function arg(name, fallback = null) {
const i = process.argv.indexOf(`--${name}`);
return i > -1 && process.argv[i + 1] && !process.argv[i + 1].startsWith('--')
? process.argv[i + 1]
: fallback;
}
const has = (name) => process.argv.includes(`--${name}`);
const siteId = Number(arg('site', 0));
const site = siteId
? db.prepare('SELECT * FROM sites WHERE id = ?').get(siteId)
: db.prepare('SELECT * FROM sites ORDER BY id LIMIT 1').get();
if (!site) {
console.error('No sites exist yet.');
process.exit(1);
}
if (arg('label')) site.printer_label = arg('label');
if (arg('rotate')) site.printer_rotate = Number(arg('rotate'));
const label = printer.labelFor(site);
const target = `tcp://${site.printer_host}:${site.printer_port || 9100}`;
console.log('');
console.log(` site ${site.name}`);
console.log(` printer ${site.printer_model || 'QL-820NWB'} at ${target}`);
console.log(` server printing ${site.printer_enabled ? 'on' : 'OFF — the kiosk would print instead'}`);
console.log(` badge ${site.badge_width_mm} x ${site.badge_height_mm} mm, rotate ${site.printer_rotate || 0}`);
console.log(` roll setting ${site.printer_label || '(unset)'} -> --label ${label}`);
console.log(` red requested ${Boolean(site.badge_accent)}, will print ${printer.accentWillPrintRed(site)}`);
const png = await printer.renderBadgePng(printer.sampleVisit(site), site);
const file = '/tmp/print-test.png';
fs.writeFileSync(file, png);
console.log(` rendered ${png.readUInt32BE(16)} x ${png.readUInt32BE(20)} dots -> ${file}`);
if (!site.printer_host) {
console.error('\n No printer address set for this site. Set one in Admin -> Sites -> Edit.');
process.exit(1);
}
if (has('dry')) {
console.log('\n --dry given, so nothing was sent.\n');
process.exit(0);
}
const args = [
'--backend', 'network',
'--model', site.printer_model || 'QL-820NWB',
'--printer', target,
'print',
'--label', label,
file,
];
console.log('');
console.log(` running: ${config.printing.command} ${args.join(' ')}`);
console.log('');
try {
const out = execFileSync(config.printing.command, args, {
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'pipe'],
timeout: config.printing.timeoutMs,
});
console.log(out.trim() || ' (no output)');
console.log('\n Sent. If nothing came out, the printer rejected it silently — check its display.\n');
} catch (err) {
console.error(' FAILED\n');
console.error(`${err.stdout || ''}${err.stderr || ''}`.trim() || err.message);
console.error('');
console.error(' Roll ids this printer understands:');
console.error(' 62 62 mm continuous, black only');
console.error(' 62red 62 mm continuous, black and red (DK-22251)');
console.error(' 62x100 62 x 100 mm DIE-CUT (pre-cut labels, not a continuous roll)');
console.error(' 62x29 62 x 29 mm die-cut');
console.error('');
console.error(' A continuous roll sent a die-cut id, or the reverse, is refused as a wrong roll.');
console.error(' Try: node scripts/print-test.mjs --label 62x100');
console.error('');
process.exit(1);
}