Raise alerts: failed or paused prints, and AI detections
Nothing subscribed to channel:print_alerts and nothing watched a printer fail, so an operator away from the screen found out when they came back to a ruined plate. Alerts are now rows in printer_alerts, listed at GET /alerts (open=true for what still needs a person) and cleared with POST /alerts/:id/acknowledge, which is operator-only and keeps the first acknowledger on the record. Two sources. Telemetry: a change into error is a failed print if the printer was printing or paused, otherwise a printer error; a print the printer paused itself (how an AMS fault looks) is announced too. Transitions, not levels - a printer sitting in error is one alert, not one per frame - and a connection's first sight of a printer raises nothing, so a gateway that reconnects does not re-announce known faults. AI: the worker's Valkey publications are stored when confidence is at least ALERT_MIN_CONFIDENCE (default 0.6); the worker deliberately does not threshold, so the policy lives here. A bad message costs one message, not the listener. e2e-authz.sh gains the scoping/ack cases; new e2e-alerts.sh drives a stand-in gateway over the real /ws/edge/v1 and the real Valkey channel (checked to fail when the derivation is broken).
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* A stand-in gateway for scripts/e2e-alerts.sh: connects to /ws/edge/v1 with
|
||||
* an edge JWT, says hello, then reports one printer through a sequence of
|
||||
* states, one telemetry frame each, and waits for the backend to take them.
|
||||
*
|
||||
* Usage: bun scripts/fake-gateway.ts <ws-url> <edge-jwt> <printer-id> STATE[,STATE...]
|
||||
* A state is a Bambu gcode_state word (IDLE, RUNNING, PAUSE, FAILED).
|
||||
*/
|
||||
const [url, jwt, printerId, states] = process.argv.slice(2);
|
||||
if (!url || !jwt || !printerId || !states) {
|
||||
console.error("usage: fake-gateway.ts <ws-url> <edge-jwt> <printer-id> STATE[,STATE...]");
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const ws = new WebSocket(url, { headers: { authorization: `Bearer ${jwt}` } } as never);
|
||||
ws.onerror = () => {
|
||||
console.error("socket error");
|
||||
process.exit(1);
|
||||
};
|
||||
ws.onopen = async () => {
|
||||
ws.send(JSON.stringify({ type: "hello", gateway_id: "fake-gw" }));
|
||||
for (const state of states.split(",")) {
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: "telemetry",
|
||||
printers: [{ printer_id: printerId, name: "Fake", state, percent: 10, print_error: 0 }],
|
||||
}),
|
||||
);
|
||||
// Telemetry is persisted in order per socket; a pause keeps the frames
|
||||
// from being coalesced into one observation.
|
||||
await Bun.sleep(400);
|
||||
}
|
||||
await Bun.sleep(500);
|
||||
ws.close();
|
||||
process.exit(0);
|
||||
};
|
||||
Reference in New Issue
Block a user