BetterFrame/nodered/src/bf-trigger-kiosk-changed.js
Mitchell R bd48c853e6 feat: restructure Node-RED nodes + server event emission
Renames:
- bf-config → bf-server-config (config node clarity)
- bf-event-in → bf-kiosk-camera-event (specific camera trigger)

New trigger nodes (input-only, under "BetterFrame Triggers"):
- bf-trigger-display-power, bf-trigger-layout-changed,
  bf-trigger-kiosk-changed, bf-trigger-camera-changed

New flow nodes:
- bf-config-get: query state by type (displays/kiosks/cameras/layouts/
  entities, or by-id)
- bf-config-set: mutate via typed setters (default-layout, enabled,
  priority, name)

Server-side event emission:
- shared/strip-secrets.ts: recursive password scrub
- New JSON admin endpoints: GET/POST /api/admin/{displays,kiosks,
  layouts,entities}[/:id]
- Coordinator-ws fires kiosk.changed on connect/disconnect/heartbeat
- Layout/power/camera routes call nodered.forward() on state change
2026-05-13 02:26:08 +02:00

45 lines
1.6 KiB
JavaScript

/**
* bf-trigger-kiosk-changed — fires on kiosk state changes (connect, disconnect,
* heartbeat with hardware telemetry).
*
* Topic filter: `kiosk.changed`. Server emits these from the coordinator-ws
* plugin on WS connect/disconnect and from heartbeat status messages.
*
* Output msg.payload:
* { kiosk_id, kiosk_name,
* event: "connected" | "disconnected" | "heartbeat",
* cpu_temp_c?: number, fan_rpm?: number, fan_pwm?: number }
*/
module.exports = function (RED) {
function BfTriggerKioskChangedNode(config) {
RED.nodes.createNode(this, config);
const node = this;
node.on("input", function (msg, send, done) {
const body = (msg && msg.payload && typeof msg.payload === "object") ? msg.payload : {};
const topic = msg.topic || body.topic || "kiosk.changed";
if (String(topic) !== "kiosk.changed") {
return done && done();
}
const out = {
topic: "kiosk.changed",
payload: {
kiosk_id: body.kiosk_id !== undefined ? body.kiosk_id : null,
kiosk_name: body.kiosk_name || null,
event: body.event || null,
cpu_temp_c: body.cpu_temp_c !== undefined ? body.cpu_temp_c : null,
fan_rpm: body.fan_rpm !== undefined ? body.fan_rpm : null,
fan_pwm: body.fan_pwm !== undefined ? body.fan_pwm : null,
},
};
node.status({
fill: "green",
shape: "dot",
text: (out.payload.kiosk_name || String(out.payload.kiosk_id || "")) + " " + (out.payload.event || ""),
});
send(out);
done && done();
});
}
RED.nodes.registerType("bf-trigger-kiosk-changed", BfTriggerKioskChangedNode);
};