mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 16:56:33 +00:00
fix: Node-RED event forwarding + parse ONVIF Key section (PlateNumber)
Server bridge was forwarding to raw topic paths that no Node-RED node listens on. Now forwards to fixed routes: camera.event, onvif.event, onvif.motion, onvif.anpr — matching what trigger nodes register. ONVIF XML parser now extracts Key section SimpleItems (PlateNumber, etc.) into the data map alongside Data section items. Previously only parsed Source and Data, missing Key-section fields like plate numbers. Node-RED trigger nodes: camera_id filter changed from Number() to String() comparison for UUIDv7 compatibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
eb8abbdff9
commit
55b11f2ffa
6 changed files with 16 additions and 12 deletions
|
|
@ -448,6 +448,11 @@ fn parse_notification_messages(xml: &str) -> Vec<OnvifEvent> {
|
|||
source.insert(name, value);
|
||||
}
|
||||
}
|
||||
if let Some(key_block) = extract_section(block, "Key") {
|
||||
for (name, value) in parse_simple_items(&key_block) {
|
||||
data.insert(name, value);
|
||||
}
|
||||
}
|
||||
if let Some(data_block) = extract_section(block, "Data") {
|
||||
for (name, value) in parse_simple_items(&data_block) {
|
||||
data.insert(name, value);
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ module.exports = function (RED) {
|
|||
function BfKioskCameraEventNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
const node = this;
|
||||
const filterIdRaw = (config.camera_id || "").toString().trim();
|
||||
const filterId = filterIdRaw && !isNaN(Number(filterIdRaw)) ? Number(filterIdRaw) : null;
|
||||
const filterId = (config.camera_id || "").toString().trim() || null;
|
||||
|
||||
async function handler(req, res) {
|
||||
const body = await readJsonBody(req);
|
||||
|
|
@ -37,7 +36,7 @@ module.exports = function (RED) {
|
|||
const cameraId = body.camera_id !== undefined ? body.camera_id
|
||||
: body.source_camera_id !== undefined ? body.source_camera_id
|
||||
: null;
|
||||
if (filterId !== null && Number(cameraId) !== filterId) {
|
||||
if (filterId !== null && String(cameraId) !== filterId) {
|
||||
return res.status(200).end();
|
||||
}
|
||||
const out = {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ module.exports = function (RED) {
|
|||
function BfTriggerAnprNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
const node = this;
|
||||
const filterCam = config.camera_id ? Number(config.camera_id) : null;
|
||||
const filterCam = config.camera_id ? String(config.camera_id).trim() : null;
|
||||
|
||||
async function handler(req, res) {
|
||||
const body = await readJsonBody(req);
|
||||
|
|
@ -33,7 +33,7 @@ module.exports = function (RED) {
|
|||
}
|
||||
|
||||
const cameraId = body.camera_id ?? body.source_camera_id ?? null;
|
||||
if (filterCam !== null && Number(cameraId) !== filterCam) {
|
||||
if (filterCam !== null && String(cameraId) !== filterCam) {
|
||||
return res.status(200).end();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ module.exports = function (RED) {
|
|||
function BfTriggerEventNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
const node = this;
|
||||
const filterCam = config.camera_id ? Number(config.camera_id) : null;
|
||||
const filterCam = config.camera_id ? String(config.camera_id).trim() : null;
|
||||
const filterTopic = (config.topic_filter || "").trim();
|
||||
|
||||
async function handler(req, res) {
|
||||
|
|
@ -27,7 +27,7 @@ module.exports = function (RED) {
|
|||
}
|
||||
|
||||
const cameraId = body.camera_id ?? body.source_camera_id ?? null;
|
||||
if (filterCam !== null && Number(cameraId) !== filterCam) {
|
||||
if (filterCam !== null && String(cameraId) !== filterCam) {
|
||||
return res.status(200).end();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ module.exports = function (RED) {
|
|||
function BfTriggerMotionNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
const node = this;
|
||||
const filterCam = config.camera_id ? Number(config.camera_id) : null;
|
||||
const filterCam = config.camera_id ? String(config.camera_id).trim() : null;
|
||||
|
||||
async function handler(req, res) {
|
||||
const body = await readJsonBody(req);
|
||||
|
|
@ -34,7 +34,7 @@ module.exports = function (RED) {
|
|||
}
|
||||
|
||||
const cameraId = body.camera_id ?? body.source_camera_id ?? null;
|
||||
if (filterCam !== null && Number(cameraId) !== filterCam) {
|
||||
if (filterCam !== null && String(cameraId) !== filterCam) {
|
||||
return res.status(200).end();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -735,11 +735,11 @@ function registerKioskRoutes(
|
|||
nodered.forward(body.topic, out, markForwarded);
|
||||
mqtt.publishEvent(kiosk.id, body.topic, out);
|
||||
|
||||
// ONVIF events: also forward to the fixed onvif.event route so the
|
||||
// bf-trigger-motion / bf-trigger-anpr / bf-trigger-event nodes
|
||||
// receive them without needing per-topic route registration.
|
||||
nodered.forward("camera.event", out);
|
||||
if (body.source_type === "onvif") {
|
||||
nodered.forward("onvif.event", out);
|
||||
nodered.forward("onvif.motion", out);
|
||||
nodered.forward("onvif.anpr", out);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue