pliceclogs-og/rfid-daemon/variants/log.js
type-two e5b8504bc6 Import pliceclogs as-is — the original Discogs seller extension
Snapshot of the working tree exactly as it stood, no edits. This is the predecessor
PRICEGOD was rewritten from ("kept intact, untouched" per pricegod/README.md), and it
is still the only place the DYMO scale is actually implemented —
rfid-daemon/index.js:1068-1265: HID discovery, parseScaleReport, one-shot read, and a
streaming /weight + /scale/start|stop session whose JSON shape PRICEGOD's daemon.js
already speaks.

Preserved verbatim on purpose (hence -og), including the known bug: DYMO_PIDS at
index.js:1082 is [0x8003, 0x8004], so it cannot see the bench M25 (0x8009). Fix that
in whatever daemon inherits the scale, not here.

node_modules stays ignored (22M of the 24M tree). No credentials in the import: the
two PEM markers in utils.js/sheets.js only strip headers off a key read from settings,
and mrpadmin / johnking are an SSH and a Postgres username, both key/trust auth.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 13:47:09 +10:00

76 lines
2.3 KiB
JavaScript

'use strict';
// Per-session JSON-lines logger shared across all variants. Writes to
// rfid-daemon/diagnostics/run-<variant>-<YYYYMMDD-HHMMSS>.log so we can
// compare variants apples-to-apples after a session.
const fs = require('fs');
const path = require('path');
const pad2 = n => n.toString().padStart(2, '0');
function tsForFilename(d = new Date()) {
return `${d.getFullYear()}${pad2(d.getMonth()+1)}${pad2(d.getDate())}-${pad2(d.getHours())}${pad2(d.getMinutes())}${pad2(d.getSeconds())}`;
}
function createLogger(variant, diagDir) {
fs.mkdirSync(diagDir, { recursive: true });
const logPath = path.join(diagDir, `run-${variant}-${tsForFilename()}.log`);
const stream = fs.createWriteStream(logPath, { flags: 'a' });
const counters = {
write_ok: 0, write_failed: 0,
read_ok: 0, read_failed: 0,
inventory_ok: 0, inventory_failed: 0,
timeout: 0,
keepalive_sent: 0, preflight_run: 0,
recover_attempted: 0,
lockups: 0,
};
let lastSuccessAt = null;
let inLockupSince = null;
const startedAt = Date.now();
function writeLine(obj) {
stream.write(JSON.stringify(obj) + '\n');
}
function event(name, data = {}) {
const obj = { ts: new Date().toISOString(), ev: name, ...data };
writeLine(obj);
if (name in counters) counters[name]++;
const isSuccess = (name === 'write_ok' || name === 'read_ok' || name === 'inventory_ok');
if (isSuccess) {
lastSuccessAt = Date.now();
if (inLockupSince) {
writeLine({ ts: obj.ts, ev: 'recovered', afterMs: Date.now() - inLockupSince });
inLockupSince = null;
}
}
if (name === 'timeout' && !inLockupSince) {
inLockupSince = Date.now();
counters.lockups++;
writeLine({ ts: obj.ts, ev: 'lockup_detected', sinceLastSuccessMs: lastSuccessAt ? Date.now() - lastSuccessAt : null });
}
}
function summary() {
return {
variant,
runtimeMs: Date.now() - startedAt,
counters: { ...counters },
lastSuccessAgoMs: lastSuccessAt ? Date.now() - lastSuccessAt : null,
currentlyLocked: !!inLockupSince,
};
}
function close() {
writeLine({ ts: new Date().toISOString(), ev: 'end', ...summary() });
stream.end();
}
return { event, summary, close, logPath };
}
module.exports = { createLogger };