PrintFxv2

This commit is contained in:
2026-09-16 11:29:52 +10:00
parent 922ce99d25
commit 3b2a399769
7 changed files with 57 additions and 11 deletions
+13 -2
View File
@@ -179,6 +179,11 @@ the widest roll it will accept — the console warns you if you enter anything w
| DK-11208 | 38 × 90 mm die-cut | Narrower; turn the photo off | | DK-11208 | 38 × 90 mm die-cut | Narrower; turn the photo off |
| DK-11209 | 29 × 62 mm die-cut | Name and host only | | DK-11209 | 29 × 62 mm die-cut | Name and host only |
**A DK-22251 must be set as the black/red roll even if nothing on the badge is red.** The printer
refuses a monochrome job on two-colour tape, saying *Black/Red on White paper is installed now.
Change it to Monochrome media.* The roll setting controls how the job is built, not just its
colour.
**Tell it which roll is loaded.** *Roll loaded in the printer* under **Sites → Edit → Printer** **Tell it which roll is loaded.** *Roll loaded in the printer* under **Sites → Edit → Printer**
must match what is physically in the machine. A two-colour job sent to a plain roll is refused must match what is physically in the machine. A two-colour job sent to a plain roll is refused
outright: the printer shows **Wrong Roll Type** and nothing comes out. The setting is separate outright: the printer shows **Wrong Roll Type** and nothing comes out. The setting is separate
@@ -223,8 +228,14 @@ docker compose exec visitor-signin node scripts/printer-status.mjs
``` ```
It reports the media width, whether the roll is continuous or die-cut, any error the printer is It reports the media width, whether the roll is continuous or die-cut, any error the printer is
holding, and the roll id that matches. `brother_ql`'s network backend only writes to the socket holding, and the roll id that matches.
and never reads, which is why a refused job still looks like a success — this asks directly.
**It does not work on every printer.** Many Brother network print servers are write-only on port
9100: they accept jobs but never answer a status request, even though the same printer reports
happily over USB. The QL-820NWB is one of them. When that happens, **Brother Status Monitor on a
PC with the printer installed is the thing to use** — it gives the exact reason a job was refused,
in plain words, which is more than anything on the server can tell you. `brother_ql`'s network
backend never reads the socket at all, so it reports success no matter what the printer does.
If the printer will not answer, work through the possibilities one at a time: If the printer will not answer, work through the possibilities one at a time:
+4 -2
View File
@@ -847,8 +847,10 @@ function openSiteModal(site) {
<option value="62" ${site.printer.label !== '62red' ? 'selected' : ''}>62 mm continuous, black only</option> <option value="62" ${site.printer.label !== '62red' ? 'selected' : ''}>62 mm continuous, black only</option>
<option value="62red" ${site.printer.label === '62red' ? 'selected' : ''}>62 mm continuous, black and red (DK-22251)</option> <option value="62red" ${site.printer.label === '62red' ? 'selected' : ''}>62 mm continuous, black and red (DK-22251)</option>
</select></label> </select></label>
<p class="hint">This must match the roll actually in the machine. Send a two-colour job to a <p class="hint">This must match the roll actually in the machine, and it matters in both
plain roll and the printer answers <em>Wrong Roll Type</em> and prints nothing.</p> directions. A two-colour job on a plain roll is refused as <em>Wrong Roll Type</em>; a
monochrome job on a DK-22251 is refused with <em>Black/Red on White paper is installed
now</em>. The DK-22251 needs the two-colour option even when the badge is entirely black.</p>
<div class="modal-row"> <div class="modal-row">
${field('Model', 'printerModel', site.printer.model)} ${field('Model', 'printerModel', site.printer.model)}
<label class="modal-field"><span>Rotation</span> <label class="modal-field"><span>Rotation</span>
+1 -1
View File
@@ -68,7 +68,7 @@ for (const [label, description] of CANDIDATES) {
'--backend', 'network', '--backend', 'network',
'--model', site.printer_model || 'QL-820NWB', '--model', site.printer_model || 'QL-820NWB',
'--printer', target, '--printer', target,
'print', '--label', label, file, 'print', '--label', label, ...(label === '62red' ? ['--red'] : []), file,
], ],
{ stdio: ['ignore', 'pipe', 'pipe'], timeout: config.printing.timeoutMs } { stdio: ['ignore', 'pipe', 'pipe'], timeout: config.printing.timeoutMs }
); );
+3 -1
View File
@@ -73,8 +73,10 @@ const args = [
'--printer', target, '--printer', target,
'print', 'print',
'--label', label, '--label', label,
file,
]; ];
// Required on black/red tape even when the badge is entirely black.
if (label === '62red') args.push('--red');
args.push(file);
console.log(''); console.log('');
console.log(` running: ${config.printing.command} ${args.join(' ')}`); console.log(` running: ${config.printing.command} ${args.join(' ')}`);
+23 -2
View File
@@ -102,6 +102,15 @@ socket.on('connect', () => {
socket.write(Buffer.alloc(200, 0x00)); socket.write(Buffer.alloc(200, 0x00));
socket.write(Buffer.from([0x1b, 0x40])); socket.write(Buffer.from([0x1b, 0x40]));
socket.write(Buffer.from([0x1b, 0x69, 0x53])); socket.write(Buffer.from([0x1b, 0x69, 0x53]));
// Some firmware only answers once it is in raster mode, so ask again that way
// before giving up.
setTimeout(() => {
if (!chunks.length && !socket.destroyed) {
socket.write(Buffer.from([0x1b, 0x69, 0x61, 0x01]));
socket.write(Buffer.from([0x1b, 0x69, 0x53]));
}
}, 1500);
}); });
socket.on('data', (d) => { socket.on('data', (d) => {
@@ -113,8 +122,20 @@ socket.on('timeout', () => {
socket.destroy(); socket.destroy();
if (!chunks.length) { if (!chunks.length) {
console.error(' The printer accepted the connection but sent nothing back.'); console.error(' The printer accepted the connection but sent nothing back.');
console.error(' Some firmware only answers when idle — make sure it is not mid-job,'); console.error('');
console.error(' and that nothing else is holding port 9100 open.\n'); console.error(' Many Brother network print servers are write-only on port 9100: they accept');
console.error(' jobs but never report status, even though the same printer answers happily');
console.error(' over USB. If this is one of them, no amount of asking will help.');
console.error('');
console.error(' Read the printer instead from:');
console.error(' - the display on the machine itself');
console.error(' - Brother Status Monitor, on a PC with the printer installed');
console.error(' - the printer\'s own web page, at http://' + host + '/');
console.error('');
console.error(' Status Monitor in particular gives the exact reason a job was refused,');
console.error(' which is more than brother_ql can tell you — its network backend never');
console.error(' reads the socket, so it reports success whatever the printer does.');
console.error('');
process.exit(1); process.exit(1);
} }
}); });
+12 -2
View File
@@ -291,6 +291,9 @@ function explainPrintError(output, host) {
if (/Unknown label|label/i.test(last) && /identifier/i.test(last)) { if (/Unknown label|label/i.test(last) && /identifier/i.test(last)) {
return 'The printer rejected the label size. Check the roll loaded matches the badge settings.'; return 'The printer rejected the label size. Check the roll loaded matches the badge settings.';
} }
if (/Black\/Red|Monochrome media/i.test(output)) {
return 'The printer has a black/red roll loaded but received a monochrome job. Set "Roll loaded in the printer" to the DK-22251 option so the job is built for two-colour tape.';
}
if (/wrong roll|WrongMedia|media/i.test(last)) { if (/wrong roll|WrongMedia|media/i.test(last)) {
return 'The printer says the roll is wrong. Check "Roll loaded in the printer" matches what is actually in the machine — a black and red job is refused on a plain roll.'; return 'The printer says the roll is wrong. Check "Roll loaded in the printer" matches what is actually in the machine — a black and red job is refused on a plain roll.';
} }
@@ -336,15 +339,22 @@ export async function printBadge(visit, site) {
const port = Number(site.printer_port) || 9100; const port = Number(site.printer_port) || 9100;
const target = `tcp://${site.printer_host}:${port}`; const target = `tcp://${site.printer_host}:${port}`;
const label = labelFor(site);
const args = [ const args = [
'--backend', 'network', '--backend', 'network',
'--model', site.printer_model || 'QL-820NWB', '--model', site.printer_model || 'QL-820NWB',
'--printer', target, '--printer', target,
'print', 'print',
'--label', labelFor(site), '--label', label,
file,
]; ];
// brother_ql: "You must use this option when printing on black/red tape, even
// when not printing red." Without it the job is built as monochrome, the
// printer sees two-colour media, and refuses the whole thing.
if (label === '62red') args.push('--red');
args.push(file);
try { try {
await runBrotherQl(args, config.printing.timeoutMs); await runBrotherQl(args, config.printing.timeoutMs);
note(site.id, true, `Printed to ${site.printer_host}`); note(site.id, true, `Printed to ${site.printer_host}`);
+1 -1
View File
@@ -539,7 +539,7 @@ router.get('/sites/:id/printer-diagnostics', (req, res) => {
'brother_ql --backend network', 'brother_ql --backend network',
`--model ${site.printer_model || 'QL-820NWB'}`, `--model ${site.printer_model || 'QL-820NWB'}`,
`--printer tcp://${site.printer_host}:${site.printer_port || 9100}`, `--printer tcp://${site.printer_host}:${site.printer_port || 9100}`,
`print --label ${printer.labelFor(site)} badge.png`, `print --label ${printer.labelFor(site)}${printer.labelFor(site) === '62red' ? ' --red' : ''} badge.png`,
].join(' '), ].join(' '),
}); });
}); });